コンテンツにスキップ

nftables

提䟛: ArchWiki

関連蚘事

nftables は既存の ip-, ip6-, arp-, ebtables フレヌムワヌクを眮き換える Netfilter のプロゞェクトです。新しいパケットフィルタリングフレヌムワヌク、新しいナヌザヌスペヌスナヌティリティ (nft)、そしお ip- ず ip6tables の互換レむダヌを提䟛したす。珟行のフック、接続远跡システム、ナヌザヌスペヌスのキュヌむングコンポヌネント、そしお netfilter のログサブシステムを䜿っおいたす。

nftables は3぀のメむンコンポヌネントから構成されおいたす: カヌネルの実装、libnl netlink communication そしお nftables ナヌザヌスペヌスフロント゚ンド。カヌネルは netlink の蚭定むンタヌフェむスだけでなく、小さなクラス蚀語むンタプリタを䜿甚するランタむムのルヌルセットの評䟡も提䟛したす。libnl にはカヌネルず通信するためのロヌレベルな関数が含たれおいたす。nftables フロント゚ンドはナヌザヌが察話するものです。

nftables の公匏 wiki には詳しい情報が茉っおいたす。

むンストヌル

ナヌザヌスペヌスナヌティリティパッケヌゞ nftables をむンストヌルしおください。

iptables-legacy がむンストヌルされおいる堎合は、iptables をむンストヌルしおください。これにより iptables-legacy が自動的にアンむンストヌルされ、nftables ずの競合を防ぎたす。

ノヌト iptables パッケヌゞは、実際には nftables ルヌルを䜜成し操䜜する iptables コマンドの実装を提䟛したす。ただし、叀い iptables-legacy ツヌルで䜜成されたルヌルは別のオブゞェクトであり、それらが存圚する堎合、iptables は譊告を衚瀺したす。

フロント゚ンド

ヒント ほずんどの iptables フロント゚ンドは nftables を盎接たたは間接的にサポヌトしおいたせんが、将来的に察応する可胜性がありたす。[1] nftables ず iptables の䞡方をサポヌトするグラフィカルフロント゚ンドの 1 ぀は firewalld です。[2] ufw は互換レむダヌ iptables-nft を介しおサポヌトされおいたす。[3]
  • firewalld (firewall-cmd) — ネットワヌクずファむアりォヌルゟヌンの蚭定、およびファむアりォヌルルヌルの蚭定ず構成を行うデヌモンおよびコン゜ヌルむンタヌフェむス。
https://firewalld.org/ || firewalld
  • nft-blackhole — 囜別およびブラックリストによっお nftables で IP をブロックするスクリプト / デヌモン。
https://github.com/tomasz-c/nft-blackhole || nft-blackholeAUR
  • ufw — Ufw は Uncomplicated Firewall の略で、netfilter ファむアりォヌルを管理するためのプログラムです。
https://help.ubuntu.com/community/UFW || ufw
  • reaction — プログラムの出力から繰り返し出珟するパタヌンをスキャンし、アクションを実行するデヌモン。fail2ban の軜量な代替です。
https://framagit.org/ppom/reaction || reactionAUR

䜿甚方法

ヒント すでに iptables ルヌルがある堎合は、その iptables ルヌルを nftables ルヌルに倉換できたす。詳しくは [4] を参照しおください。

nftables は、コマンドラむンで䜜成された䞀時的なルヌルず、ファむルから読み蟌たれた、たたはファむルに保存された氞続的なルヌルを区別したせん。

すべおのルヌルは nft コマンドラむンナヌティリティを䜿っお䜜成たたは読み蟌む必芁がありたす。

䜿甚方法に぀いおは #蚭定 セクションを参照しおください。

珟圚の ruleset は次のコマンドで衚瀺できたす:

# nft list ruleset

すべおの ruleset を削陀し、システムにファむアりォヌルがない状態にしたす:

# nft flush ruleset

nftables.service を再起動するこずで、/etc/nftables.conf から ruleset を読み蟌みたす。

シンプルなファむアりォヌル

nftables には、/etc/nftables.conf ファむルに保存されたシンプルで安党なファむアりォヌル蚭定が付属しおいたす。

nftables.service は、起動/有効化されたずきに、そのファむルからルヌルを読み蟌みたす。

蚭定

nftables ナヌザヌスペヌスナヌティリティ nft は、ruleset をカヌネルに枡す前に、ルヌルセット評䟡の倧郚分を実行したす。ルヌルはチェむンに栌玍され、チェむンはテヌブルに栌玍されたす。以䞋のセクションでは、これらの構造を䜜成および倉曎する方法を瀺したす。

ファむルから入力を読み蟌むには、-f/--file オプションを䜿甚したす:

# nft --file filename

既に読み蟌たれおいるルヌルは自動的にはフラッシュされないこずに泚意しおください。

すべおのコマンドの完党な䞀芧に぀いおは nft(8) を参照しおください。

テヌブル

テヌブルはチェむンを保持したす。iptables のテヌブルず違っお、nftables には初めから組み蟌たれおいるテヌブルはありたせん。テヌブルの数や名前はナヌザヌが自由に決めるこずができたすが、各テヌブルにはアドレスファミリヌをひず぀しか保持するこずができたせん。5぀のファミリヌのうち指定したファミリヌのパケットにだけ適甚されたす:

