ΠΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½ Π²ΡΠΏΡΡΠΊ ΠΏΠ°ΠΊΠ΅ΡΠ½ΠΎΠ³ΠΎ ΡΠΈΠ»ΡΡΡΠ° nftables 1.0.0, ΡΠ½ΠΈΡΠΈΡΠΈΡΡΡΡΠ΅Π³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² Π΄Π»Ρ IPv4, IPv6, ARP ΠΈ ΡΠ΅ΡΠ΅Π²ΡΡ ΠΌΠΎΡΡΠΎΠ² (Π½Π°ΡΠ΅Π»Π΅Π½ Π½Π° Π·Π°ΠΌΠ΅Π½Ρ iptables, ip6table, arptables ΠΈ ebtables). ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π²ΡΠΏΡΡΠΊΠ° nftables 1.0.0 ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π² ΡΠΎΡΡΠ°Π² ΡΠ΄ΡΠ° Linux 5.13. ΠΠ½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π½ΠΎΠΌΠ΅ΡΠ° Π²Π΅ΡΡΠΈΠΈ Π½Π΅ ΡΠ²ΡΠ·Π°Π½ΠΎ Ρ ΠΊΠ°ΠΊΠΈΠΌΠΈ-ΡΠΎ ΠΊΠ°ΡΠ΄ΠΈΠ½Π°Π»ΡΠ½ΡΠΌΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΠΌΠΈ, Π° Π»ΠΈΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΠ²ΠΈΠ΅ΠΌ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΡ Π½ΡΠΌΠ΅ΡΠ°ΡΠΈΠΈ Π² Π΄Π΅ΡΡΡΠΈΡΠ½ΠΎΠΌ ΠΈΡΡΠΈΡΠ»Π΅Π½ΠΈΠΈ (ΠΏΡΠΎΡΠ»ΡΠΉ Π²ΡΠΏΡΡΠΊ Π±ΡΠ» 0.9.9).
Π ΠΏΠ°ΠΊΠ΅Ρ nftables Π²Ρ ΠΎΠ΄ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΏΠ°ΠΊΠ΅ΡΠ½ΠΎΠ³ΠΎ ΡΠΈΠ»ΡΡΡΠ°, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠ΅ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΡΠ΄ΡΠ° ΡΠ°Π±ΠΎΡΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΠ° nf_tables, Π²Ρ ΠΎΠ΄ΡΡΠ°Ρ Π² ΡΠΎΡΡΠ°Π² ΡΠ΄ΡΠ° Linux Π½Π°ΡΠΈΠ½Π°Ρ Ρ Π²ΡΠΏΡΡΠΊΠ° 3.13. ΠΠ° ΡΡΠΎΠ²Π½Π΅ ΡΠ΄ΡΠ° ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΡΡΡ Π»ΠΈΡΡ ΠΎΠ±ΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, Π½Π΅ Π·Π°Π²ΠΈΡΡΡΠΈΠΉ ΠΎΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡΠΈΠΉ Π±Π°Π·ΠΎΠ²ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ ΠΈΠ· ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Ρ Π΄Π°Π½Π½ΡΠΌΠΈ ΠΈ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠΌ.
ΠΠ΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ ΠΈ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΠ΅ Π΄Π»Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠ² ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΡΡΡΡ Π² Π±Π°ΠΉΡΠΊΠΎΠ΄ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ Π΄Π°Π½Π½ΡΠΉ Π±Π°ΠΉΡΠΊΠΎΠ΄ Π·Π°Π³ΡΡΠΆΠ°Π΅ΡΡΡ Π² ΡΠ΄ΡΠΎ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Netlink ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² ΡΠ΄ΡΠ΅ Π² ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Π΅, Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°ΡΡΠ΅ΠΉ BPF (Berkeley Packet Filters). ΠΠΎΠ΄ΠΎΠ±Π½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΠΊΡΠ°ΡΠΈΡΡ ΡΠ°Π·ΠΌΠ΅Ρ ΠΊΠΎΠ΄Π° ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅Π³ΠΎ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΡΠ΄ΡΠ° ΠΈ Π²ΡΠ½Π΅ΡΡΠΈ Π²ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ°Π·Π±ΠΎΡΠ° ΠΏΡΠ°Π²ΠΈΠ» ΠΈ Π»ΠΎΠ³ΠΈΠΊΠΈ ΡΠ°Π±ΠΎΡΡ Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°ΠΌΠΈ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ.
ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ Π½ΠΎΠ²ΡΠ΅ΡΡΠ²Π°:
- Π set-ΡΠΏΠΈΡΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°-ΠΌΠ°ΡΠΊΠΈ «*», ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΠ΅Π³ΠΎ Π΄Π»Ρ Π»ΡΠ±ΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², Π½Π΅ ΠΏΠΎΠ΄ΠΏΠ°Π΄Π°ΡΡΠΈΡ ΠΏΠΎΠ΄ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠ΅ Π² Π½Π°Π±ΠΎΡΠ΅. table x { map blocklist { type ipv4_addr : verdict flags interval elements = { 192.168.0.0/16 : accept, 10.0.0.0/8 : accept, * : drop } } chain y { type filter hook prerouting priority 0; policy accept; ip saddr vmap @blocklist } }
- ΠΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΈΠ· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΠΎΠΏΡΠΈΠΈ «—define». # cat test.nft table netdev x { chain y { type filter hook ingress devices = $dev priority 0; policy drop; } } # nft —define dev=»{ eth0, eth1 }» -f test.nft
- Π map-ΡΠΏΠΈΡΠΊΠ°Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΡΠΎΡΠ½Π½ΡΡ (stateful) Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ: table inet filter { map portmap { type inet_service : verdict counter elements = { 22 counter packets 0 bytes 0 : jump ssh_input, * counter packets 0 bytes 0 : drop } } chain ssh_input { } chain wan_input { tcp dport vmap @portmap } chain prerouting { type filter hook prerouting priority raw; policy accept; iif vmap { «lo» : jump wan_input } } }
- ΠΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° «list hooks» Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π° ΡΠΏΠΈΡΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π° ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²: # nft list hooks ip device eth0 family ip { hook ingress { +0000000010 chain netdev x y [nf_tables] +0000000300 chain inet m w [nf_tables] } hook input { -0000000100 chain ip a b [nf_tables] +0000000300 chain inet m z [nf_tables] } hook forward { -0000000225 selinux_ipv4_forward 0000000000 chain ip a c [nf_tables] } hook output { -0000000225 selinux_ipv4_output } hook postrouting { +0000000225 selinux_ipv4_postroute } }
- Π Π±Π»ΠΎΠΊΠ°Ρ «queue» ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ jhash, symhash ΠΈ numgen Π΄Π»Ρ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΏΠΎ ΠΎΡΠ΅ΡΠ΅Π΄ΡΠΌ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ. … queue to symhash mod 65536 … queue flags bypass to numgen inc mod 65536 … queue to jhash oif . meta mark mod 32 «queue» ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡΠ΅ΡΠ°ΡΡ Ρ map-ΡΠΏΠΈΡΠΊΠ°ΠΌΠΈ Π΄Π»Ρ Π²ΡΠ±ΠΎΡΠ° ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ. … queue flags bypass to oifname map { «eth0» : 0, «ppp0» : 2, «eth1» : 2 }
- ΠΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ°ΡΠΊΡΡΡΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ , Π²ΠΊΠ»ΡΡΠ°ΡΡΠΈΡ set-ΡΠΏΠΈΡΠΎΠΊ, Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ map-ΠΎΠ². define interfaces = { eth0, eth1 } table ip x { chain y { type filter hook input priority 0; policy accept; iifname vmap { lo : accept, $interfaces : drop } } } # nft -f x.nft # nft list ruleset table ip x { chain y { type filter hook input priority 0; policy accept; iifname vmap { «lo» : accept, «eth0» : drop, «eth1» : drop } } }
- Π Π°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ vmap-ΠΎΠ² (verdict map) c ΠΈΠ½ΡΠ΅ΡΠ²Π°Π»Π°ΠΌΠΈ: # nft add rule x y tcp dport . ip saddr vmap { 1025-65535 . 192.168.10.2 : accept }
- Π£ΠΏΡΠΎΡΡΠ½ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΠΉ Π΄Π»Ρ NAT. Π Π°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ΠΎΠ² Π°Π΄ΡΠ΅ΡΠΎΠ²: … snat to ip saddr map { 10.141.11.4 : 192.168.2.2-192.168.2.4 } ΠΈΠ»ΠΈ ΡΠ²Π½ΡΡ IP-Π°Π΄ΡΠ΅ΡΠΎΠ² ΠΈ ΠΏΠΎΡΡΠΎΠ²: … dnat to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 } ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠΈ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ΠΎΠ² IP ΠΈ ΠΏΠΎΡΡΠΎΠ²: … dnat to ip saddr . tcp dport map { 192.168.1.2 . 80 : 10.141.10.2-10.141.10.5 . 8888-8999 }
ΠΡΡΠΎΡΠ½ΠΈΠΊ: opennet.ru