Linux

Настройка port forwarding на Linux: подробное руководство

Этот гайд поможет вам настроить перенаправление портов на Linux, чтобы предоставить доступ к локальным сервисам из внешней сети. Мы рассмотрим способы с iptables и firewalld.

Обновлено 17 февраля 2026 г.
10-15 мин
Средняя
FixPedia Team
Применимо к:Ubuntu 20.04+CentOS 7+Debian 10+Fedora 35+

Введение / Зачем это нужно

Port forwarding (перенаправление портов) позволяет сделать локальный сервис, работающий на внутреннем IP-адресе и порту, доступным из внешней сети через публичный IP и порт вашего Linux-сервера. Это незаменимо, когда вы хотите, например, предоставить доступ к веб-серверу на порту 8080, базе данных или SSH-демону, находящимся за NAT, без изменения конфигурации самих сервисов.

После выполнения этого гайда вы сможете настроить перенаправление входящего трафика с порта 80 на внутренний сервер 192.168.1.100:8080, или с порта 2222 на внутренний SSH-сервер 192.168.1.100:22 — в зависимости от ваших задач.

Требования / Подготовка

Перед началом убедитесь, что:

  • У вас есть доступ к Linux-системе (Ubuntu, CentOS, Debian, Fedora и т.д.) с правами sudo или root.
  • На системе установлен и работает iptables (для классических дистрибутивов) или firewalld (для CentOS/RHEL/Fedora). Проверить можно командами:
    sudo systemctl status iptables   # для iptables
    sudo systemctl status firewalld  # для firewalld
    
  • Вы знаете внутренний IP-адрес и порт сервиса, который хотите пробросить. Узнать можно через:
    ip addr show
    
    или
    hostname -I
    
  • У вас есть публичный IP-адрес (или доменное имя), на который будет приходить входящий трафик. Если сервер находится в локальной сети, это IP вашего роутера, и на нём должен быть настроен проброс портов (port forwarding на роутере) на ваш Linux-сервер.

Шаг 1: Включение IP-форвардинга в ядре

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

sudo sysctl -w net.ipv4.ip_forward=1

Чтобы включить навсегда (чтобы настройка сохранилась после перезагрузки), отредактируйте файл /etc/sysctl.conf или создайте новый в /etc/sysctl.d/:

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ipforward.conf
sudo sysctl -p /etc/sysctl.d/99-ipforward.conf

⚠️ Важно: Если вы используете IPv6, также включите форвардинг для него, добавив net.ipv6.conf.all.forwarding=1 в тот же файл.

Шаг 2: Настройка port forwarding с iptables

Этот способ подходит для дистрибутивов, где по умолчанию используется iptables (например, Ubuntu до 20.04, Debian, CentOS 6/7 без firewalld).

Предположим, вы хотите пробросить входящие подключения на порт 80 (HTTP) к внутреннему серверу с IP 192.168.1.100 на порт 8080.

  1. Добавьте правило DNAT (изменение адреса назначения) в таблицу nat для цепочки PREROUTING. Это правило сработает для входящих пакетов, предназначенных для порта 80:
    sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
    
    • -t nat — указывает таблицу NAT.
    • -A PREROUTING — добавляет правило в конец цепочки PREROUTING (обрабатывает пакеты до маршрутизации).
    • -p tcp — протокол TCP (для UDP замените на udp).
    • --dport 80 — целевой порт на внешнем интерфейсе.
    • -j DNAT — цель — изменить адрес назначения.
    • --to-destination 192.168.1.100:8080 — новый адрес и порт.
  2. Разрешите проброс пакетов в цепочке FORWARD. Это нужно, чтобы ядро не блокировало пересылку пакетов к внутреннему серверу:
    sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 8080 -j ACCEPT
    

    Если у внутреннего сервера есть необходимость выходить в интернет через этот же шлюз, добавьте правило MASQUERADE (маскировка) для исходящего трафика:
    sudo iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 8080 -j MASQUERADE
    

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

Шаг 3: Настройка port forwarding с firewalld

Для дистрибутивов с firewalld (CentOS 7+, RHEL 7+, Fedora) используйте более простой синтаксис с зонами.

  1. Определите активную зону (например, public):
    sudo firewall-cmd --get-default-zone
    

    Обычно это public.
  2. Добавьте правило port forwarding в эту зону. Для проброса порта 80 на 192.168.1.100:8080:
    sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080
    
    • --add-forward-port — добавляет правило проброса порта.
    • port=80 — внешний порт.
    • proto=tcp — протокол (можно udp).
    • toaddr=192.168.1.100 — внутренний IP.
    • toport=8080 — внутренний порт.
  3. Сделайте правило постоянным (чтобы оно сохранилось после перезагрузки):
    sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080 --permanent
    

    💡 Совет: Если ваш внутренний сервер должен иметь доступ в интернет через этот же шлюз, включите маскарадинг:

    sudo firewall-cmd --zone=public --add-masquerade --permanent
    

