NAT - приклади
Програма fw4 OpenWrt має розширену підтримку NAT-фільтрації. NAT — це потужна функція для перенаправлення мережевого трафіку, що заслуговує на визнання як фактор, який продовжив життя протоколу IPv4.
У цьому розділі наведено типові приклади використання можливостей NAT у fw4. Як і в інших розділах про файрвол, тут не розглядаються теоретичні аспекти NAT. Ось кілька корисних посилань для глибшого ознайомлення:
Для діагностики NAT дивіться Управління Netfilter, щоб проаналізувати правила та дослідити сесії conntrack.
Приклади конфігурації NAT
Програма fw4 в OpenWrt підтримує DNAT, SNAT та MASQUERADING. Наведені нижче приклади можна використати у файлі конфігурації fw4 /etc/config/firewall.
Destination NAT (DNAT)
Для публічних серверів за файрволом використовується 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
У цьому прикладі 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 маршрутизувати його без додаткових правил у файрволі.
Source NAT (SNAT)
Мета цього правила — транслювати 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
Для тестування:
- На станції STA1 (WAN) запустіть: `nc -l 8080`
- На станції 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.*
MASQUERADE
Це найпоширеніша і найкорисніша форма 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
Увімкнення маскування (NAT) для зони WAN.
uci set firewall.@zone[1].masq="1" uci commit firewall service firewall restart
NAT для IPv6
Увімкнення маскування (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
Вибіркове NAT
Увімкнення маскування лише для певної підмережі джерела.
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
Вибіркове NAT для IPv6
Увімкнення маскування 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
NPT
Увімкнення трансляції префіксів мережі IPv4 → IPv4 (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
NPT для IPv6
Увімкнення трансляції префіксів IPv6 → IPv6.
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
Багатоінтерфейсний NPTv6 (Multi-WAN)
Увімкнення трансляції префіксів IPv6 → IPv6 з підтримкою кількох 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
Симетричний динамічний NPTv6
Увімкнення симетричної динамічної трансляції IPv6 → IPv6 префіксів.
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 з використанням Jool
Увімкнення NAT64 (IPv6 → IPv4) для мереж з лише 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 з використанням Tayga
Увімкнення NAT64 (IPv6 → IPv4) для мереж з лише 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
Зміна 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
IPv6 обмеження стрибків (hop limit)
Зміна обмеження кількості стрибків (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
Прозоре проходження FTP (FTP passthrough)
Увімкнення NAT-проходження для FTP за допомогою kmod-nf-nathelper.
opkg update
opkg install kmod-nf-nathelper
service firewall restart
Прозоре проходження SIP (SIP passthrough)
Увімкнення NAT-проходження для SIP, PPTP, GRE тощо за допомогою kmod-nf-nathelper-extra.
opkg update
opkg install kmod-nf-nathelper-extra
service firewall restart
Прозоре проходження RTSP (RTSP passthrough)
Увімкнення NAT-проходження для RTSP за допомогою kmod-ipt-nathelper-rtsp.
opkg update
opkg install kmod-ipt-nathelper-rtsp
service firewall restart