0.はじめに
今後はiptablesに代わってnftablesが採用されるらしい。
firewalldに完全移行した人はバックエンドが変わるだけで気にする必要はないようだが、せっかくなのでnftalbesをさわってみる。
(ていうか自分がfirewalldに移行できていない)
CentOS8はまだリリース前なのでDebian10 "Buster"で試す。
1. 前提
- iptablesの知識はあるけどnftablesは知らない
- とりあえず動かしてみたい
- 何かあっても責任は負えません
2. 環境
ローカル仮想環境
- Linux debian10 4.19.0-6-amd64
3. nftablesを使ってみる
インストール
# apt install nftables
# nft --version
nftables v0.9.0 (Fearless Fosdick)
起動
# systemctl start nftables.service
起動すると/etc/nftables.confが読み込まれるがこの時点では何もルールが設定されていない。
サンプル
/usr/share/doc/nftables/examples/workstation.nftをコピーしてくる。
簡単なサーバーの場合、開放するポートさえ変更すれば十分そう。
- 変更後の/etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
# accept any localhost traffic
iif lo accept
# accept traffic originated from us
ct state established,related accept
# activate the following line to accept common local services
tcp dport { 22, 80, 443 } ct state new accept
# ↑の行のコメントアウトを外して、開放したいtcpポートを列挙
# accept neighbour discovery otherwise IPv6 connectivity breaks.
ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
# count and drop any other traffic
counter drop
}
}
再読込
# systemctl reload nftables.service
NAT
/usr/share/doc/nftables/examples/nat.nftを読むとNATの設定方法も書いてある。
4. iptablesの設定をnftables用に変換
suin様の
にお世話になったので、これをnftableで使ってみます。
inet -> ip に変更
nftablesはipv4とipv6をinetとしてまとめて扱えるのだが、とりあえず今はipv4だけを考える。
システムのipv6を無効化して、さらに/etc/nftables.conf内のinetをipに変更。
#!/usr/sbin/nft -f
flush ruleset
table ip filter {
chain input {
type filter hook input priority 0;
}
chain forward {
type filter hook forward priority 0;
}
chain output {
type filter hook output priority 0;
}
}
iptablesのインストールと設定
nftablesを一度とめてiptablesをインストール。
# systemctl stop nftables.service
# apt install iptables
suin様のスクリプトをほぼ素のまま実行(最後のfinalizeだけコメントアウトした)。
nftables用に変換
iptablesの設定を一度ファイルに書き出します。
# iptables-save > iptables.conf
(他のサーバーで動かしている場合はそっちから持ってきても可)
用意されてるコマンドでnftables用に変換します。
# iptables-restore-translate -f iptables.conf > nftables.temp
(上記のコマンドが見つからなければiptablesをインストール)
注意点
大文字と小文字が区別されてしまうので、いま作成したnftables.temp内の
"INPUT", "OUTPUT", "FORWARD"を小文字にしておきます。
適用
nftablesを再度起動させ変換したルールを追加します。
# systemctl start nftables.service
# nft -f nftables.temp
確認
# nft list ruleset
永続化
nftコマンドで一時的に追加したルールを永続化する場合はファイルに上書きしておきます。
# nft list ruleset > /etc/nftables.conf
5. 最終的なnftables.conf
table ip filter {
chain input {
type filter hook input priority 0; policy drop;
iifname "lo" counter packets 0 bytes 0 accept
ip protocol tcp ct state established,related counter packets 60 bytes 4136 accept
tcp flags & (syn | ack) == syn | ack ct state new counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (fin | syn | rst | psh | ack | urg) == 0x0 counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (fin | syn) == fin | syn counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (syn | rst) == syn | rst counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (fin | syn | rst | psh | ack | urg) == fin | syn | rst | ack | urg counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (fin | rst) == fin | rst counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (fin | ack) == fin counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (psh | ack) == psh counter packets 0 bytes 0 jump STEALTH_SCAN
tcp flags & (ack | urg) == urg counter packets 0 bytes 0 jump STEALTH_SCAN
ip frag-off & 8191 != 0 counter packets 0 bytes 0 log prefix "fragment_packet:"
ip frag-off & 8191 != 0 counter packets 0 bytes 0 drop
icmp type echo-request counter packets 0 bytes 0 jump PING_OF_DEATH
tcp flags & (fin | syn | rst | ack) == syn counter packets 0 bytes 0 jump SYN_FLOOD
tcp dport { http, https } counter packets 0 bytes 0 jump HTTP_DOS
tcp dport auth counter packets 0 bytes 0 reject with tcp reset
ip daddr 192.168.1.255 counter packets 0 bytes 0 log prefix "drop_broadcast: "
ip daddr 192.168.1.255 counter packets 0 bytes 0 drop
ip daddr 255.255.255.255 counter packets 0 bytes 0 log prefix "drop_broadcast: "
ip daddr 255.255.255.255 counter packets 0 bytes 0 drop
ip daddr 224.0.0.1 counter packets 0 bytes 0 log prefix "drop_broadcast: "
ip daddr 224.0.0.1 counter packets 0 bytes 0 drop
ip protocol icmp counter packets 0 bytes 0 accept
tcp dport { http, https } counter packets 0 bytes 0 accept
tcp dport ssh counter packets 0 bytes 0 accept
counter packets 0 bytes 0 log prefix "drop: "
counter packets 0 bytes 0 drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
chain STEALTH_SCAN {
counter packets 0 bytes 0 log prefix "stealth_scan_attack: "
counter packets 0 bytes 0 drop
}
chain PING_OF_DEATH {
icmp type echo-request meter t_PING_OF_DEATH size 65535 { ip saddr timeout 5m limit rate 1/second burst 10 packets} counter packets 0 bytes 0 return
counter packets 0 bytes 0 log prefix "ping_of_death_attack: "
counter packets 0 bytes 0 drop
}
chain SYN_FLOOD {
tcp flags & (fin | syn | rst | ack) == syn meter t_SYN_FLOOD size 65535 { ip saddr timeout 5m limit rate 200/second burst 3 packets} counter packets 0 bytes 0 return
counter packets 0 bytes 0 log prefix "syn_flood_attack: "
counter packets 0 bytes 0 drop
}
chain HTTP_DOS {
tcp dport { http, https } meter t_HTTP_DOS size 65535 { ip saddr timeout 5m limit rate 1/second burst 100 packets} counter packets 0 bytes 0 return
counter packets 0 bytes 0 log prefix "http_dos_attack: "
counter packets 0 bytes 0 drop
}
}
これを元にnftablesの文法を勉強しようと思います。