Шаг 4: Сохранение правил

Правила iptables и firewalld по-разному сохраняются.

Для iptables

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

  • Ubuntu/Debian с пакетом iptables-persistent:
    sudo netfilter-persistent save
    

    Или вручную:
    sudo iptables-save > /etc/iptables/rules.v4
    
  • CentOS 6/7 (если не используется firewalld):
    sudo service iptables save
    

    или
    sudo /etc/init.d/iptables save
    

Для firewalld

Правила, добавленные с флагом --permanent, сохраняются в конфигурационных файлах (/etc/firewalld/). После добавления правил перезагрузите firewalld, чтобы убедиться, что они применены:

sudo firewall-cmd --reload

Шаг 5: Проверка работоспособности

  1. Просмотрите активные правила:
    • Для iptables:
      sudo iptables -t nat -L -n -v
      
      Вы должны увидеть правило в цепочке PREROUTING и FORWARD.
    • Для firewalld:
      sudo firewall-cmd --list-all
      
      В выводе ищите forward-ports.
  2. Проверьте, что порт открыт на внешнем интерфейсе. Обратите внимание: после DNAT порт 80 на публичном интерфейсе не слушается демоном, а перенаправляется. Поэтому команда ss -tuln | grep :80 может не показать ничего. Лучше проверить снаружи.
  3. Протестируйте извне:
    • С другого компьютера в сети или из интернета выполните:
      curl http://публичный_IP:80
      
      или
      telnet публичный_IP 80
      
    • Должны получить ответ от внутреннего сервера (например, веб-страницу с порта 8080).

    Если сервис использует HTTPS, замените порт 80 на 443 и протокол на https.

Возможные проблемы

Правила не работают после перезагрузки

  • iptables: Вы не сохранили правила. Выполните sudo netfilter-persistent save или аналогичную команду для вашего дистрибутива.
  • firewalld: Вы добавили правило без --permanent. Исправьте: sudo firewall-cmd --zone=public --add-forward-port=... --permanent и перезагрузите.

Ошибка "Permission denied" или "Operation not permitted"

  • Убедитесь, что вы выполняете команды с sudo или от root. Port forwarding требует прав администратора.

Порт уже занят

  • На внешнем порту (например, 80) уже работает другой сервис (веб-сервер Apache/Nginx). Остановите его или выберите другой порт.
  • Проверьте: sudo ss -tuln | grep :80

Неверный внутренний IP

  • Убедитесь, что IP 192.168.1.100 корректен и сервис на нём запущен. Проверьте: ping 192.168.1.100 и curl http://192.168.1.100:8080 с самого Linux-сервера.

Конфликт firewalld и iptables

  • На системах с firewalld (CentOS 7+) не используйте iptables напрямую — firewalld управляет правилами через iptables. Вместо этого настраивайте всё через firewall-cmd. Если вы случайно добавили правило iptables, оно может быть перезаписано firewalld.

Блокировка SELinux (для CentOS/RHEL/Fedora)

  • SELinux по умолчанию может запрещать проброс портов. Временно отключите для теста:
    sudo setenforce 0
    
    Если это помогло, настройте политики SELinux правильно. Для firewalld обычно проблем нет, но для iptables может потребоваться:
    sudo semanage port -a -t http_port_t -p tcp 80
    

Внутренний сервис не отвечает

  • Проверьте, что сервис (например, веб-сервер) слушает на 0.0.0.0:8080 или на внутреннем IP, а не только на 127.0.0.1. Используйте sudo ss -tuln | grep 8080.
  • Убедитесь, что на внутреннем сервере (если он отдельный) есть маршрут обратно к клиенту через ваш шлюз. Иногда требуется добавить статический маршрут или настроить NAT на шлюзе.

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

  • Для UDP используйте те же команды, но замените tcp на udp в iptables или proto=udp в firewalld. Пример для firewalld:
    sudo firewall-cmd --zone=public --add-forward-port=port=53:proto=udp:toaddr=192.168.1.100:toport=53 --permanent
    

Часто задаваемые вопросы

Что такое port forwarding и для чего он используется?
Какой способ лучше: iptables или firewalld?
Как проверить, что port forwarding работает?
Нужны ли root-права для настройки port forwarding?

Полезное

Включите IP-форвардинг в ядре Linux
Добавьте правило port forwarding
Сохраните правила для постоянного применения
Протестируйте перенаправление портов

Эта статья помогла вам решить проблему?