NAT - приклади

Програма fw4 OpenWrt має розширену підтримку NAT-фільтрації. NAT — це потужна функція для перенаправлення мережевого трафіку, що заслуговує на визнання як фактор, який продовжив життя протоколу IPv4.

У цьому розділі наведено типові приклади використання можливостей NAT у fw4. Як і в інших розділах про файрвол, тут не розглядаються теоретичні аспекти NAT. Ось кілька корисних посилань для глибшого ознайомлення:

Для діагностики NAT дивіться Управління Netfilter, щоб проаналізувати правила та дослідити сесії conntrack.

Програма fw4 в OpenWrt підтримує DNAT, SNAT та MASQUERADING. Наведені нижче приклади можна використати у файлі конфігурації fw4 /etc/config/firewall.

Для публічних серверів за файрволом використовується DNAT — перетворення публічної IP-адреси на стороні WAN на приватну адресу LAN сервера.

:!: Сервер, доступний з Інтернету, є вразливим. Рекомендується розмістити публічні сервери в демілітаризованій зоні (DMZ) для підвищення безпеки.

DNAT: Переадресація порту для IPv4

Мета цього правила — перенаправити весь вхідний трафік з порту 2222 на інтерфейсі WAN на порт 22 (SSH) конкретного пристрою в LAN.

config redirect
       option name            'Example of SSH DNAT'
       option target          DNAT
       option src             wan
       option dest            lan
       option proto           tcp
       option src_dport       2222
       option dest_ip         192.168.10.20
       option dest_port       22
       option enabled         1

Для перевірки з боку клієнта в мережі WAN (STA1) виконайте:

ssh -p 2222 203.0.113.8 "hostname; cat /proc/version"

Після активації правила пристрій STA2 відповість своєю назвою хоста та версією ядра. Якщо правило вимкнено — з'єднання буде відхилено.

Для допитливих: «Які саме правила netfilter генерує fw4?»:

# fw4 print | awk '/\{/ { p=$0 }; /Example/ { print p, $0, "}"; }' | tr -d '\t'
chain dstnat_wan { meta nfproto ipv4 tcp dport 2222 counter dnat 192.168.10.20:22                     comment "!fw4: Example of SSH DNAT" }
chain dstnat_lan { ip saddr 192.168.10.0/24 ip daddr 203.0.113.8 tcp dport 2222 dnat 192.168.10.20:22 comment "!fw4: Example of SSH DNAT (reflection)" }
chain srcnat_lan { ip saddr 192.168.10.0/24 ip daddr 192.168.10.20 tcp dport 22 snat 192.168.10.1     comment "!fw4: Example of SSH DNAT (reflection)" }

Netfilter використовує ці правила, зіставляючи записи з таблицею conntrack.

Пояснення:

  • Перше правило стосується з'єднань із WAN на порт 2222 і перенаправляє їх на IP LAN-сервера — 192.168.10.20:22.
  • Друге правило — для випадків, коли пристрій з LAN намагається підключитися до публічної адреси (віддзеркалення, reflection).
  • Третє правило змінює IP-адресу джерела на адресу маршрутизатора (SNAT), щоб сервер «бачив» з'єднання як такі, що йдуть від шлюзу.

DNAT: Пінг з певної WAN IP до LAN-пристрою

Це правило DNAT дозволяє ICMP-запити (ping) з певної IP-адреси на стороні WAN (наприклад, 1.2.3.4) перенаправляти до конкретного пристрою в LAN.

config redirect
        option src      wan
        option src_dip  1.2.3.4
        option proto    icmp
        option dest     lan
        option dest_ip  192.168.10.20
        option target   DNAT
        option name     DNAT-ICMP-WAN-LAN
        option enabled  1

DNAT: Публічний сервер у мережі LAN

Схема DNAT

У цьому прикладі STA2 знаходиться всередині LAN і працює як поштовий сервер (наприклад, postfix), що слухає порт 2525 для вхідної пошти.

config redirect
        option target DNAT
        option src wan
        option src_dport 25
        option proto tcp
        option family ipv4
        option dest lan
        option dest_ip 192.168.10.20
        option dest_port 2525
        option name DNAT-MAIL-SERVER
        option enabled 1

