Проброс портов (port forwarding) в linux используя iptables

Сценарии сетевых подключений

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

И так далее. Думаю, достаточно для простого примера. Смысл в том, чтобы максимально точно определить картину сетевого взаимодествия. Любой сценарий имеет только одну цель — формализовать взаимодействие с пользователями и сервисами до составления описаний соединений, включающих порт, протокол, адрес источника, адрес назначения для каждого соединения.

Настройка NAT (MASQUERADE)

Большинство организаций получает от своих интернет-провайдеров ограниченное количество публично доступных IP-адресов, поэтому администратору требуется разделять доступ к Интернету, не выдавая каждому узлу сети публичный IP-адрес. Для доступа к внутренним и внешним сетевым службам узлы локальной сети используют внутренний (частный) IP-адрес. Граничные маршрутизаторы (межсетевые экраны) могут получать входящие соединения из Интернета и передавать их нужным узлам локальной сети и наоборот, направлять исходящие соединения узлов удаленным интернет-службам. Такое перенаправление сетевого трафика может быть опасным, особенно учитывая доступность современных средств взлома, осуществляющих подмену внутренних IP-адресов и таким образом маскирующих машину злоумышленника под узел вашей локальной сети. Чтобы этого не случилось, в Iptables существуют политики маршрутизации и перенаправления, которые можно применять для исключения злонамеренного использования сетевых ресурсов. Политика FORWARD позволяет администратору контролировать маршрутизацию пакетов в локальной сети. Например, чтобы разрешить перенаправление всей локальной сети, можно установить следующие правила (в примере предполагается, что внутренний IP-адрес брандмауэра/шлюза назначен на интерфейсе eth1):

sudo iptables -A FORWARD -i eth1 -j ACCEPT
sudo iptables -A FORWARD -o eth1 -j ACCEPT

Эти правила предоставляют системам за шлюзом доступ к внутренней сети. Шлюз направляет пакеты от узла локальной сети к узлу назначения и наоборот (опции -o и -i), передавая их через устройство eth1.

net.ipv4.ip_forward = 1

Разрешение перенаправления пакетов внутренним интерфейсом брандмауэра позволяет узлам локальной сети связываться друг с другом, но у них не будет доступа в Интернет. Чтобы обеспечить узлам локальной сети с частными IP-адресами возможность связи с внешними публичными сетями, нужно настроить на брандмауэре трансляцию сетевых адресов (NAT). Создадим правило:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

В этом правиле используется таблица NAT, поэтому она указывается в явном виде (-t nat) и указана встроенная цепочка этой таблицы POSTROUTING для внешнего сетевого интерфейса eth0 (-o eth0). POSTROUTING позволяет изменять пакеты, когда они выходят из внешнего интерфейса шлюза. Целевое действие -j MASQUERADE заменяет (маскирует) частный IP-адрес узла внешним IP-адресом шлюза. Это называется IP-маскарадингом.

Форвардинг портов на другую машину

По сути форвардинг портов на другую машину не отличается от форварда портов в пределах одной машины, но по существу это не одно и то же, поскольку пакеты будут передаваться не в пределах одной машины, как в случае с loopback-интерфейсом, когда фактически пакеты транслируются в пределах сетевого стека. Обычно форвардинг портов производится с определенного порта внешнего интерфейса на определенный порт машины во внутренней сети, поэтому между сетевыми интерфейсами должен быть настроен форвардинг. Например, проброс порта 3389 для работы удаленного рабочего стола (RDP) с внешнего сетевого интерфейса (192.168.100.25) на порт 3389 на одну из машин во внутренней сети (192.168.0.15):

iptables -t nat -A PREROUTING -d 192.168.100.25/32 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.15:3389
iptables -t nat -A POSTROUTING -s 192.168.0.15/32 -p tcp -m tcp --dport 3389 -j SNAT --to-source 192.168.100.25

Как открыть один порт

Рассмотрим синтаксис команды.

На практике аргумент -t опускается. Для первого примера откроем 80 port для протокола tcp.

Здесь:

  • -A — добавить новое правило в цепочку;
  • -p — протокол tcp;
  • ACCEPT — разрешить.

После этого все внешние устройства смогут установить связь по порту 80 (для примера). Теперь сделаем тоже самое, только для протокола udp

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