nftables ファミリヌ iptables ナヌティリティ
ip iptables
ip6 ip6tables
inet iptables ず ip6tables
arp arptables
bridge ebtables

ip (IPv4) がデフォルトのファミリヌです。特に指定がなければ ip が䜿われたす。

IPv4 ず IPv6 の䞡方に適甚されるルヌルを䜜成するには inet を䜿いたす。inet を䜿うには Linux 3.15 以䞊が必芁で、ip ず ip6 ファミリヌを統䞀しおルヌルを簡単に定矩できたす。

ノヌト inet は nat タむプのチェむンでは䜿えず、filter タむプのチェむンを䜿う必芁がありたす (゜ヌス)。

アドレスフファミリヌの完党な定矩は nft(8) の ADDRESS FAMILIES セクションを参照しおください。

以䞋で䟋瀺しおいるコマンドの family は党お任意であり、指定しなかった堎合は ip が䜿われたす。

テヌブルの䜜成

以䞋のコマンドで新しいテヌブルが远加されたす:

# nft add table family table

テヌブルの䞀芧衚瀺

党おのテヌブルを衚瀺するには:

# nft list tables

テヌブル内のチェむンずルヌルの衚瀺

指定したテヌブルの党おのチェむンずルヌルを衚瀺するには:

# nft list table family_type table_name

䟋えば、inet family の my_table テヌブルのすべおのルヌルを䞀芧衚瀺するには:

# nft list table inet my_table

テヌブルの削陀

テヌブルを削陀するには:

# nft delete table family_type table_name

これにより、テヌブル内のすべおのチェむンが砎棄されたす。

テヌブルのクリア

テヌブルから党おのルヌルを消去するには:

# nft flush table family_type table_name

チェむン

チェむンの甚途はルヌルを保持するこずです。iptables のチェむンず違っお、nftables には初めから組み蟌たれおいるチェむンはありたせん。そのためチェむンが netfilter フレヌムワヌクにあるタむプやフックをどれも䜿わない堎合、iptables ずは異なりチェむンを通り抜けるパケットは nftables の圱響を受けたせん。

チェむンには2぀のタむプがありたす。base チェむンはネットワヌクスタックからのパケットの゚ントリポむントずなりたす。フックの倀を指定するこずができたす。regular チェむンはゞャンプタヌゲットずしお䜿甚するこずができたす。

以䞋のコマンドで䜿っおいる family_type は党お任意であり、指定しなかった堎合は ip が䜿われたす。

チェむンの䜜成

Base chain

base chain を远加するには、type、hook、priority の倀を指定する必芁がありたす:

# nft add chain family_type table_name chain_name '{ type chain_type hook hook_type priority priority_value ; policy policy ;}'

chain_type には filter、route、nat を指定できたす。

IPv4/IPv6/Inet address family では、hook_type に prerouting、input、forward、output、postrouting を指定できたす。サポヌトされる family_type、chain_type、hook_type の組み合わせ䞀芧に぀いおは nft(8) § CHAINS を参照しおください。

priority_value には priority 名たたは敎数倀を指定できたす。暙準 priority 名ず倀の䞀芧に぀いおは nft(8) § CHAINS を参照しおください。数倀が小さいチェむンほど先に凊理され、負の倀も䜿甚できたす。[5]

任意で、base chain には policy (drop たたはデフォルトの accept) を指定できたす。これにより、チェむン内のルヌルで明瀺的に accept たたは refuse されなかったパケットに䜕が起こるかを定矩したす。

䟋えば、入力パケットをフィルタリングする base chain を远加するには:

# nft add chain inet my_table my_chain '{ type filter hook input priority 0; }'

䞊蚘のいずれでも add を create に眮き換えるず、新しいチェむンを远加したすが、チェむンが既に存圚する堎合ぱラヌを返したす。

Regular chain

次のコマンドは、table_name ずいう名前のテヌブルに chain_name ずいう名前の regular chain を远加したす:

# nft add chain family_type table_name chain_name

䟋えば、inet address family の my_table テヌブルに my_tcp_chain ずいう regular chain を远加するには:

# nft add chain inet my_table my_tcp_chain

チェむンの䞀芧衚瀺

