🧱
ファイアウォール iptables をやめて nftables に乗り換えてみた
自宅で使っている Raspberry Pi OS (Debian ベース)も Jetson Linux (Ubuntu ベース)も数年前からデフォルトのファイアウォールが nftables になっていたのだが、ようやく試験的に乗り換えてみた。
感想
- 豊富な公式ドキュメント ← これが一番大事
- iptables 利用者なら受け入れやすいコマンド
- IPv4 と IPv6 を別々に書かなくてもよい
- 複数のポート番号や複数のタイプを一行で書ける
- コンフィグファイルがブラケットとインデントで見やすい
利用条件
- IPv4 はルータのファイアウォール下
- IPv6 は WAN 直結(ルータは IPv6 パススルー設定)
- ポート22(SSH)は WAN からもアクセスする
- VPN クライアントが稼動し、LAN 内の別の機器にフォワーディングできる
- Ping に応答する
設定例
iptables
# IPv4
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# inside the geteway firewall
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
# VPN
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# IPv6
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
# under IPv6 passthrough
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT
ip6tables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -i eth0 -p tcp -m state --state NEW --dport 22 -j ACCEPT
# VPN
ip6tables -A INPUT -i wg0 -j ACCEPT
ip6tables -A FORWARD -i wg0 -j ACCEPT
ip6tables -A FORWARD -o wg0 -j ACCEPT
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
nftables
# default policy
nft add table inet filter
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 \; }
# main rules
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state related,established accept
nft add rule inet filter input icmp type echo-request ct state new accept
nft add rule inet filter input icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, echo-request } accept
nft add rule inet filter input tcp dport { 22 } ct state new accept
# VPN
nft add rule inet filter input iifname wg0 accept
nft add rule inet filter forward iifname wg0 accept
nft add rule inet filter forward oifname wg0 accept
nft add table inet nat
nft add chain inet nat postrouting { type nat hook postrouting priority 0 \; }
nft add rule inet nat postrouting oifname eth0 masquerade
/etc/nftables.conf
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
iif "lo" accept
iifname "wg0" accept
ct state established,related accept
icmp type echo-request ct state new accept
icmpv6 type { echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
tcp dport 22 ct state new accept
}
chain forward {
type filter hook forward priority filter; policy drop;
iifname "wg0" accept
oifname "wg0" accept
}
chain output {
type filter hook output priority filter; policy accept;
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority filter; policy accept;
oifname "eth0" masquerade
}
}
Discussion