Как перенаправлять порты через шлюз Linux с помощью Iptables
Большое количество компьютеров в сети постепенно начало становиться проблемой, ведь в IPv4 встроена поддержка относительно ограниченного количества хостов. Обойти лимиты получилось при помощи технологии NAT, позволяющей объединять любые офисные сети таким образом, чтобы внутри они работали «как обычно», а для внешних клиентов были доступны по одному IP-адресу (обычно установленному для сетевого устройства, роутера или маршрутизатора).
Оборудование считывает из пакета данных информацию о локальной машине, для которой адресованы переданные блоки, и подменяет IP на реальный. Те же операции доступны и для портов – NAT меняет их значение, эта процедура получила название «проброс портов». Ее используют при необходимости получения внешнего трафика в частную сеть. На базе платформы Linux управление технологией осуществляется утилитой IPTables.
Принцип работы NAT
Первое и наиболее важное условие для функционирования любой системы – уникальный IP-адрес у каждого компьютера, объединенного в сеть. Но резкий рост количества объединяемых хостов привел к тому, что номеров стало не хватать. И пришлось продумывать варианты, как временно объединить несколько машин под одним адресом – это и стало толчком к появлению технологии Network Address Translation (NAT), так называемому форвардингу портов.
Система функционирует довольно просто. Фактически компьютеры не видны извне, хотя имеют уникальные IP-адреса. Их фильтрует маршрутизатор, который и занимается подменой. Например, локальная машина отправила пакет на внешний ресурс. Тот сначала попадает в память сетевого устройства, которое подменяет адрес отправителя на собственный и отправляет данные дальше. В памяти роутера сохраняется информация, откуда пришел пакет и куда отправлять ответ.
Единственный минус такого подхода заключается в невозможности инициации подключения к ПК напрямую извне. Ведь в таком случае маршрутизатор не знает, какой именно компьютер нужен, и соединение отсекается. Хотя при помощи утилиты IPTables можно настроить NAT, если роутер работает под управлением операционки Debian 10.
Проброс портов в iptables
Первым шагом активируем режим переадресации трафика, которая будет работать на уровне ядра (возможно, это уже сделано, но лучше убедиться):
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Важно обеспечить сохранение настройки после перезапуска сетевого оборудования:
sudo sysctl -w net.ipv4.ip_forward=1
Перед началом работы можно подробнее ознакомиться с официальной справкой по IPTables, но особой необходимости в этом нет, управление утилитой не вызывает затруднений.
Настройка прохождения пакетов
В начале процедуры требуется включить режим пропуска пакетов сквозь сетевое устройство. В утилите IPTables для этого используют цепочку FORWARD
. Настройки по умолчанию предполагают отклонение всех поступающих на маршрутизатор пакетов данных (срабатывает правило DROP
). Поэтому нужно разрешить инициализировать новые коннекты, поступающие от eth0
до eth1
. Они получают назначение типа conntrack с представлением в виде пакета SYN
:
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
Внесение правила ACCEPT
необходимо для разрешения текущего соединения. Оно имеет действие только на первый поступающий пакет, а ведь еще предстоит давать ответ и отправлять «обратные» пакеты. Поэтому включим возможность коннекта в обе стороны через порт 80, в этом нам помогут правила ESTABLIHED
и RELATED
:
sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Теперь укажем, что по умолчанию требуется применять политику DROP
:
sudo iptables -P FORWARD DROP
Первоначальная настройка завершена – мы включили возможность прохождения трафика на порт 80 и обратно. Но это еще не все, проброс портов пока не работает, потому что нужно настроить еще несколько правил, отвечающих за перенаправление потоков данных.
Модификация пакетов в IPTables
Чтобы сделать это, укажем маршрутизатору, как модифицировать адрес компьютера, для которого предназначены пакеты (Destination) DNAT
и адрес отправляющей машины (Source) SNAT
. Первые будем настраивать в цепочке PREROUTING
в таблице NAT. Процедура изменит адрес на нужный для достижения требуемой цели при прохождении информации между разными сетями. Пакеты же исходящего направления будут автоматом направляться на веб-сервер с IP 192.168.1.2.
Обращение происходит на порт 80:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2
Половина требуемого сделана. Теперь в пакет будет включен изначальный адрес рабочего места, а это означает, что на него уже можно отправлять ответные пакеты. Но локальная машина ожидает их от маршрутизатора, а не от внешнего ресурса, поэтому придется решить еще одну проблему – сетевое оборудование должно менять входящий IP на внутренний, принадлежащий конкретному компьютеру (в нашем случае 192.168.1.1).
sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 192.168.1.2 -j SNAT --to-source 192.168.1.1
При перенаправлении трафика на другой порт, например, 8080, его указывают после IP:
sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 192.168.1.2 -j SNAT --to-source 192.168.1.1:8080
Когда речь идет о пробросе диапазона портов, их указывают следующим образом:
sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 1000:2000 -d 192.168.1.2 -j SNAT --to-source 192.168.1.1
Теперь можно проверить работоспособность перенаправления трафика через IPTables и понять, все ли работает, как предполагалось.
Сохранение настроек IPTables
Далее рекомендуется сохранить внесенные настройки, чтобы при перезапуске оборудования они остались прежними. Выполним это командой:
sudo service iptables-persistent save
Выводы
Мы разобрались, как работает проброс портов в Debian. Процедура предполагает настройку обоих направлений передачи данных. Тогда система поймет, откуда пришел пакет и куда возвращать ответ, если тот поступит на маршрутизатор. В качестве тренировки можно настроить подобный коннект с удаленным сервером, арендованным у провайдера timeweb.cloud.