Це правило означає: увесь вхідний трафік з порту 25 на стороні WAN буде перенаправлений на порт 2525 пристрою STA2 у мережі LAN.

Для перевірки можна переглянути /proc/net/nf_conntrack, щоб відслідкувати активні з’єднання. Оскільки там може бути багато записів, шукаємо тільки ті, що використовують порт 2525:

# grep port=2525 /proc/net/nf_conntrack
...
ipv4     2 tcp      6 7436 ESTABLISHED src=198.51.100.171 dst=203.0.113.8 sport=41370 dport=25 packets=4 bytes=229 src=192.168.10.20 dst=198.51.100.171 sport=2525 dport=41370 packets=3 bytes=164 [ASSURED] mark=0 use=2
...

З’єднання надходить з STA1 (порт 25) до маршрутизатора (DUT) і транслюється до STA2 (порт 2525) з відповіддю назад на STA1.

Відповідний трафік відповідає стану DNAT у conntrack, що дозволяє OpenWrt маршрутизувати його без додаткових правил у файрволі.

Мета цього правила — транслювати IP-адресу джерела зі справжньої IP на вигадану, для трафіку, що йде через порт 8080.

config redirect
        option target           SNAT
        option src              lan
        option dest             wan
        option proto            tcp
        option src_ip           192.168.10.20
        option src_dip          192.168.10.13
        option dest_port        8080
        option enabled          1

Для тестування:

  1. На станції STA1 (WAN) запустіть: `nc -l 8080`
  2. На станції STA2 (LAN): `nc -v 192.168.3.171 8080`

Введіть щось на STA2 і перевірте, що воно з’явилось на STA1. На STA1 перевірте активне з’єднання командою `netstat -ntap` — з’явиться рядок:

tcp        0      0 192.168.3.171:8080      192.168.10.13:47970 ESTABLISHED 16746/nc

Це підтверджує, що SNAT працює — з’єднання надійшло від IP-адреси 192.168.10.13 (а не реального STA2).

SNAT може використовуватись, щоб обмежити пристрою повноцінний вихід в інтернет, дозволяючи лише доступ до певних сервісів (наприклад, NTP).

*DNAT ховає LAN від інтернету, а SNAT — інтернет від LAN.*

Це найпоширеніша і найкорисніша форма NAT. Вона транслює локальні приватні IP-адреси на стороні LAN у публічну адресу/порт на стороні WAN — і навпаки.

MASQUERADE — це стандартна конфігурація файрволу для кожного IPv4-маршрутизатора, тому конфігурація у fw4 дуже проста:

config zone
  option name 'wan'
  list network 'wan'
  ....
  option masq '1'

Просто, правда ж?

Маршрутизатор зазвичай отримує свою IP-адресу на WAN від DHCP-сервера провайдера, а сам виконує роль DHCP- і DNS-сервера для LAN. Файл конфігурації `network` визначає приватну підмережу, а файл `dhcp` — як маршрутизатор роздає IP-адреси у LAN.

При включеному MASQUERADE весь трафік між WAN і LAN транслюється. Завдяки цьому, помилки в конфігурації таких правил зустрічаються дуже рідко.

Щоб перевірити активні з’єднання MASQUERADE, перегляньте `conntrack`:

ipv4     2 tcp      6 4615 ESTABLISHED src=192.168.3.171 dst=192.168.10.20 sport=60446 dport=22 packets=27 bytes=1812 src=192.168.10.20 dst=192.168.3.171 sport=22 dport=60446 packets=21 bytes=2544 [ASSURED] mark=0 use=2

Цей запис показує SSH-з’єднання від STA1 до STA2, модифіковане правилами MASQUERADE.

:!: MASQUERADE підтримує дві або більше приватних LAN-зони

:!: не протестовано

Наступне правило перенаправляє весь HTTP-трафік із LAN через зовнішній проксі на 192.168.1.100, який слухає порт 3128. Передбачається, що адреса lan — це 192.168.1.1. Це необхідно, щоб маскувати перенаправлений трафік до проксі.

config redirect
        option src              lan
        option proto            tcp
        option src_ip           !192.168.1.100
        option src_dport        80
        option dest_ip          192.168.1.100
        option dest_port        3128
        option target           DNAT
 
