LINUX.ORG.RU
решено ФорумAdmin

iptables проброс порта с внутреней сети на внешний интерфейс

 , ,


0

1

Здравствуй ЛОР.

Помоги разобратся с непонятнятками в iptables. Вот схемка сети. Все просто!: сервер, с двумя внутренними сетями(«VM network product» = DMZ), одна сеть для WEB приложений, другая для сервисов в часности Nginx Proxy. Проброс портов с внешки на Nginx, далее Nginx проксирует в DMZ на приложение (192.168.1.2:80). Firewall настроен только на самом физическом сервере(на виртуальных машинах все ACCEPT). Все вроде просто и работает(в данном виде).

Задача: Чтобы приложение с хоста 192.168.1.2 имело доступ по своему DNS имени на внешнем интерфейсе к самому себе. Т.е. приложение на хосте 192.168.1.2 делает http(/s) запрос по своему DNS имени app.example.com и получало доступ к самому себе через Nginx Proxy.

Непонятно следующее: как _правильно_ решить данную задачу. в данный момент имеются следующие правила:

#$IPT -t nat -A PREROUTING -p tcp -i $PRODUCT_LAN_IF -m multiport --dports '80,443' -j DNAT --to-destination $NGINX_PROXY_IP
#$IPT -t nat -I POSTROUTING -p tcp -d $NGINX_PROXY_IP --dport 80 -j SNAT --to-source $SERVICE_LAN_IP
но я не понимаю правильно ли они работают(запрос приложения сначала DNAT-ится потом SNAT-ится, и получается что приложение от IP сервера обращается к Nginx. Мега костыль же, поизящнее никак?). И я не совсем понимаю как пакеты проходят через цепочки iptables. Про -j LOG в курсе, только не знаю где его ставить.

Ответ на: комментарий от outsider

Проблема в том что иногда приложению требуется обращатся по https, по валидному сертификату. Не, ставить на каждую виртуалку Nginx c валидным сертификатом конечно можно, но много их, как то бы без этого обойтись.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

тогда вытащи nginx_proxy на внешний сервер и рули уже им

Задача: Чтобы приложение с хоста 192.168.1.2 имело доступ по своему DNS имени на внешнем интерфейсе к самому себе. Т.е. приложение на хосте 192.168.1.2 делает http(/s) запрос по своему DNS имени app.example.com и получало доступ к самому себе через Nginx Proxy.

А нафига вообще такое надо?

outsider ★★
()
Ответ на: комментарий от outsider

тогда вытащи nginx_proxy на внешний сервер и рули уже им

Тоже вариант. Я понимаю что так можно. Но хотелось бы не разворачивать ничего на виртуальном сервере. И на Nginx потом планируется вход по сертификатам и доп.костыли. Негоже это на vm-host ставить.

А нафига вообще такое надо?

В данный момент на 1й vm несколько приложений, и они обращаются к друг другу по внешнему имени app.example.com. Потом програмисты может быть и перепишут(а может и нет).

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

они обращаются к друг другу по внешнему имени app.example.com

так тогда пропиши локальные адреса в hosts, типа

app.example.com 192.168.2.2 1.2.3.4

outsider ★★
()
Ответ на: комментарий от outsider

так тогда пропиши локальные адреса в hosts, типа

Да я прописывал. по http все прекрасно работает. Проблема в https. Вкраце, суть в том что в приложении адреса выдаваемые клиентам и адреса для связи между приложениями это одно и то же. Поэтому либо ставить Nginx с валидным сертификатом (моё второе сообщение), либо использовать только http (так работает да, проверял). Почему нехочу ставить Nginx на каждую виртуалку, потому что планирую автоматизировать разворачивание новых приложений/стендов с помощю ansimble. И поэтому хотелось бы минимизировать количество настроек отдельно взятой vm.

«Обходные» пути вроде все рассмотрены. И я думаю что оптимальный путь это корректная настройка iptables на vm-host.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

Поциент, если я правильно вас понял, то вы путаетесь в показаниях. С одной стороны вы хотите что бы запросы https летали через nginx который где-то там в инете. С другой стороны просите что бы они через него не летали. Вы уж или «крестик снимите или трусы наденьте»

anc ★★★★★
()
Ответ на: комментарий от anc

если я правильно вас понял

Не правильно понял.

С одной стороны вы хотите что бы запросы https летали через nginx который где-то там в инете

Не в инете а в подсети, сервера виртуальных машин. Схема в первом посте прикреплена.

