Iptables: как перенаправить TCP-/UDP- подключений от внешних клиентов на другой внешний IP?
Для моего проекта мне необходимо настроить хост, выполняющий функцию прозрачного прокси, не только для веб-сервера, но и для других TCP/UDP-соединений (SIP, RDP, и т.д.), чтобы эти серверы были скрыты непосредственно от пользователей для повышения уровеня безопасности.
Конфигурация должна быть такой, чтобы со стороны клиента не требовались дополнительные настройки. Учитывая специфику моей инфраструктуры, стандартные решения (Squid, VPN, NAT (External to Internal)) мне не подходят.
Специфика моей сети:
1. Все хосты распределены териториально (VPS, Дедики) и связаны между собой через внешние интерфейсы. При этом использовать частные сети, предлагаемые провайдерами, я не могу, т.к. провайдеры отличаются.
2. Поднять VPN-сервер и подключить все хосты к VPN. Этот вариант не подходит ввиду существенного увеличечения задержек, а также проблем с поддержкой VPN частью оборудования.
3. Reverse Proxy - как я понимаю, это решение подразумевает использование только портов HTTP, HTTPS
Думаю, возможно ли реализивать "прозрачный прокси" для TCP/UDP соединений между удаленными клиентом и сервером без VPN для различных сервисов, используя iptables для вот такой схемы: |удаленный клиент|public ip|> <-SIP, RDP, HTTPS-> <|внешний IP|Прокси-сервер|внешний IP|> <-SIP, RDP, HTTPS-> <|внешний IP|хосты с сервисами (RDP, SIP, VPN.)|
Как я понимаю, для этого мне понадобятся следующие таблицы и цепочки:
PREROUTING:
1)Connection Tracking
2)DNAT
POSTROUTING:
SNAT
Бьюсь третий день, ничего не работает. Буду признателен за любые советы и ваше мнение - можно ли реализовать такое для UDP-соединений?
iptables -t nat -A PREROUTING -p udp --dst ретранслятор --dport порт -j DNAT --to-destination сервер:порт
iptables -t nat -A POSTROUTING -p udp --dst сервер --dport порт -j SNAT --to-source ретранслятор
По сути банальный проброс портов.
Все что пришло по нужному протоколу, на указанный порт - тупо пересылается на другой белый айпишник на указанный порт. Ответ точно также идет обратно по цепочке.
Или по портам вы делить трафик не можете?
Спасибо, как раз о подобной схеме думаю.
По портам разбросать - вообще отлично.
Но тут возникает один момент:
Пробовал подобную конфигурацию iptables для порта порта HTTP - вечное ожидание загрузки страницы, хотя ретранслятор пингуется на этом порту.
Есть подозрение, что происходит следующее:
Запрос от клиента успешно уходит на сервер через ретранслятор, но когда пакеты идут назад от сервера клиенту, то на ретрансляторы разворачиваются назад в сторону сервера, т.к. в iptables ретранслятора прописана переадресация всех входящих пакетов на порту 80 на сервер.
Возникает вопрос: если исключить серверы из Routing схемы по их айпишнику, будут ли доходить от сервера клиенту пакеты, которые являются "ответами" на ранее переадресованные запросы клиента. Ведь установлен SNAT, сервер думает, что нужно доставить пакеты только ретранслятору.
Или ретранслятор успешно разберется в обратной доставке пакетов при работе DNAT/SNAT?
Второй вариант, как я думал решить эту проблему - это сделать на ретрансляторе два внешних сетевых интерфейса. На один принимать и с с него переадресовывать подключения со стороны клиента, а на другой - со стороны сервера. Но тут все сильно усложняется для меня в плане понимания конфигурации.
В сторону целевогл сервера натятся, а вот к клиенту с ретранслятора не возвращаются, а снова натятся на целевой сервер, тк в правилах же прописано натить указанные порты, приходящие на публичный Ip рестраслятора. Получаетсч, под это правило попадают и ответы сервера клиенту
cyberhaze, ответ не может попасть под это правило, порт другой.
Вы прислали пакет на 80 порт ретранслятора - он его переслал на нужный сервер и ждет ответа на указанном порту например на 58420, когда на этот порт придет ответ, он разумеется никоим образом не сможет попасть под правило для 80порта, и пойдет в цепочку POSTROUTING
Пробовал подобную конфигурацию iptables для порта порта HTTP - вечное ожидание загрузки страницы, хотя ретранслятор пингуется на этом порту.
А напрямую без ретранслятора у вас HTTP отдается нормально? Может там HTTPS а вы пробросили только 80порт?
И еще - ретранслятор не может пинговаться на "этом порту"
Пинг это протокол ICMP, там нет такого понятия как порт.
если есть правило с рандомным источником перенаправлять какой-то порт на сервер Х, то почему-бы не сделать выше правило не перенаправлять пакет с этого порта пришедший с сервера Х?
Отправить соединение на другой удаленный хост не выйдет. Единственный вариант натить на адрес, скажем, в впн: например поднять IP поверх и слать там. Если вы не хотите использовать никакие впн, то проблема неразрешима.
cyberhaze, других вариантов у вас нет, ни в рамках TCP/IP, ни в рамках udp не подразумевается создание новых пакетов (а именно этого хотите вы). Postrouting/prerouting может только изменить пакет: ни создать новый пакет, ни создать, тем более, новое соединение, невозможно. Читаем матчасть.
Dmitry Tallmange, на самом деле, нет разницы, натить в VPN, или натить в белый IP "ретранслятора". Другой вопрос, что SIP могуть быть проблемы -- не очень-то он приспособлен для обхода NAT-ов, тем более нескольких. С остальным -- вполне реализуемо.
Dmitry Tallmange, да, уже чувствую, что вы правы. Провозился целую ноч, так и не удалось мне сделать external to external NAT штатными средствами iptables. Пакеты в сторону целевого сервера переадресуются, но вот назад до клиента не долетают. Похоже на фидбэк луп, тк получается, что ответы от целевого сервера также попадают под правила Forward и уходят назад на него. Возможно, бубен может решить эту проблему через создание более детальных правил или подключение еще одного нет-интерфейча к ретранлятору для маршрутизации ответных пакетов. Но вот на реддите тоже уверены, что это очень кривое решение будет и что проще все же запилить VPN
athacker, с моей колокольни (могу ошибаться) разница в тои, что если натить не в VPN, то работать это будет быстрее за счёт экономти ресурсов на инкапсуляцию пакетов. Очень бы хотелось так и сделать, но похоже все же придется юзать VPN
Итак, друзья, давайте развенчаем все мифы окончательно.
Клиент - 1.1.1.1 - запрашивающий ресурс удаленный клиент.
СерверА - 2.2.2.2 - сервер, который планируется как "прокси".
СерверБ - 3.3.3.3 - сервер, на который мы хотим переадресовать клиента.
Клиент 1.1.1.1 отправлят запрос на 2.2.2.2. Последний делает DST-NAT на адрес 3.3.3.3. Таким образом СерверБ получает входящий запрос с адреса 1.1.1.1. Он честно начинает отвечать адресу 1.1.1.1 согласно своей текущей таблице маршрутизации. Таким образом соединение потеряно.
Что делать? Назначить сервер 2.2.2.2 в качестве шлюза по умолчанию для сервера 3.3.3.3. Блестяще! Но есть одно но: шлюзом может быть только интерфейс, либо адрес, являющийся next-hop. В рассматриваемом случае интерфейса у нас нет, а есть адрес 2.2.2.2, который не является next-hop, потому что он находится в интернетах. Таким образом, единственный вариант, благодаря которому мы можем направить весь трафик с сервера 3.3.3.3 через сервер 2.2.2.2 - тоннель. Любой IP over IP.
Dmitry Tallmange Ну технически там нужно делать не только DST, но и SRC NAT. Т. е. клиент 1.1.1.1 отправляет пакет на "прокси" 2.2.2.2, на определённый порт. "Прокси" делает SRC NAT от своего имени и отправляет пакет дальше, на сервер 3.3.3.3, на необходимый порт сервиса.
Другой вопрос, что это геморрой, который не стоит свеч. И больше принесёт проблем, нежели усилит защиту. Например, сервер 3.3.3.3 не сможет видеть реальных IP-адресов клиентов, что усложнит отладку и расследование инцидентов. Нужно будет костылить на ретрансляторе запись netflow, например, чтобы была информация, откуда и на какие сервисы ходили, и потом сопоставлять две базы -- логов сервиса и netflow.
В общем, гораздо правильнее обеспечить защиту сервисов на местах (т. е. на тех серверах, где они работают). Либо собрать всё на одной площадке, на серых адресах, и действительно поставить некий шлюз с белым IP между ними.
athacker, В общем, гораздо правильнее обеспечить защиту сервисов на местах (т. е. на тех серверах, где они работают). Либо собрать всё на одной площадке, на серых адресах, и действительно поставить некий шлюз с белым IP между ними.
Спасибо, теперь ситуация для меня прояснилась окончательно.