config redirect
        option dest             lan
        option proto            tcp
        option src_dip          192.168.1.1
        option dest_ip          192.168.1.100
        option dest_port        3128
        option target           SNAT

Увімкнення маскування (NAT) для зони WAN.

uci set firewall.@zone[1].masq="1"
uci commit firewall
service firewall restart

Увімкнення маскування (NAT66) для зони WAN.

uci set firewall.@zone[1].masq6="1"
uci commit firewall
service firewall restart

Оголошення маршруту за замовчуванням для ULA-префікса.

uci set dhcp.lan.ra_default="1"
uci commit dhcp
service odhcpd restart

Вимкнення фільтрації джерела IPv6 на інтерфейсі WAN.

uci set network.wan6.sourcefilter="0"
uci commit network
service network restart

Увімкнення маскування лише для певної підмережі джерела.

uci -q delete firewall.nat
uci set firewall.nat="nat"
uci set firewall.nat.family="ipv4"
uci set firewall.nat.proto="all"
uci set firewall.nat.src="wan"
uci set firewall.nat.src_ip="192.168.2.0/24"
uci set firewall.nat.target="MASQUERADE"
uci commit firewall
service firewall restart

Увімкнення маскування IPv6 лише для певної підмережі джерела.

uci -q delete firewall.nat6
uci set firewall.nat6="nat"
uci set firewall.nat6.family="ipv6"
uci set firewall.nat6.proto="all"
uci set firewall.nat6.src="wan"
uci set firewall.nat6.src_ip="fd00:2::/64"
uci set firewall.nat6.target="MASQUERADE"
uci commit firewall
service firewall restart

Увімкнення трансляції префіксів мережі IPv4IPv4 (NPT).

cat << "EOF" > /etc/nftables.d/npt.sh
LAN_PFX="192.168.1.0/24"
WAN_PFX="192.168.2.0/24"
. /lib/functions/network.sh
network_flush_cache
network_find_wan WAN_IF
network_get_device WAN_DEV "${WAN_IF}"
nft add rule inet fw4 srcnat \
oifname "${WAN_DEV}" snat ip prefix to ip \
saddr map { "${LAN_PFX}" : "${WAN_PFX}" }
EOF
uci -q delete firewall.npt
uci set firewall.npt="include"
uci set firewall.npt.path="/etc/nftables.d/npt.sh"
uci commit firewall
service firewall restart

Увімкнення трансляції префіксів IPv6IPv6.

cat << "EOF" > /etc/nftables.d/npt6.sh
LAN_PFX="$(uci -q get network.globals.ula_prefix)"
. /lib/functions/network.sh
network_flush_cache
network_find_wan6 WAN_IF
network_get_device WAN_DEV "${WAN_IF}"
network_get_prefix6 WAN_PFX "${WAN_IF}"
nft add rule inet fw4 srcnat \
oifname "${WAN_DEV}" snat ip6 prefix to ip6 \
saddr map { "${LAN_PFX}" : "${WAN_PFX}" }
EOF
uci -q delete firewall.npt6
uci set firewall.npt6="include"
uci set firewall.npt6.path="/etc/nftables.d/npt6.sh"
uci commit firewall
service firewall restart

Увімкнення трансляції префіксів IPv6IPv6 з підтримкою кількох WAN-інтерфейсів (наприклад, для mwan3).

cat << "EOF" > /etc/nftables.d/npt6.sh
LAN_IF="lan"
WAN_IF="wana6 wanb6"
. /lib/functions/network.sh
network_flush_cache
network_get_prefix_assignment6 LAN_PFX "${LAN_IF}"
for WAN_IF in ${WAN_IF}
do
network_get_device WAN_DEV "${WAN_IF}"
network_get_prefix6 WAN_PFX "${WAN_IF}"
nft add rule inet fw4 srcnat \
oif "${WAN_DEV}" snat ip6 prefix to ip6 \
saddr map { "${LAN_PFX}" : "${WAN_PFX}" }
done
EOF
uci -q delete firewall.npt6
uci set firewall.npt6="include"
uci set firewall.npt6.path="/etc/nftables.d/npt6.sh"
uci commit firewall
service firewall restart

Увімкнення симетричної динамічної трансляції IPv6IPv6 префіксів.