что бы они через него не летали

Чтобы Nginx не было на каждой vm с приложением, а чтобы Nginx был один единственный на всем сервере.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

Вкраце, суть в том что в приложении адреса выдаваемые клиентам и адреса для связи между приложениями это одно и то же. Поэтому либо ставить Nginx с валидным сертификатом (моё второе сообщение), либо использовать только http (так работает да, проверял).

Может у меня конечно с глазами плохо, но: Ваша схема никак это не поясняет, что такое «адреса выдаваемые клиентам» что такое «адреса для связи между приложениями» почему не спасает запись в hosts? Зачем нужен nat, который непонятно где работает и непонятно что у него в параметрах, только догадаться можно сравнивая с вашей схемой, что не правильно... больше вопросов чем ответов. Возможно кто-то еще расшифрует ваш запрос, но у меня не получается.

anc ★★★★★
()
Ответ на: комментарий от anc

что такое «адреса выдаваемые клиентам» что такое «адреса для связи между приложениями»

Ох зря я это написал. Это была попытка объяснить зачем приложение из за NAT должно «видеть» само себя по внешнему адресу. В общем не важно. Ограничимся только первым постом.

почему не спасает запись в hosts

Потому что нужен httpS. Впринципе вообще то да, я могу прописать в hosts виртуалок

 app.example.com 192.168.2.2
т.е. адрес Nginx из внутреней сети для httpS. И это будет работать (возможно именно это хотел сказать outsider но я его не совсем понял). Но всетаки я хотел бы решить проблему описаную в первом посте.

Зачем нужен nat, который непонятно где работает и непонятно что у него в параметрах, только догадаться можноо сравнивая с вашей схемой, что не правильно...

Суть в задаче описаной в первом посте. Костыль который я нагуглил для её решения (NAT) приведен там же. Я прошу подсказать как решить эту задачу средствами iptables, наиболее «правильно» если можно обойтись без NAT то будет вообще замечательно.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

Впринципе вообще то да, я могу прописать в hosts виртуалок
app.example.com 192.168.2.2
т.е. адрес Nginx из внутреней сети для httpS. И это будет работать (возможно именно это хотел сказать outsider но я его не совсем понял).
Но всетаки я хотел бы решить проблему описаную в первом посте.

Вы окончательно запутали. Если решение в виде hosts у вас работает. То что именно не работает? Можно подробнее кто->куда должен обращаться и кто->кому должен отвечать.

anc ★★★★★
()
Ответ на: комментарий от anc

Если решение в виде hosts у вас работает

Впринципе если прописать адрес Nginx из внутреней сети 192.168.2.2 то при обращении с хоста 192.168.1.2 будет работать да. Сегодня проверю это.

То что именно не работает?

Хотелось бы сделать решение через iptables на сервере виртуальных машин. Те правила DNAT,SNAT которые я написал в первом посте работают, но я не совсем понимаю как пакет проходит при этих правилах по цепочкам iptables. Мне нужно понять это для корректного написания правил разрешения фильтрации траффика.

Можно подробнее кто->куда должен обращаться и кто->кому должен отвечать.

Описание сети: есть сервер виртуальных машин, у которого 1 внешний интерфейс с IP адресом 1.2.3.4, и есть две внутренние подсети созданые с помощю brctl(br_product_lan и br_service_lan с IP адресами 192.168.1.1 и 192.168.2.1) виртуальные машины KVM подключаются к виртуальным сетям сервера. Фильтрация траффика _только_ на сервере виртуальных машин.

Правила iptables на сервере виртуальных машин: для простоты можно представить что все политики установленны в ACCEPT, и в iptables всего два правила:

iptables -t nat -A POSTROUTING -o $EXTERNAL_IF -j SNAT --to-source 1.2.3.4
iptables -t nat -A PREROUTING -p tcp -i $EXTERNAL_IF -m multiport --dports '80,443' -j DNAT --to-destination 192.168.2.2

Задача: Имеется DNS запись типа A:

app.example.com -> 1.2.3.4
на хосте 192.168.1.2 во внутренней сети сервера работает приложение которое должно принимать http/https запросы по данному DNS имени. Для этого сделана еще одна виртуалка с Nginx настроенным в качестве простого прокси, с адресом 192.168.2.2, на данный адрес сделан DNAT с внешнего интерфейса по портам 80 и 443. Нужно чтобы приложение с хоста 192.168.1.2 делало http/https запрос по DNS имени app.example.com(1.2.3.4), попадало через Nginx proxy (192.168.2.2) к самому себе(192.168.1.2).