После выполнения данного действия порт с указанным номером откроется на вашем ПК.

Открытие нескольких портов сразу

Для примера откроем диапазон портов с 18060:18071.

Что получится в результате? Теперь возможен прием входящих пакетов, передаваемых по протоколу на локальный ПК. Порты 18060-18071 открылись одновременно.

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

Теперь перейдем к настройкам исходящего коннекта. Пользователю нужно задать команду аналогичного вида. Единственная разница будет заключаться в изменении «INPUT» на «OUTPUT». Во всем остальном указанная схема остается без изменений.

Как проверить статус порта

На практике очень часто бывает так, что введенная команда не работает. Чтобы не попасть в такую ситуацию, необходимо проверить состояния порта. Для этих целей используется telnet.

Проверка порта осуществляется таким образом:

Как видно по заданной команде, система проверит порт под номером 8080 у компьютера с указанным IP-адресом. А теперь представим ситуацию, что порт 445 на удаленном устройстве открыт для входящего коннекта, а порт 445 на локальном устройстве открыт для исходящего коннекта. При таких условиях на экран будет выведено сообщение данного вида: «Connection closed by foreign host». В обратном случае выведенное сообщение будет носить иной характер. И это можно воспринять, как невозможность дальнейшего соединения.

Заключение

Открытие порта iptables на локальном устройстве вызывает множество различных трудностей у новичков. Внимательно следуя рекомендациям в данной статье, можно быстро приучиться к новшествам системы Линукс и решить все незакрытые вопросы. Воспользуйтесь подсказками, если вам потребуется открыть один или сразу несколько портов на своём ПК, закрыть его или проверить актуальный статус портов на нескольких машинах. Создайте новый коннект («NEW») или отточите своё мастерство при работе с уже установленными коннектами.

Базовая конфигурация

Ниже приведён пример базовой статической конфигурации iptables

При сохранении и загрузке подобной конфигурации необходимо принимать во внимание возможность внесения в неё изменений со стороны других сервисов, например Fail2ban. Кроме того, при использовании IPv6-адресации конфигурацию для IPv6 следует выполнять независимо от IPv4.

IPv4

Просмотр текущей конфигурации:

sudo iptables-save

Создаём скрипт с дампом правил iptables:

sudo nano etcnetworkif-up.diptables-rules

Копируем следующий код:

#!/sbin/iptables-restore
# Таблица filter и её цепочки
*filter
:INPUT ACCEPT :
:FORWARD ACCEPT :
:OUTPUT ACCEPT :
# Разрешаем связанные и установленые соединения
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Разрешаем служебный icmp-трафик
-A INPUT -p icmp -j ACCEPT
# Разрешаем доверенный трафик на интерфейс loopback
-A INPUT -i lo -j ACCEPT
# Сюда можно вставлять дополнительные правила для цепочки INPUT
# Запрещаем всё остальное для INPUT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
# Порядок и смысл правил для цепочек FORWARD и OUTPUT аналогичен INPUT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
# Фильтровать цепочку OUTPUT настоятельно не рекомендуется
#-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#-A OUTPUT -p icmp -j ACCEPT
#-A OUTPUT -o lo -j ACCEPT
#-A OUTPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

Дополняем нужными правилами с учётом iptables-save.

Сохраняем и закрываем: Ctrl+O, Enter, Ctrl+X

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

sudo chmod +x etcnetworkif-up.diptables-rules
sudo etcnetworkif-up.diptables-rules

IPv6

Просмотр текущей конфигурации:

sudo ip6tables-save

Создаём скрипт с дампом правил ip6tables:

sudo nano etcnetworkif-up.dip6tables-rules

Копируем следующий код:

#!/sbin/ip6tables-restore
# Таблица filter и её цепочки
*filter
:INPUT ACCEPT :
:FORWARD ACCEPT :
:OUTPUT ACCEPT :
# Разрешаем связанные и установленые соединения
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Разрешаем служебный icmp-трафик
-A INPUT -p ipv6-icmp -j ACCEPT
# Разрешаем доверенный трафик на интерфейс loopback
-A INPUT -i lo -j ACCEPT
# Сюда можно вставлять дополнительные правила для цепочки INPUT
# Запрещаем всё остальное для INPUT
-A INPUT -j REJECT --reject-with icmp6-adm-prohibited
# Порядок и смысл правил для цепочек FORWARD и OUTPUT аналогичен INPUT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -p ipv6-icmp -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
# Фильтровать цепочку OUTPUT настоятельно не рекомендуется
#-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#-A OUTPUT -p ipv6-icmp -j ACCEPT
#-A OUTPUT -o lo -j ACCEPT
#-A OUTPUT -j REJECT --reject-with icmp6-adm-prohibited
COMMIT