cat << "EOF" > /etc/nftables.d/npt6.sh
LAN_IF="lan"
sleep 5
. /lib/functions/network.sh
network_flush_cache
network_get_device LAN_DEV "${LAN_IF}"
network_get_prefix_assignment6 LAN_PFX "${LAN_IF}"
network_find_wan6 WAN_IF
network_get_device WAN_DEV "${WAN_IF}"
network_get_prefix6 WAN_PFX "${WAN_IF}"
nft add rule inet fw4 srcnat \
oifname "${WAN_DEV}" snat ip6 prefix to ip6 \
saddr map { "${LAN_PFX}" : "${WAN_PFX}" }
nft add rule inet fw4 srcnat \
oifname "${LAN_DEV}" snat ip6 prefix to ip6 \
saddr map { "${WAN_PFX}" : "${LAN_PFX}" }
EOF
uci -q delete firewall.npt6
uci set firewall.npt6="include"
uci set firewall.npt6.path="/etc/nftables.d/npt6.sh"
uci commit firewall
service firewall restart

Увімкнення NAT64 (IPv6IPv4) для мереж з лише IPv6 за допомогою Jool. Необхідно використовувати DNS64 для резолвінгу доменів.

opkg update
opkg install jool-tools-netfilter
. /usr/share/libubox/jshn.sh
json_init
json_add_string "instance" "default"
json_add_string "framework" "netfilter"
json_add_object "global"
json_add_string "pool6" "64:ff9b::/96"
json_close_object
json_dump > /etc/jool/jool-nat64.conf.json
uci set jool.general.enabled="1"
uci set jool.nat64.enabled="1"
uci commit jool
service jool restart

Увімкнення NAT64 (IPv6IPv4) для мереж з лише IPv6 за допомогою Tayga. Необхідно використовувати DNS64 для резолвінгу доменів.

opkg update
opkg install tayga
uci del_list firewall.lan.network="nat64"
uci add_list firewall.lan.network="nat64"
uci commit firewall
service firewall restart
uci -q delete network.nat64
uci set network.nat64="interface"
uci set network.nat64.proto="tayga"
uci set network.nat64.prefix="64:ff9b::/96"
uci set network.nat64.ipv6_addr="fd00:ffff::1"
uci set network.nat64.dynamic_pool="192.168.255.0/24"
uci set network.nat64.ipv4_addr="192.168.255.1"
uci commit network
service network restart

Зміна TTL (Time To Live) для вихідного трафіку.

cat << "EOF" > /etc/nftables.d/ttl.sh
WAN_TTL="65"
. /lib/functions/network.sh
network_flush_cache
network_find_wan WAN_IF
network_get_device WAN_DEV "${WAN_IF}"
nft add rule inet fw4 mangle_postrouting \
oifname "${WAN_DEV}" ip ttl set "${WAN_TTL}"
EOF
uci -q delete firewall.ttl
uci set firewall.ttl="include"
uci set firewall.ttl.path="/etc/nftables.d/ttl.sh"
uci commit firewall
service firewall restart

Зміна обмеження кількості стрибків (hop limit) для вихідного IPv6-трафіку.

cat << "EOF" > /etc/nftables.d/hlim.sh
WAN_HLIM="65"
. /lib/functions/network.sh
network_flush_cache
network_find_wan6 WAN_IF
network_get_device WAN_DEV "${WAN_IF}"
nft add rule inet fw4 mangle_postrouting \
oifname "${WAN_DEV}" ip6 hoplimit set "${WAN_HLIM}"
EOF
uci -q delete firewall.hlim
uci set firewall.hlim="include"
uci set firewall.hlim.path="/etc/nftables.d/hlim.sh"
uci commit firewall
service firewall restart

Увімкнення NAT-проходження для FTP за допомогою kmod-nf-nathelper.

opkg update
opkg install kmod-nf-nathelper
service firewall restart

Увімкнення NAT-проходження для SIP, PPTP, GRE тощо за допомогою kmod-nf-nathelper-extra.

opkg update
opkg install kmod-nf-nathelper-extra
service firewall restart

Увімкнення NAT-проходження для RTSP за допомогою kmod-ipt-nathelper-rtsp.

opkg update
opkg install kmod-ipt-nathelper-rtsp
service firewall restart
  • Last modified: 2025/06/06 13:36
  • by vazaz