Требуется решить данную задачу именно средствами iptables на хосте виртуальных машин. Прочитав RTFM я написал следующие правила:

iptables -t nat -A PREROUTING -p tcp -i br_product_lan -m multiport --dports '80,443' -j DNAT --to-destination 192.168.2.2
iptables -t nat -I POSTROUTING -p tcp -d 192.168.2.2 --dport 80 -j SNAT --to-source 192.168.2.1
Т.е. данные правила делают следующее(по RTFM) пакет от хоста 192.168.1.2 с адресом назначения 1.2.3.4 отправляется серверу виртуальных машин на интерфейс 192.168.1.1. Затем на сервере делается сначала DNAT на адрес 192.168.2.2 (Nginx), а потом SNAT на интерфейс 192.168.2.1(интерфейс сервера виртуалок в котором находится Nginx). И это работает.

Но моя проблема в том что: я не могу понять как мне написать разрешающие правила -t filter FORWARD, при политике iptables DROP. Т.к. я не понимаю как проходит пакет по цепочкам iptables. И -j LOG я не знаю куда точно ставить, т.к. правил в iptables много, и -j LOG весьма затруднителен.

PS: про другие решения (не средствами iptables), я понял, но хочу всетаки разобратся с iptables.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

У тебя явно проблемы с архитектурой или сам себе проблемы решил добавить? Зачем тут лишняя машина nginx_proxy 192.168.2.2?

outsider ★★
()
Ответ на: комментарий от outsider

Вся суть моего вопроса состоит в следующем: «какие разрешающие правила добавить в „iptables -t filter FORWARD“, для проброшенного в ту же внутренюю сеть через DNAT со шлюза(для этой же сети) порта.»

Про архитектуру понимаю что это весьма не «изящно», но это в моём случае наименьшее из зол(я так думаю).

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

вся проблема в этом

для проброшенного в ту же внутренюю сеть через DNAT со шлюза(для этой же сети)

ты либо натишь с внешки во внутрь (по портам), либо общаешься по внутренним адресам

outsider ★★
()
Ответ на: комментарий от Miss_Burpl

1. Если у вас виртуалок вида 192.168.1.2 не много, то достаточно прописать в host и никакие правила iptables не нужны. Если много можно на dns создать view что бы для запроса от них отдавал 192.168.2.2
2. При вашей схеме вот это правило «iptables -t nat -I POSTROUTING -p tcp -d 192.168.2.2 --dport 80 -j SNAT --to-source 192.168.2.1» вообще не уперлось все же роутится через один сервер.
3.

Но моя проблема в том что: я не могу понять как мне написать разрешающие правила -t filter FORWARD, при политике iptables DROP. Т.к. я не понимаю как проходит пакет по цепочкам iptables.

Есть iptables tutorial (в том числе и на русском) там хорошая картинка с описанием прохождения правил

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 2)

Блин, переоткрыл для себя -j TRACE. Причем раньше пользовался им сам, даже записи куда пнуть в sysctl для того чтобы заработал -j TRACE, свои же нашел(раньше им пользовался но забыл про него)! А сейчас пытался пихать зачем то везде -j LOG...

С TRACE все прекрасно видно где и что надо сделать. Добавил несколько правил для iptables все прекрасно заработало, и теперь мне все ясно(что, как и куда идет). В отличие от костылей в hosts на всяких виртуалках и прочих dns серверах, проблема решается добавлением нескольких правил в iptables на одном хосте.

Всем спасибо за внимание, прошу прощения если отвлек на свою дребедень.

Miss_Burpl
() автор топика
Ответ на: комментарий от Miss_Burpl

И все-таки вы норкоман :) Использовать нат где все решается роутингом, в вашем случае костыль это именно нат, а не то что вам предлагали.

anc ★★★★★
()
Ответ на: комментарий от anc

Использовать нат где все решается роутингом

Я много раз здесь говорил о том что у меня будет много виртуалок, и мне гораздо удобнее сделать этот костыль один раз и в одном месте. Чем потом следить за записями DNS будь то файл hosts или запись на внутренем DNS... Тем более как я уже писал выше планирую автоматизировать разворачивание виртуалок с помощю ansimble, и лишние записи где либо мне совсем не к чему.

Miss_Burpl
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.