Принцип проброса портов в Linux

  • От Darkness9724
  • 2 мин чтения
  • Теги: 
  • linux

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

1. Подготовка

Для корректной работы проброса портов необходимо:

  • Удалённый сервер с белым IP-адресом, подключение к которому организуется через VPN или другие виды туннелирования сетевого уровня (например, SSH).
  • Убедиться, что нужные порты открыты на обоих хостах (локальном и удалённом). По-умолчанию netfilter не фильтрует порты.
  • На удалённом сервере разрешить пересылку пакетов между интерфейсами.
  • Настроить NAT и правила перенаправления в iptables или nftables.

2. Разрешение пересылки пакетов

На удалённой машине включаем форвардинг IPv4 (и IPv6 при необходимости), если он выключен (NixOS включает пересылку автоматически при обнаружении требующей этого конфигурации):

# Временно, до перезагрузки
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1

# Постоянно (добавить в /etc/sysctl.conf)
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Проверить можно командой:

sysctl net.ipv4.ip_forward
sysctl net.ipv6.conf.all.forwarding

3. Настройка NAT и проброс порта

Допустим, нам нужно пробросить UDP-порт 10800 с внешнего интерфейса eth0 удалённого сервера на внутренний хост 10.10.0.2:10800.

Вариант 1: через iptables

# Пробрасываем порт 10800/UDP с внешнего интерфейса на внутренний адрес
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 10800 -j DNAT --to-destination 10.10.0.2:10800

# Включаем маскарадинг, чтобы пакеты с внутреннего хоста могли корректно возвращаться через внешний интерфейс
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Сохраняем правила
iptables-save > /etc/iptables/rules.v4

Вариант 2: через nftables

# Создаём таблицу NAT, если её нет
nft add table ip nat

# Создаём цепочки
nft add chain ip nat prerouting { type nat hook prerouting priority 0; }
nft add chain ip nat postrouting { type nat hook postrouting priority 100; }

# Пробрасываем порт 10800/UDP
nft add rule ip nat prerouting iifname "eth0" udp dport 10800 dnat to 10.10.0.2:10800

# Включаем маскарадинг
nft add rule ip nat postrouting oifname "eth0" masquerade

# Сохраняем правила
nft list ruleset > /etc/nftables.conf

Для TCP будет тоже самое, достаточно заменить udp на tcp.

4. Проверка

Проверьте, что правила применились:

iptables -t nat -L -n -v
# или
nft list ruleset

Убедитесь, что порт доступен снаружи:

nc -u -v <внешний_IP_сервера> 10800

На локальной машине, куда проброшен порт, можно проверить, что пакеты действительно приходят, например, с помощью tcpdump:

tcpdump -n -i eth0 udp port 10800

5. NixOS

В этом плане NixOS простой как дрова. Для включения всего вышеперечисленного достаточно добавить этот блок в файл конфигурации (где бы он ни был):

{
  networking = {
    # Открываем порты
    firewall = {
      enable = true;
      allowedUDPPorts = [ 10800 ];
    };

    # Включаем маскарадинг
    nat = {
      enable = true;
      externalInterface = "eth0";
      internalInterfaces = [ "wg0" ];
    };

    # Пробрасываем порт 10800/UDP
    nftables = {
      enable = true;
      tables.nat.content = ''
        chain prerouting {
          type nat hook prerouting priority 0;
          iifname "eth0" udp dport 10800 dnat to 10.10.0.2:10800
        }
      '';
    };
  };
}

6. Итог

Теперь входящие соединения на удалённый сервер по порту 10800/UDP будут автоматически перенаправляться на внутренний хост 10.10.0.2:10800.