Дополняем нужными правилами с учётом ip6tables-save.

Сохраняем и закрываем: Ctrl+O, Enter, Ctrl+X

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

sudo chmod +x etcnetworkif-up.dip6tables-rules
sudo etcnetworkif-up.dip6tables-rules

Как открыть порт в Убунту

Теперь рассмотрим нашу вторую часть сегодняшнего обсуждения. Прежде всего вам потребуется запустить консоль для ввода команд и скриптов. Далее, пробуем следующие две комбинации, которые позволят вам открыть определённый порт. Стоит отметить, что все выполняемые действия производятся на ваш страх и риск, так как они предназначены для опытных пользователей. Любые неверные шаги или же неблагополучные манипуляции могут привести вас к неприятным последствиям. Например, есть вероятность потерять важные файлы и данные или же поломать что-нибудь в строе системы. Приступайте к следующим действиям только при полной уверенности своих сил и возможностей.

Способ первый

Ниже рассматриваются примеры для порта 7777:

  1. Итак, добавляем в нашу консоль правило: iptables -t filter -A INPUT -i eth0 -p tcp —dport 7777 -j ACCEPT. 
  2. Если так не получилось, то стоит проверить настройки конфигурации файрволла, только потом ввести следующее значение: iptables -L. После этого для открытия нужного порта используете консольную команду: iptables -A INPUT -p tcp —dport 777 -j ACCEPT.
  3. Если же и эта команда вам не помогла, то воспользуйтесь следующей: sudo iptables -A INPUT -p tcp —dport 7777-j ACCEPT.

Стоит отметить, однако, очень важный момент. Дело в том, что файрволл iptables имеется абсолютно во всех дистрибутивах Linux. Более того, правила их являются также одинаковыми, но зато настройка и запуск может различаться. Вот почему может понадобиться наличие универсального способа. Вероятнее всего, что опытные пользователи не применят его, но вот обычные юзеры вполне могут воспользоваться им.

Способ второй

  1. Для начала стоит проверить наличие iptables в вашей ОС. Для этого делаем следующую команду в консоли: iptables -list. После этого вы получите необходимые вами данные.
  2. Наиболее приемлемым вариантом будет закрытие всех портов, необходимых операционке. Далее, устанавливая правила, откройте порты Linux для игры, трансфера документов и веб-сёрфинга. Чтобы сделать это, убедитесь в наличие iptables. После этого создайте файл /etc/iptables.sh с суперпользовательскими правами. Содержание файла будет следующее:

Этот скрипт подходит для всех дистрибутивов Linux, в том числе и Ubuntu. Поэтому можно не волноваться по поводу несовместимости кодов и их работы в операционной системе. Но вдруг если ни один из этих методов вам не помог, потребуется дополнительная диагностика. Например, вы можете посмотреть, не занят ли случайно необходимый порт другим приложением. Если ответ будет положительным, то понадобится закрыть все утилиты, связанные с ним. Только потом можно будет повторить свои попытки со скриптами и кодами.

Как закрыть порт iptables

Если вы открыли порт с помощью описанных выше правил и политика брандмауэра по умолчанию DROP, то достаточно это правило удалить. Если же у вас стоит политика по умолчанию ACCEPT, то чтобы закрыть порт надо использовать действие DROP.

Например:

Эта команда в таблицу filter в цепочку INPUT запишет правило для протокола TCP, от компьютера из подсети 192.168.3.0/24, на порт назначения 445 (так как цепочка входящая, то порт назначения находится на данном компьютере) для пакетов, поступающих в рамках уже открытого соединения, применять действие DROP (отбросить пакет).

Для правил, запрещающих прием пакета, применимо всё сказанное выше для закрытия порта (одиночный порт, диапазон портов, входящие и исходящие соединения, действия для установленных соединений и новых соединений). Про закрытие портов в iptables читайте более подробно в отдельной статье.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: