Iptables redirect на другой ip

Iptables redirect на другой ip

Рассмотрим перенаправление (forward) на двух примерах:

1. с внешнего IP на внутренний сервер (без masquerade, IP-адрес источника сохраняется);

2. forward с использованием masquerade, с подменой IP-адреса источника (в локалку, и просто с сервера на сервер).

Пример 1: FORWARD (снаружи в локальную сеть, DNAT, меняется только адрес назначения)

Предположим, у вас есть веб-сервер в локальной сети, который должен быть доступным из дикого интернета только по https (443/tcp). Причин не использовать VPN или отдельный IP для отдельного сервера может быть много. Например, архитектура сети, отсутствие свободных IP, веб-сервер — гостевая виртуальная машина, а наш шлюз — хост )) Ну, не знаю, сами придумайте ситуацию.

Причем мы хитрые и хотим, чтобы наш веб сервер из интернета не был виден на 443 порту, а был доступен, скажем, на 1293 порту (примерно вот так: https://1.2.3.4:1293).

Итак, мы хотим перенаправить входящие из интернет на порт 1293 на порт 443 сервера в локальной сети.

IF_EXT="eth0" # Внешний сетевой адаптер
IF_INT="eth1" # Внутренний сетевой адаптер

IP_EXT="1.2.3.4" # Внешний IP
IP_INT="192.168.1.1" # Внутренний IP

FAKE_PORT="1293" # Фейковый порт, доступен из интернет

LOCAL_SRV="192.168.1.28" # Web сервер в LAN
SRV_PORT="443" # Настоящий порт

# NAT
$IPT -t nat -A PREROUTING -i $IF_EXT -p tcp -d $IP_EXT —dport $FAKE_PORT -j DNAT —to $LOCAL_SRV:$SRV_PORT

# FORWARD
$IPT -A FORWARD -i $IF_EXT -o $IF_INT -d $LOCAL_SRV -p tcp —dport $SRV_PORT -j ACCEPT

PREROUTING

Каждый пакет, попадающий на интерфейс, сначала предварительно обрабатывается (prerouting). Нам нужно, чтобы до того, как шлюз примет решение о маршрутизации (типа, а что с этим делать-то?), всем пакетам, пришедшим на внешний ($IF_EXT) интерфейс на порт 1293 (например, так: https://1.2.3.4:1293), был бы изменен пункт назначения на IP и порт сервера во внутренней сети. Т.е. шлюз "подкорректирует" destination пришедшего пакета так, чтобы можно было принять правильное решение о маршрутизации.

/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -d 1.2.3.4 —dport 1293 -j DNAT —to 192.168.1.28:443

Дальше пакет попадет в цепочку FORWARD.

FORWARD

Пакет изменен и, очевидно, что он не предназначен хосту 1.2.3.4. Хост знает, как добраться до локальной сети 192.168.1.0. Поэтому после прохождения цепочки PREROUTING пакет будет направлен на маршрутизацию (а не в INPUT или OUTPUT) — до хоста 192.168.1.28. Т.к. все FORWARD по умолчанию запрещены, разрешаем в явном виде отправку данных, попавших на внешний интерфейс, уходящих через внутренний интерфейс на адрес в локальной сети 192.168.1.28 на порт 443:

/sbin/iptables -A FORWARD -i eth0 -o eth1 -d 192.168.1.28 -p tcp —dport 443 -j ACCEPT

Читайте также:  Hp pavilion g6 notebook pc технические характеристики

Есть тонкость: это не маскарадинг (когда сервер-получатель не знает, откуда реально пришел запрос). Это изменение адреса назначения. Сервер в локальной сети получит пакет с реального адреса клиента, а не с ip шлюза. Это не плюс и не минус. Это просто факт. Иногда это удобно (когда именно ваш внутренний веб-сервер должен решать, давать кому-то доступ к его ресурсам или нет), а иногда — нет (это в данном случае ответ от веб-сервера пойдет через наш шлюз и не возникнет проблем, а если бы мы делали forward не в локальную сеть, а на другой публичный ip-адрес, то веб-сервер послал бы ответ не шлюзу, а сразу клиенту, и тот мог бы отбросить ответ от ip, который он не запрашивал).

Пример 2: FORWARD с одного ip на другой (DNAT с MASQUERADE, меняется адрес источника и назначения)

Не всегда перенаправление совершается из/в локальную сеть. Бывает, что необходимо сделать проброс соединения на какой-то сервер, используя промежуточный. Это может быть необходимо для дополнительной фильтрации подключаемых клиентов, для разделения нагрузки и других задач.

Есть хост с публичным IP-адресом (1.1.1.1), ему может быть сопоставлено доменное имя, для которого могут быть выпущены SSL-сертификаты и прочее.

Нужно, чтобы клиенты, обращающиеся на 1.1.1.1:25, направлялись бы на 2.2.2.2:25, с 1.1.1.1:443 — на 3.3.3.3:443, а с ip 4.4.4.4 обращения на порт 3535 шли бы на 3.3.3.3:22.

1.1.1.1, 2.2.2.2, 3.3.3.3 — это публичные IP-адреса (а могут быть и внутренними, не важно, могут быть от разных ISP и вообще, в разных местах). Подключающимся клиентам это знать незачем, не придется ничего перенастраивать в почтовых программах и т.п.

(!) Естественно, хосты 2.2.2.2 и 3.3.3.3 должны разрешать трафик на соответствующие порты!

Вот идея правил iptables на сервере 1.1.1.1:

Комментарии к скрипту:

1) INPUT разрешен только для 22/tcp, для ssh.

2) Несмотря на то, что интерфейс всего один, masquerade включен все равно. При переброске трафика все последующие сервера будут считать, что источник всего — это 1.1.1.1, а не реальные клиенты! Это важное отличие от предыдущего примера forward, когда менялся только адрес назначения!

3) Пусть вас не смущает, что OUTPUT по дефолту DROP, а ниже — все ACCEPT. Привык всегда вначале ставить DROP на все, а потом по необходимости разрешаю. В данном случае нет необходимости фильтровать исходящие со шлюза пакеты.

Отладка

На удаленном компьютере-клиенте запустите что-то вроде "telnet 1.1.1.1 25". Пакет должен прийти на 1.1.1.1:25. Это можно контролировать, запустив на сервере 1.1.1.1 в консоли команду:

Читайте также:  Canon ip2700 не видит картриджи

tcpdump -n port 25

Если все правильно, то на удаленном клиенте пойдет сеанс связи с SMTP-сервером 2.2.2.2.

Если что-то не так, вы должны понимать, что пакет все же пришел на 1.1.1.1:25. А вот потом не ушел. Он не должен попасть никуда, кроме FORWARD. Поэтому для отлова отбрасываемого трафика в цепочке FORWARD раскомментируйте правило лога (есть в примере) и просматривайте события в реальном времени (например, "tail -f /var/log/messages"). В соответствии с тем, что вы увидите в логе, испрвьте ваши правила iptables. Все должно получиться. Когда это произойдет, не забудьте выключить логирование (иначе размер лог-файла станет огромным).

Есть модем, который открывает свой 8080й порт и направляет его на комп на локали по адресу 192.168.1.2. На компе стоит точка доступа и мой ноут имеет адрес 192.168.0.16. Как направить этот траффик сразу на ноут (но через комп)?

Internet Modem (8080 -> 192.168.1.2:8080) PC (192.168.1.2) Laptop
. . . . . . . . . . . . . . . . . . . |_____|_________________________________________________________________/

Проброс трафика за NAT или проброс трафика на другой сервер

Чаще всего проброс трафика используется, если мы находимся в локальной сети и от внешнего мира отделены шлюзом. Для того, чтобы открыть доступ для локальных служб (ssh, web, ftp), нам необходимо пробросить порты. Поскольку в качестве шлюза мы будем использовать сервер на Linux, то осуществлять данные действия будем с помощью iptables.

Определимся с переменными, которые будут использоваться в статье:

$EXT_IP — внешний, реальный IP-адрес шлюза;
$INT_IP — внутренний IP-адрес шлюза, в локальной сети;
$LAN_IP — внутренний IP-адрес сервера, предоставляющего службы внешнему миру;
$SRV_PORT — порт службы. Для веб-сервера равен 80, для SMTP — 25 и т.д.;
eth0 — внешний интерфейс шлюза. Именно ему присвоен сетевой адрес $EXT_IP;
eth1 — внутренний интерфейс шлюза, с адресом $INT_IP;

Проброс портов

На шлюз приходит пакет, который мы должны перенаправить на нужный сервер в локальной сети перед принятием решения о маршрутизации, то есть — в цепочке PREROUTING таблицы nat.

Рассмотрим пример

Если входящий пакет пришёл извне на шлюз (1.2.3.4), но предназначен веб-серверу (порт 80), то адрес назначения подменяется на локальный адрес 192.168.1.50. И впоследствии маршрутизатор передаст пакет в локальную сеть.

Дальше принимается решение о маршрутизации. В результате пакет пойдёт по цепочке FORWARD таблицы filter, поэтому в неё надо добавить разрешающее правило. Оно может выглядеть, например, так:

Рассмотрим пример

Пропустить пакет, который пришёл на внешний интерфейс, уходит с внутреннего интерфейса и предназначен веб-серверу (192.168.1.50:80) локальной сети.

С одной стороны, этих двух правил уже достаточно для того, чтобы любые клиенты за пределами локальной сети успешно подключались к внутреннему серверу. С другой — а что будет, если попытается подключиться клиент из локальной сети? Подключение просто не состоится: стороны не поймут друг друга.

Читайте также:  1С загрузка справочника из файла

Допустим, 192.168.1.31 — ip-адрес клиента внутри локальной сети.

  1. Пользователь вводит в адресную строку браузера адрес example.com;
  2. Сервер обращается к DNS и разрешает имя example.com в адрес 1.2.3.4;
  3. Маршрутизатор понимает, что это внешний адрес и отправляет пакет на шлюз;
  4. Шлюз, в соответствии с нашим правилом, подменяет в пакете адрес 1.2.3.4 на 192.168.1.50, после чего отправляет пакет серверу;
  5. Веб-сервер видит, что клиент находится в этой же локальной сети (обратный адрес пакета — 192.168.1.31) и пытается передать данные напрямую клиенту, в обход шлюза;
  6. Клиент игнорирует ответ, потому что он приходит не с 1.2.3.4, а с 192.168.1.50;
  7. Клиент и сервер ждут, но связи и обмена данными нет.

Есть два способа избежать данной ситуации.

Первый — разграничивать обращения к серверу изнутри и извне, для этого создать на локальном DNS-сервере А-запись для example.com указывающую на 192.168.1.50

Второй — с помощью того же iptables заменить обратный адрес пакета.
Правило должно быть добавлено после принятия решения о маршрутизации и перед непосредственной отсылкой пакета. То есть — в цепочке POSTROUTING таблицы nat.

Рассмотрим пример

Если пакет предназначен веб-серверу, то обратный адрес клиента заменяется на внутренний адрес шлюза.
Этим мы гарантируем, что ответный пакет пойдёт через шлюз.

Надо дополнительно отметить, что это правило важно только для внутренних клиентов. Ответ внешним клиентам пойдёт через шлюз в любом случае.

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

Рассмотрим пример

Теперь для удобства запилим скрипт, чтобы не прописывать правила каждый раз вручную.

rules.sh

Теперь, чтобы обеспечить доступ извне к локальному FTP по адресу 192.168.1.52, достаточно набрать в консоли от имени супер-пользователя:

Перенаправление портов

Перенаправление портов нужно в том случае, если мы хотим «замаскировать» внутреннюю службу, обеспечив к ней доступ извне не по стандартному, а совсем по другому порту.

Пусть $FAKE_PORT — обманный порт на внешнем интерфейсе шлюза, подключившись к которому мы должны попасть на адрес $LAN_IP и порт $SRV_PORT .

Набор правил для iptables будет отличаться несущественно, поэтому приведу сразу пример итогового скрипта для ленивых.

Ссылка на основную публикацию
Adblock detector