Проброс портов внутрь LAN с помощью iptables

В данной статье рассказано, как сделать выход в интернет из сервера (ВМ) в локальной сети и
пробросить внешний порт публичного IP-адреса на локальный порт сервера (ВМ) внутри локальной сети. Все эти задачи реализуем при помощи iptables.

Синтаксис: iptables -t таблица команда

Ключи:
-L — список правил
-F — удалить все правила
-A — добавить правило

пример: iptables -t таблица -A цепочка правило

-D — удалить правило

пример: iptables -t таблица -D цепочка номер_правила

Для сохранения текущих правил выполните:

/etc/init.d/iptables save

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

Схема сети

Для начала нам нужно включить форвардинг:

echo 1 > /proc/sys/net/ipv4/ip_forward

Для того, чтобы это работало после перезагрузки, расcкомментируем строку в /etc/sysctl.conf:

net.ipv4.ip_forward=1

Доступ в Интернет

Предположим, что eth0 подключен к провайдеру и имеет IP-адрес в его подсети, допустим 199.199.199.2.

eth1 подключен к компьютеру в локальной сети, которому нужно обеспечить доступ в Интернет через NAT.
eth1 имеет адрес 10.10.10.1

IP-адрес компьютера, которому необходимо обеспечить доступ: 10.10.10.2 Даем доступ интерфейсу eth1 с IP-адреса 10.10.10.2:

iptables -t nat -A POSTROUTING -s 10.10.10.2 -o eth1 -j MASQUERADE
или всей подсети:
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth1 -j MASQUERADE

Проброс порта

Взависимости от ситуации внешний порт можно пробросить на локальную машину.

Например, у нас имеется ftp сервер внутри сети 10.10.10.2 порт 21, и нам нужно разрешить пользователям подключаться к нему из Интернета.

Внешний адрес — 199.199.199.2, адрес ftp — 10.10.10.2, порт — 21

iptables -t nat -A PREROUTING --dst 199.199.199.2 -p tcp --dport 21 -j DNAT --to-destination 10.10.10.2 
iptables -I FORWARD -i eth0 -o eth1 -d 10.10.10.2 -p tcp -m tcp --dport 21 -j ACCEPT
Первое правило добавляется в таблицу трансляции (-t nat) и перенапрявляет пакеты, посланные на порт 21, с адреса 199.199.199.2 на 10.10.10.2.
Второе правило разрешает пакетам проходить по данному маршруту.
Для проброса диапазона портов используется двоеточие.
Например для проброса всех портов используйте команды:

iptables -t nat -A PREROUTING --dst 199.199.199.2 -p tcp --dport 1024:65535 -j DNAT --to-destination 10.10.10.2 
iptables -I FORWARD -i eth0 -o eth1 -d 10.10.10.2 -p tcp -m tcp --dport 1024:65535 -j ACCEPT
Для маскировки сервиса, внешний порт можно изменить, например, с 21 на 4321.

Например, при подключении к 199.199.199.2:4321 клиент попадает на 10.10.10.2:21

iptables -t nat -A PREROUTING --dst 199.199.199.2 -p tcp -m tcp --dport 4321 -j DNAT --to-destination 10.10.10.2:21 
iptables -I FORWARD -i eth0 -o eth1 -d 10.10.10.2 -p tcp -m tcp --dport 21 -j ACCEPT

Пример скрипта

#!/bin/bash
dst_ip="10.0.3.55"
#dst_ports="445 139"
#dst_prot="tcp"
dst_ports="137 138"
dst_prot="udp"

for dst_port in $dst_ports; do
  echo $dst_port
  sudo iptables -t nat -A PREROUTING --dst 65.21.104.63 -p $dst_prot --dport $dst_port -j DNAT --to-destination ${dst_ip}:${dst_port}
  sudo iptables -I FORWARD 1 -i eth0 -o lxcbr0 -d $dst_ip -p $dst_prot -m $dst_prot --dport $dst_port -j ACCEPT

  sudo iptables -t nat -A PREROUTING --dst 65.21.104.63 -p $dst_prot --dport $dst_port -j DNAT --to-destination ${dst_ip}:${dst_port}
  sudo iptables -I FORWARD 1 -i eth0 -o lxcbr0 -d $dst_ip -p $dst_prot -m $dst_prot --dport $dst_port -j ACCEPT
done

iptables -t filter -L --line-numbers -n
Еще один пример - более универсальный

#!/bin/bash
src_ip="123.11.123.11"
dst_ip="10.0.3.131"
src_port="2201"
dst_port="22"
dst_prot="tcp"
src_if="eth0"


echo 'Перенаправляем '$src_ip':'$src_port' ===> '$dst_ip':'$dst_port
sudo iptables -t nat -A PREROUTING --dst $src_ip -p $dst_prot --dport $src_port -j DNAT --to-destination ${dst_ip}:${dst_port}
sudo iptables -I FORWARD 1 -i $src_if -o lxcbr0 -d $dst_ip -p $dst_prot -m $dst_prot --dport $dst_port -j ACCEPT
iptables -t filter -L --line-numbers -n