Linux dnat проброс портов

Перенаправление (forward) портов iptables

Рассмотрим перенаправление (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

Читайте также:  Zabbix чтение логов linux

Есть тонкость: это не маскарадинг (когда сервер-получатель не знает, откуда реально пришел запрос). Это изменение адреса назначения. Сервер в локальной сети получит пакет с реального адреса клиента, а не с 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:

#!/bin/sh IF_EXT="eth0" IPT="/sbin/iptables" # flush $IPT --flush $IPT -t nat --flush $IPT -t mangle --flush $IPT -X # loopback $IPT -A INPUT -i lo -j ACCEPT $IPT -A OUTPUT -o lo -j ACCEPT # default $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP # allow forwarding echo 1 > /proc/sys/net/ipv4/ip_forward # NAT $IPT -t nat -A PREROUTING -i $IF_EXT -p tcp --dport 25 -j DNAT --to 2.2.2.2:25 $IPT -t nat -A PREROUTING -i $IF_EXT -p tcp --dport 443 -j DNAT --to 3.3.3.3:443 $IPT -t nat -A PREROUTING -i $IF_EXT -p tcp -s 4.4.4.4 --dport 3535 -j DNAT --to 3.3.3.3:22 $IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE # FORWARD $IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A FORWARD -i $IF_EXT -o $IF_EXT -s 4.4.4.4 -d 3.3.3.3 -j ACCEPT $IPT -A FORWARD -i $IF_EXT -o $IF_EXT -d 2.2.2.2 -j ACCEPT $IPT -A FORWARD -i $IF_EXT -o $IF_EXT -d 3.3.3.3 -j ACCEPT # log #$IPT -A FORWARD -j LOG --log-prefix " ---FORWARD-LOG--- " # INPUT $IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # ssh $IPT -A INPUT -p tcp --dport 22 -j ACCEPT # OUTPUT $IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

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

Читайте также:  Play valorant on linux

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 в консоли команду:

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

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

$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
тут ошибка
должно быть
$IPT -t nat -A POSTROUTING -o $IF_INT -j MASQUERADE

проверил — работает — только маскарад проверял
ну и не мешало бы описать какие интерфейсы у вас IN а какие EXT
Спасибо! помогла статья!

Хм. Вроде бы все правильно. Вот это:
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
относится к случаю, когда внутренние пользователи из локалки лезут в интернет (NAT на внешнем сетевом интерфейсе). Т.е. после принятия решения о направлении трафика происходит подмена адреса на внешний IP на внешнем интерфейсе роутера.

А «$IPT -t nat -A PREROUTING -i $IF_EXT -p tcp —dport 25 -j DNAT —to 2.2.2.2:25»
происходит ДО принятия решения о маршрутизации. Просто пакет свалился на голову роутеру, роутер ДО принятия решения, что с ним делать, подменяет адрес назначения на конечный (2.2.2.2) и только потом уже принимает решение как этот пакет маршрутизировать дальше.

Авторизуйтесь для добавления комментариев!

Источник

Как пробросить порт в Linux

Как пробросить порт в Linux

Заметки айтишника

В этой статье поговорим о том, как можно перенаправить трафик с IP адреса (белого) на другой IP адрес (серый) использую утилиту iptables.

Начальные данные

У нас имеется компьютер под управлением linux, выступающий в роли маршрутизатора с одним внешним интерфейсом enp0s3 для доступа в Интернет (80.81.82.83) и внутренним enp0s8 интерфейсом Локальной сети (10.0.7.1). Требуется пробросить tcp порт (2121) с белого ip-адреса на серый ip-адрес Локальной сети порт (21).

Читайте также:  Linux current dns server

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

Алгоритм проброса портов в iptables.

В принципе все довольно просто, необходимо добавить всего два правила в таблицу маршрутизации iptables. Но для начала нам нужно включить форвардинг пакетов на нашем сервере:

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

Для автоматического включения открываем файл /etc/sysctl.conf и ищем там строку #net.ipv4.ip_forward=1 , убираем знак комментария.

Настройка port forwarding на Linux

Итак, приступим. Для выполнения поставленной задачи, перенаправление порта 2222 на порт 22 другой машины, необходимо добавить следующие правила iptables:

sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -j ACCEPT

Это правило разрешает прохождение входящих пакетов внутрь сети.

Теперь опишем форвардинг (forwarding) пакетов:

sudo iptables -t nat -A PREROUTING -p tcp -d 80.81.82.83 --dport 2222 -j DNAT --to-destination 10.0.7.2:22 sudo iptables -t nat -A POSTROUTING -p tcp --sport 22 --dst 10.0.7.2 -j SNAT --to-source 80.81.82.83:2222
  • Первая строка подменяет IP адрес приемника (белый IP) на внутренний (серый IP)
  • Вторая адрес отправителя (серый IP) на внешний (белый IP).
  • 10.0.7.2 — IP адрес машины в локальной сети, на который перенаправляет трафик.
  • 80.81.82.83 — внешний IP адрес нашего сервера.

Перенаправления всего трафика

iptables -t nat -A PREROUTING -p tcp -d 80.81.82.83 -j DNAT --to-destination 10.0.7.2 iptables -t nat -A POSTROUTING -p tcp --dst 10.0.7.2 -j SNAT --to-source 80.81.82.83

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

Содержимое файла по первому примеру:

#!/bin/sh # Перенаправляем ssh с 2222 на 22 IP-10.0.7.2 iptables -t nat -A PREROUTING -p tcp -d 80.81.82.83 --dport 2222 -j DNAT --to-destination 10.0.7.2:22 iptables -t nat -A POSTROUTING -p tcp -dst 10.0.7.2 --sport 22 -j SNAT --to-source 80.81.82.83:2222

Далее открываем файл interfaces

sudo nano /etc/network/interfaces

И добавляем в конце следующую строчку:

Данное выражение подгрузить правила iptables после перезагрузки системы.

Как посмотреть правила iptables

Посмотреть текущие правила iptables можно с помощью команды:

Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT tcp -- anywhere 80.81.82.83 tcp dpt:2222 to:10.0.7.2:22 Chain POSTROUTING (policy ACCEPT) SNAT tcp -- 10.0.7.2 anywhere tcp spt:ssh to:80.81.82.83:2222

Вот и все, на этом рассмотрение проброса портов в операционных системах под управлением Linux с помощью iptables завершено.

Источник

Оцените статью
Adblock
detector