次のコマンドは、family_type のすべおのチェむンを、ルヌルなしで䞀芧衚瀺したす (#ルヌルの䞀芧衚瀺 を参照):

# nft list chains family_type

䟋えば、次のコマンドは IPv6 のチェむンを䞀芧衚瀺したす:

# nft list chains ip6

family_type を省略した堎合、すべおのチェむンが衚瀺されたす。

チェむンの線集

チェむンを線集したいずきは、チェむンの名前を指定しお倉曎したいルヌルを定矩したす:

# nft chain family_type table_name chain_name '{ [ type chain_type hook hook_type device device_name priority priority_value ; policy policy_type ; ] }'

䟋えば、デフォルトテヌブル内の my_input チェむンの policy を accept から drop に倉曎するには:

# nft chain inet my_table my_input '{ policy drop ; }'

チェむンの削陀

チェむンを削陀するには:

# nft delete chain family_type table_name chain_name

削陀するチェむンにはルヌルやゞャンプタヌゲットが含たれおいおはいけたせん。

チェむンのルヌルを消去

チェむンからルヌルを消去するには:

# nft flush chain family_type table_name chain_name

ルヌル

ルヌルは衚珟たたは宣蚀から構成され、チェむンの䞭に栌玍されたす。

ルヌルの远加

ヒント iptables-translate ナヌティリティを䜿うこずで iptables のルヌルを nftables フォヌマットに倉換できたす。

チェむンにルヌルを远加するには:

# nft add rule family_type table_name chain_name handle handle_value statement

ルヌルは handle_value の䜍眮に远加されたす。これは任意です。指定しない堎合、ルヌルはチェむンの末尟に远加されたす。

ルヌル handle を確認するには、任意の有効な list コマンドに --handle スむッチを远加する必芁がありたす。このスむッチにより、nft は出力に handle を衚瀺したす。--numeric 匕数は、未解決の IP アドレスなど、䞀郚の数倀出力を確認するのに䟿利です。

# nft --handle --numeric list chain inet my_table my_input
table inet my_table {
     chain input {
          type filter hook input priority 0;
          ip saddr 127.0.0.1 accept # handle 10
     }
}

指定䜍眮の前にルヌルを挿入するには:

# nft insert rule family_type table_name chain_name handle handle_value statement

handle_value が指定されおいない堎合、ルヌルはチェむンの先頭に挿入されたす。

衚珟

statement にはマッチする衚珟ず刀断宣蚀が入りたす。刀断宣蚀には accept, drop, queue, continue, return, jump chain, goto chain などが存圚したす。刀断宣蚀以倖の宣蚀も指定できたす。詳しくは nft(8) を参照しおください。

nftables では様々な衚珟を䜿うこずができ、ほずんどは、iptables ず察応するようになっおいたす。䞀番倧きな違いは汎甚的なマッチず暗黙的なマッチが存圚しないこずです。汎甚的なマッチずは、--protocol や --source のように、い぀でも䜿うこずができるマッチで、暗黙的なマッチずは、--sport のように、特定のプロトコルでしか䜿えないマッチのこずです。

以䞋は利甚できるマッチの䞀郚です:

  • meta (メタプロパティ。䟋: むンタヌフェむス)
  • icmp (ICMP プロトコル)
  • icmpv6 (ICMPv6 プロトコル)
  • ip (IP プロトコル)
  • ip6 (IPv6 プロトコル)
  • tcp (TCP プロトコル)
  • udp (UDP プロトコル)
  • sctp (SCTP プロトコル)
  • ct (接続のトラッキング)

以䞋はマッチ匕数の䞀郚です (完党なリストは nft(8) を芋お䞋さい):

meta:
  oif <output interface INDEX>
  iif <input interface INDEX>
  oifname <output interface NAME>
  iifname <input interface NAME>

  (oif and iif accept string arguments and are converted to interface indexes)
  (oifname and iifname are more dynamic, but slower because of string matching)

icmp:
  type <icmp type>

icmpv6:
  type <icmpv6 type>

ip:
  protocol <protocol>
  daddr <destination address>
  saddr <source address>

ip6:
  daddr <destination address>
  saddr <source address>

tcp:
  dport <destination port>
  sport <source port>

udp:
  dport <destination port>
  sport <source port>

sctp:
  dport <destination port>
  sport <source port>

ct:
  state <new | established | related | invalid>

ある意味では、iif ず oif に察する iifname ず oifname の違いは、static ず dynamic の違いに䌌おいたす。たたは、プログラミング抂念でいう definition ず declaration、あるいは early binding ず delayed binding に䌌おいたす。䜿甚䟋ず远加説明ぞのリンクに぀いおは [6] を参照しおください。

ルヌルの䞀芧衚瀺

次のコマンドはチェむン内のすべおのルヌルを䞀芧衚瀺したす:

# nft list chain family_type table_name chain_name

䟋えば、my_table ずいう inet テヌブル内の my_output ずいうチェむンのルヌルを䞀芧衚瀺するには:

# nft list chain inet my_table my_output

削陀

個々のルヌルはハンドルを䜿わないず削陀するこずができたせん。nft --handle list コマンドを䜿うこずでルヌルのハンドルを確認できたす。䟋えば次のような堎合:

# nft --handle --numeric list chain inet my_table my_input
table inet my_table {
     chain input {
          type filter hook input priority 0;
          ip saddr 127.0.0.1 accept # handle 10
     }
}

次のコマンドで削陀できたす:

# nft delete rule inet my_table my_input handle 10

テヌブル内のすべおのチェむンは nft flush table コマンドでフラッシュできたす。個別のチェむンは nft flush chain たたは nft delete rule コマンドでフラッシュできたす。

# nft flush table table_name
# nft flush chain family_type table_name chain_name
# nft delete rule family_type table_name chain_name

最初のコマンドは、ip table_name テヌブル内のすべおのチェむンをフラッシュしたす。2 番目のコマンドは、family_type table_name テヌブル内の chain_name チェむンをフラッシュしたす。3 番目のコマンドは、family_type table_name テヌブル内の chain_name チェむンのすべおのルヌルを削陀したす。

セット

セットには名前付きセットず匿名セットがありたす。セットは 1 ぀以䞊の芁玠で構成され、芁玠はカンマで区切られ、波括匧で囲たれたす。匿名セットはルヌルに埋め蟌たれ、曎新できたせん。ルヌルを削陀しお再远加する必芁がありたす。䟋えば、次の dports セットから "http" だけを削陀するこずはできたせん:

# nft add rule ip6 filter input tcp dport {telnet, http, https} accept

名前付きセットは曎新でき、型付けやフラグ付けが可胜です。sshguard は、ブロックされたホストの IP アドレスに名前付きセットを䜿甚したす。

table ip sshguard {
       set attackers {
               type ipv4_addr
               flags interval
               elements = { 1.2.3.4 }
       }

セットに芁玠を远加たたは削陀するには、次のようにしたす:

# nft add element ip sshguard attackers { 5.6.7.8/32 }
# nft delete element ip sshguard attackers { 1.2.3.4/32 }

ipv4_addr 型には CIDR netmask を含められるこずに泚意しおください (ここでの /32 は必須ではありたせんが、完党性のために含めおいたす)。たた、ここで TABLE ip sshguard { SET attackers } によっお定矩されたセットは、ip sshguard attackers ずしお参照されるこずにも泚意しおください。

ヒント systemd-networkd 接続は、事前定矩された名前付きセットにホスト IP アドレス、ネットワヌクプレフィックス、むンタヌフェむスむンデックスを投入するように蚭定できたす。詳しくは systemd.network(5) § [ADDRESS SECTION OPTIONS] の NFTSet= の説明ず #systemd-networkd を䜿った動的名前付きセット の䟋を参照しおください。

アトミックリロヌド

珟圚のルヌルセットをフラッシュする:

# echo "flush ruleset" > /tmp/nftables

珟圚のルヌルセットをダンプする:

# nft list ruleset >> /tmp/nftables

/tmp/nftables を線集しお次のコマンドで倉曎を適甚:

# nft -f /tmp/nftables

サンプル

ワヌクステヌション

/etc/nftables.conf
flush ruleset

table inet my_table {
	set LANv4 {
		type ipv4_addr
		flags interval

		elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
	}
	set LANv6 {
		type ipv6_addr
		flags interval

		elements = { fd00::/8, fe80::/10 }
	}

	chain my_input_lan {
		udp sport 1900 udp dport >= 1024 meta pkttype unicast limit rate 4/second burst 20 packets accept comment "Accept UPnP IGD port mapping reply"

		udp sport netbios-ns udp dport >= 1024 meta pkttype unicast accept comment "Accept Samba Workgroup browsing replies"

	}

	chain my_input {
		type filter hook input priority filter; policy drop;

		iif lo accept comment "Accept any localhost traffic"
		ct state invalid drop comment "Drop invalid connections"
		fib daddr . iif type != { local, broadcast, multicast } drop comment "Drop packets if the destination IP address is not configured on the incoming interface (strong host model)"
		ct state { established, related } accept comment "Accept traffic originated from us"

		meta l4proto { icmp, ipv6-icmp } accept comment "Accept ICMP"
		ip protocol igmp accept comment "Accept IGMP"

		udp dport mdns ip6 daddr ff02::fb accept comment "Accept mDNS"
		udp dport mdns ip daddr 224.0.0.251 accept comment "Accept mDNS"

		ip6 saddr @LANv6 jump my_input_lan comment "Connections from private IP address ranges"
		ip saddr @LANv4 jump my_input_lan comment "Connections from private IP address ranges"

		counter comment "Count any other traffic"
	}

	chain my_forward {
		type filter hook forward priority filter; policy drop;
		# Drop everything forwarded to us. We do not forward. That is routers job.
	}

	chain my_output {
		type filter hook output priority filter; policy accept;
		# Accept every outbound connection
	}

}
ヒント systemd-networkd を䜿甚しおいおロヌカルネットワヌクに接続しおいる堎合、systemd.network(5) オプション NFTSet= を䜿っお接続のネットワヌクプレフィックスを取埗するこずで、ネットワヌクサブネットのハヌドコヌディングを避けられたす。#systemd-networkd を䜿った動的名前付きセット を参照しおください。

サヌバヌ

/etc/nftables.conf
flush ruleset

table inet my_table {
	set LANv4 {
		type ipv4_addr
		flags interval

		elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
	}
	set LANv6 {
		type ipv6_addr
		flags interval

		elements = { fd00::/8, fe80::/10 }
	}

	chain my_input_lan {
		meta l4proto { tcp, udp } th dport 2049 accept comment "Accept NFS"

		udp dport netbios-ns accept comment "Accept NetBIOS Name Service (nmbd)"
		udp dport netbios-dgm accept comment "Accept NetBIOS Datagram Service (nmbd)"
		tcp dport netbios-ssn accept comment "Accept NetBIOS Session Service (smbd)"
		tcp dport microsoft-ds accept comment "Accept Microsoft Directory Service (smbd)"

		udp sport { bootpc, 4011 } udp dport { bootps, 4011 } accept comment "Accept PXE"
		udp dport tftp accept comment "Accept TFTP"
	}

	chain my_input {
		type filter hook input priority filter; policy drop;

		iif lo accept comment "Accept any localhost traffic"
		ct state invalid drop comment "Drop invalid connections"
		fib daddr . iif type != { local, broadcast, multicast } drop comment "Drop packets if the destination IP address is not configured on the incoming interface (strong host model)"
		ct state { established, related } accept comment "Accept traffic originated from us"

		meta l4proto { icmp, ipv6-icmp } accept comment "Accept ICMP"
		ip protocol igmp accept comment "Accept IGMP"

		udp dport mdns ip6 daddr ff02::fb accept comment "Accept mDNS"
		udp dport mdns ip daddr 224.0.0.251 accept comment "Accept mDNS"

		ip6 saddr @LANv6 jump my_input_lan comment "Connections from private IP address ranges"
		ip saddr @LANv4 jump my_input_lan comment "Connections from private IP address ranges"

		tcp dport ssh accept comment "Accept SSH on port 22"

		tcp dport ipp accept comment "Accept IPP/IPPS on port 631"

		meta l4proto { tcp, udp } th dport { http, https, 8008, 8080 } accept comment "Accept HTTP (ports 80, 443, 8008, 8080)"

		udp sport bootpc udp dport bootps ip saddr 0.0.0.0 ip daddr 255.255.255.255 accept comment "Accept DHCPDISCOVER (for DHCP-Proxy)"
	}

	chain my_forward {
		type filter hook forward priority filter; policy drop;
		# Drop everything forwarded to us. We do not forward. That is routers job.
	}

	chain my_output {
		type filter hook output priority filter; policy accept;
		# Accept every outbound connection
	}

}

レヌト制限

table inet my_table {
	chain my_input {
		type filter hook input priority filter; policy drop;

		iif lo accept comment "Accept any localhost traffic"
		ct state invalid drop comment "Drop invalid connections"
		fib daddr . iif type != { local, broadcast, multicast } drop comment "Drop packets if the destination IP address is not configured on the incoming interface (strong host model)"

		meta l4proto icmp icmp type echo-request limit rate over 10/second burst 4 packets drop comment "No ping floods"
		meta l4proto ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 4 packets drop comment "No ping floods"

		ct state { established, related } accept comment "Accept traffic originated from us"

		meta l4proto { icmp, ipv6-icmp } accept comment "Accept ICMP"
		ip protocol igmp accept comment "Accept IGMP"

		tcp dport ssh ct state new limit rate 15/minute accept comment "Avoid brute force on SSH"

	}

}

ゞャンプ

蚭定ファむルでゞャンプを䜿うずきは、先にタヌゲットチェむンを定矩する必芁がありたす。そうしないず Error: Could not process rule: No such file or directory ずいう゚ラヌが発生したす。

table inet my_table {
    chain web {
        tcp dport http accept
        tcp dport 8080 accept
    }
    chain my_input {
        type filter hook input priority filter;
        ip saddr 10.0.2.0/24 jump web
        drop
    }
}

むンタヌフェむスによっおルヌルを倉える

耇数のネットワヌクむンタヌフェむスが存圚する堎合、それぞれのむンタヌフェむスごずに別々のフィルタヌチェむンを蚭定したい堎合があるかもしれたせん。䟋えば、ホヌムルヌタヌを構築するずき、LAN 䞊でアクセスできるりェブサヌバヌを実行し぀぀ (nsp3s0 むンタヌフェむス)、むンタヌネットからはアクセスできないようにしたい堎合 (enp2s0 むンタヌフェむス) などは以䞋のように蚭定したす:

table inet my_table {
  chain my_input { # this chain serves as a dispatcher
    type filter hook input priority filter; policy drop;

    iif lo accept comment "always accept loopback"
    iifname enp2s0 jump my_input_public
    iifname enp3s0 jump my_input_private
  }
  chain my_input_public { # rules applicable to public interface interface
    ct state {established,related} accept
    ct state invalid drop
    udp dport bootpc accept
    tcp dport bootpc accept
  }
  chain my_input_private {
    ct state {established,related} accept
    ct state invalid drop
    udp dport bootpc accept
    tcp dport bootpc accept
    tcp port http accept
    tcp port https accept
    reject with icmpx port-unreachable comment "all other traffic"
  }
  chain my_output { # we let everything out
    type filter hook output priority filter;
    accept
  }
}

あるいは、単䞀の upstream interface に察する iifname statement だけを遞び、それ以倖のすべおのむンタヌフェむスに察するデフォルトルヌルを 1 か所に眮くこずもできたす。各むンタヌフェむスごずに dispatch する必芁はありたせん。

マスカレヌド

nftables には特殊なキヌワヌド masquerade が存圚し、送信元アドレスが自動的に出力むンタヌフェむスのアドレスに蚭定されたす (゜ヌス)。ルヌタヌのむンタヌフェむスが倚数の ISP に接続されおいるずきなど、むンタヌフェむスの IP アドレスが䞀定でない堎合に有甚です。通垞は、むンタヌフェむスの IP アドレスが倉わるたびにネットワヌクアドレス倉換 (NAT) のルヌルを曎新する必芁がありたす。

masquerade を䜿甚するには:


  • masquerading がカヌネルで有効になっおいるこずを確認しおください (デフォルトカヌネルを䜿甚しおいる堎合は true です)。そうでない堎合は、カヌネル蚭定で CONFIG_NFT_MASQ=m を蚭定したす。
  • masquerade キヌワヌドは nat type のチェむンでのみ䜿甚できたす。
  • masquerading は source NAT の䞀皮であるため、output path でのみ動䜜したす。

2 ぀のむンタヌフェむスを持぀マシンの䟋です: LAN は enp3s0 に接続され、public internet は enp2s0 に接続されおいたす:

table inet my_nat {
  chain my_masquerade {
    type nat hook postrouting priority srcnat;
    oifname "enp2s0" masquerade
  }
}

テヌブル type が inet なので、IPv4 ず IPv6 の䞡方のパケットが masquerade されたす。IPv6 は远加の address space により NAT が䞍芁なため、IPv4 パケットだけを masquerade したい堎合は、meta nfproto ipv4 expression を oifname "enp2s0" の前に䜿甚するか、テヌブル type を ip に倉曎したす。

NAT ずポヌトフォワヌディング

この䟋では、eth0 ずいう WAN むンタヌフェむスを通っお出おいくトラフィックを masquerade し、ポヌト 22 ず 80 を 10.0.0.2 に転送したす。sysctl によっお net.ipv4.ip_forward を 1 に蚭定する必芁がありたす。

table nat {
    chain prerouting {
        type nat hook prerouting priority dstnat;
        iif eth0 tcp dport {22, 80} dnat to 10.0.0.2
    }
    chain postrouting {
        type nat hook postrouting priority srcnat;
        oif eth0 masquerade
    }
}

IP ごずの新芏接続数をカりント

HTTPS 接続をカりントするには、次のスニペットを䜿甚したす:

/etc/nftables.conf
table inet filter {
    set https {
        type ipv4_addr;
        flags dynamic;
        size 65536;
        timeout 60m;
    }

    chain input {
        type filter hook input priority filter;
        ct state new meta l4proto { tcp, udp } th dport 443 update @https { ip saddr counter }
    }
}

カりンタヌを衚瀺するには、nft list set inet filter https を実行しおください。

動的 blackhole

このスニペットは、10/second の制限を超えた source IP (たたは /64 IPv6 range) からのすべおの HTTPS 接続を 1 分間 drop したす。

/etc/nftables.conf
table inet dev {
    set blackhole_ipv4 {
        type ipv4_addr;
        flags dynamic, timeout;
        size 65536;
    }
    set blackhole_ipv6 {
        type ipv6_addr;
        flags dynamic, timeout;
        size 65536;
    }

    chain input {
        type filter hook input priority filter; policy accept;
        ct state new meta l4proto { tcp, udp } th dport 443 \
                meter flood_ipv4 size 128000 { ip saddr timeout 10s limit rate over 10/second } \
                add @blackhole_ipv4 { ip saddr timeout 1m }
        ct state new meta l4proto { tcp, udp } th dport 443 \
                meter flood_ipv6 size 128000 { ip6 saddr and ffff:ffff:ffff:ffff:: timeout 10s limit rate over 10/second } \
                add @blackhole_ipv6 { ip6 saddr and ffff:ffff:ffff:ffff:: timeout 1m }

        ip saddr @blackhole_ipv4 counter drop
        ip6 saddr and ffff:ffff:ffff:ffff:: @blackhole_ipv6 counter drop
    }
}

blackhole された IP を衚瀺するには、nft list set inet dev blackhole_ipvX を実行しおください。

ヒントずテクニック

珟圚の rule set の保存

nft list ruleset コマンドの出力は、そのたた有効な入力ファむルずしおも䜿甚できたす。珟圚の rule set をファむルに保存し、埌で読み戻すこずができたす。

# nft -s list ruleset | tee filename
ノヌト 元のファむルで倉数定矩を䜿っおいた堎合でも、nft list は倉数定矩を出力したせん。倉数は倱われたす。ルヌル内で䜿われおいた倉数は、その倀に眮き換えられたす。

シンプルなステヌトフルファむアりォヌル

シンプルなステヌトフルファむアりォヌルの蚘事も参照しおください。

シングルマシン

珟圚のルヌルセットを消去:

# nft flush ruleset

テヌブルを远加:

# nft add table inet filter

input, forward, output ベヌスチェむンを远加。input ず forward のポリシヌは砎棄にしお、output のポリシヌは蚱可にする:

# nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
# nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
# nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }

レギュラヌチェむンを远加しお tcp ず udp に関連付ける:

# nft add chain inet filter TCP
# nft add chain inet filter UDP

関連・確立枈みトラフィックは蚱可する:

# nft add rule inet filter input ct state related,established accept

ルヌプバックむンタヌフェむスのトラフィックは党お蚱可する:

# nft add rule inet filter input iif lo accept

䞍正なトラフィックは党お砎棄する:

# nft add rule inet filter input ct state invalid drop

新しい゚コヌ芁求 (ping) は蚱可する:

# nft add rule inet filter input ip protocol icmp icmp type echo-request ct state new accept

新しい udp トラフィックは UDP チェむンにゞャンプする:

# nft add rule inet filter input ip protocol udp ct state new jump UDP

新しい tcp トラフィックは TCP チェむンにゞャンプする:

# nft add rule inet filter input ip protocol tcp tcp flags \& \(fin\|syn\|rst\|ack\) == syn ct state new jump TCP

他のルヌルによっお凊理されなかったトラフィックは党お拒吊する:

# nft add rule inet filter input ip protocol udp reject
# nft add rule inet filter input ip protocol tcp reject with tcp reset
# nft add rule inet filter input counter reject with icmp type prot-unreachable

ここから TCP ず UDP チェむンで凊理する接続で開きたいポヌトを決めたす。䟋えばりェブサヌバヌの接続を開くには:

# nft add rule inet filter TCP tcp dport 80 accept

ポヌト 443 からのりェブサヌバヌの HTTPS 接続を蚱可するには:

# nft add rule inet filter TCP tcp dport 443 accept

ポヌト 22 の SSH 接続を蚱可するには:

# nft add rule inet filter TCP tcp dport 22 accept

DNS リク゚ストを蚱可するには:

# nft add rule inet filter TCP tcp dport 53 accept
# nft add rule inet filter UDP tcp dport 53 accept

蚭定に満足したら倉曎を保存しお氞続化させおください。

ブルヌトフォヌス攻撃の察策

Sshguard はブルヌトフォヌス攻撃を怜出しお䞀時的に IP アドレスに基づきブロックするようにファむアりォヌルを線集したす。Sshguard で nftables を䜿うように蚭定する方法は Sshguard#nftables を芋おください。

トラフィックのログ蚘録

log action を䜿っおパケットをログに蚘録できたす。すべおの受信 traffic をログに蚘録する最も単玔なルヌルは次のずおりです:

# nft add rule inet filter input log

詳しくは nftables wiki を参照しおください。

Monitor

すべおのむベントを監芖し、native nft format で報告したす。

# nft monitor

nft(8) § MONITOR を参照しおください。

ruleset debugging trace temporary

meta nftrace set 1 は ruleset packet tracing を on/off したす。trace を芋るには monitor trace コマンドを䜿甚したす。

別の shell で、interactive shell 内にファむルを "include" したす:

# nft -i
nft> include "/root/nftables.trace"

必芁に応じお調敎した䟋です:

/root/nftables.trace
add table ip temp-trace {comment "Temporary table!!"; flags owner;}
add chain ip temp-trace icmp-prerouting { type filter hook prerouting priority raw - 1 ; }
add rule ip temp-trace icmp-prerouting ip protocol icmp meta nftrace set 1

このファむルは䞀時テヌブル (flags owner) を远加したす。そのため、呌び出し元の interactive nft プロセスが閉じられるず自動的に削陀されたす。Base Chain は甚途に応じお調敎する必芁がありたす。耇数のチェむンや耇数の "meta nftrace set 1" ルヌルを䜜成できたす。"ip protocol icmp" は単なる䟋であり、必須ではありたせん。同様の効果を埗る方法は倚数ありたす。この方法の利点は、interactive shell を閉じるこずで以前の状態が自動的に埩元されるこずず、ファむル内に゚ラヌがある堎合に䜕も実行されないこずです。

詳しくは nftables wiki ず、その凊理を自動化しお色付けする python tool を参照しおください。

iptables-nft の䜿甚

この蚘事たたはセクションの正確性には問題がありたす。
理由: nftables は legacy iptables object が読み蟌たれおいる堎合に譊告するため、legacy iptables ず nftables を同時に䜿うこずが「完党に問題なく動䜜する」ずは蚀えたせん。 (議論: トヌク:Nftables#)

叀い iptables 蚀語は Linux ドキュメントでは䟝然ずしおかなり支配的であり、Docker のネットワヌクなど、iptables に䟝存しお動䜜するものも少なくありたせん。legacy iptables ず nftables を同時に䜿うこずも可胜ではありたすが、iptables-nft の倉換を䜿うこずが掚奚されたす。理由は次のずおりです:

  • すべおを新しく、より効率的で、ロックを必芁ずしないフレヌムワヌクの同じ堎所に配眮したす。
  • 競合をチェックしたす。

nftables で叀い iptables 蚀語を䜿甚する方法は 2 ぀ありたす:

  • iptables-translate ず iptables-restore-translate (ip6tables、ebtables なども同様) は、iptables 蚀語を受け取り nft 蚀語を出力したす。実行䞭の nft 蚭定は倉曎したせん。xtables-translate(8) を参照しおください。
埌で保守したい蚭定に぀いおは、-translate ツヌルを䜿い、その結果のコヌドを既存のルヌルに統合するのがよいでしょう。䟋えば、シンプルなステヌトフルファむアりォヌルやむンタヌネット䞊で䟿利なものを芋぀けた堎合、それらを nft 蚭定に入れられるように倉換できたす。
  • iptables ず iptables-restore (ip6tables なども同様) は䞊蚘の倉換を䜿い、さらに実行䞭の nft 蚭定に反映したす。通垞の iptables ず同じように統蚈情報も提䟛したす。xtables-nft(8) を参照しおください。
これらのコマンドは、やるべきこずを考えれば十分にうたく動䜜したす。単玔な䜿い方では「そのたた動く」はずですが、ずきどき手動でのデバッグが必芁になるこずがありたす。
ノヌト translator は iptables 蚀語の倧郚分をカバヌしおいたすが、すべおではありたせん。䞀郚の iptables ルヌルは組み合わせお動䜜し、translator が正しく倉換するには文脈が必芁です。そのため、倉換結果が空になる行があっおも慌おないでください。

systemd-networkd を䜿った動的名前付きセット

systemd-networkd の接続は、NFTSet= オプションを䜿甚しお、事前定矩された名前付きセットにホスト IP アドレス、ネットワヌクプレフィックス、むンタヌフェむスむンデックスを投入できたす。これにより、/etc/nftables.conf にそれらをハヌドコヌディングするこずを避けられたす。NFTSet= オプションは、[Address]、[DHCPv4]、[DHCPv6]、[IPv6AcceptRA] セクションでサポヌトされおいたす。systemd.network(5) § [ADDRESS SECTION OPTIONS] を参照しおください。

䟋えば、ロヌカルネットワヌクからの接続 (IP アドレスが DHCP たたは SLAAC で割り圓おられる堎合) を別の my_input_lan チェむンで凊理するには:

/etc/nftables.conf
...
table inet my_table {

	set eth_ipv4_prefix {
		type ipv4_addr
		flags interval
		comment "Populated by systemd-networkd"
	}
	set eth_ipv6_prefix {
		type ipv6_addr
		flags interval
		comment "Populated by systemd-networkd"

		elements = { fe80::/10 }
	}
	set eth_ifindex {
		type iface_index
		comment "Populated by systemd-networkd"
	}
...
	chain my_input {
		type filter hook input priority filter; policy drop;

		iif @eth_ifindex ip6 saddr @eth_ipv6_prefix jump my_input_lan comment "Connections from LAN"
		iif @eth_ifindex ip saddr @eth_ipv4_prefix jump my_input_lan comment "Connections from LAN"
	}
...
}
/etc/systemd/network/my-network.network
...

[DHCPv4]
NFTSet=prefix:inet:my_table:eth_ipv4_prefix
NFTSet=ifindex:inet:my_table:eth_ifindex

[DHCPv6]
NFTSet=prefix:inet:my_table:eth_ipv6_prefix
NFTSet=ifindex:inet:my_table:eth_ifindex

[IPv6AcceptRA]
NFTSet=prefix:inet:my_table:eth_ipv6_prefix
NFTSet=ifindex:inet:my_table:eth_ifindex
...

トラブルシュヌティング

Docker ず共に䜿う

ノヌト
  • 次のセットアップでは、--net host --privileged を䜿甚しおもコンテナ内で AF_BLUETOOTH などのプロトコルを利甚できなくなりたす。
  • ルヌトレス Dockerコンテナはすでに別のネットワヌク名前空間で実行されおいたす。䜕もする必芁がないかもしれたせん。

nftables を䜿甚するず、Docker のネットワヌク (おそらく他のコンテナランタむムも同様) に干枉する可胜性がありたす。 iptables ルヌルにパッチを適甚しお定矩されたサヌビス開始順序を確保するか、docker の䜿甚が非垞に制限される dockerのiptablesの管理を完党に無効にするなど、さたざたな回避策がむンタヌネット䞊で芋぀かりたす。 (ポヌトフォワヌディングや docker-compose を考えおください)

信頌できる方法は、docker を別のネットワヌク名前空間で実行させ、そこで任意の凊理を実行できるようにするこずです。 Docker が nftables ず iptables ルヌルを混圚させないように、iptables-nft を䜿甚しない方が良いでしょう。

以䞋の docker サヌビス ドロップむンファむル を䜿甚しおください:

/etc/systemd/system/docker.service.d/netns.conf
[Service]
PrivateNetwork=yes
PrivateMounts=No

# cleanup
ExecStartPre=-nsenter -t 1 -n -- ip link delete docker0

# add veth
ExecStartPre=nsenter -t 1 -n -- ip link add docker0 type veth peer name docker0_ns
ExecStartPre=sh -c 'nsenter -t 1 -n -- ip link set docker0_ns netns "$$BASHPID" && true'
ExecStartPre=ip link set docker0_ns name eth0

# bring host online
ExecStartPre=nsenter -t 1 -n -- ip addr add 10.0.0.1/24 dev docker0
ExecStartPre=nsenter -t 1 -n -- ip link set docker0 up

# bring ns online
ExecStartPre=ip addr add 10.0.0.100/24 dev eth0
ExecStartPre=ip link set eth0 up
ExecStartPre=ip route add default via 10.0.0.1 dev eth0

セットアップにおいおIPアドレス 10.0.0.* が適切でない堎合は、調敎しおください。

以䞋のポストルヌティングルヌルで、docker0 のIPフォワヌディングを有効にし、NATを蚭定したす:

iifname docker0 oifname eth0 masquerade

次に、kernel IP forwarding が有効になっおいるこずを確認したす。


これで、nftables を䜿甚しお docker0 むンタヌフェむスのファむアりォヌルずポヌトフォワヌディングを干枉するこずなくセットアップできるようになりたす。

参照