今回は nftables のスクリプトを systemd から読み込むことで設定を永続化する方法について。
結論から述べると systemctl cat nftables
で読み込んでいるファイルの場所を確認したら、そこにルールを書けば良い。
使った環境は次のとおり。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.2 LTS Release: 24.04 Codename: noble $ uname -srm Linux 6.8.0-59-generic x86_64 $ nft --version nftables v1.0.9 (Old Doc Yak #3)
もくじ
下準備
まずは nftables をインストールする。 一般的な環境であれば最初から入っているはず。
$ sudo apt-get -y install nftables
UFW (Uncomplicated Firewall) は、nftables と同時に利用すると競合しやすい。 そのため、もし使っている場合には無効にする。
$ sudo systemctl stop ufw
$ sudo systemctl disable ufw
そして、systemd で nftables のサービスを動かす。
$ sudo systemctl start nftables
$ sudo systemctl enable nftables
設定ファイルの場所を確認する
まずは nftables のサービスが、どこの設定ファイルを読むのか確認する。
systemctl cat
でユニットファイルの内容を見るのが手っ取り早い。
$ systemctl cat nftables | grep -i ^exec ExecStart=/usr/sbin/nft -f /etc/nftables.conf ExecReload=/usr/sbin/nft -f /etc/nftables.conf ExecStop=/usr/sbin/nft flush ruleset
上記から /etc/nftables.conf
を読んでいることが確認できる。
デフォルトの設定を確認する
先ほど確認した設定ファイルの内容を見てみよう。 すると input, forward, output hook に base チェインが設定されている。 単なる入れ物が用意されているだけで、すべての通信が accept される状態になっている。
$ cat /etc/nftables.conf #!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority filter; } chain forward { type filter hook forward priority filter; } chain output { type filter hook output priority filter; } }
上記の設定ファイルの内容がシステムに反映されているか確認してみよう。
nft list ruleset
コマンドを実行すると、先ほどの設定ファイルと同じ内容が確認できる。
$ sudo nft list ruleset table inet filter { chain input { type filter hook input priority filter; policy accept; } chain forward { type filter hook forward priority filter; policy accept; } chain output { type filter hook output priority filter; policy accept; } }
これは、先ほど systemd の nftables サービスを開始したため設定が読み込まれている。
nftables の設定ファイルを編集してみる
続いては systemd のサービスが読んでいる nftables の設定ファイルを編集してみよう。
以下では /etc/nftables
にディレクトリを作って、そこに nftables のスクリプトを用意している。
内容は基本的な設定を入れたファイアウォールになっている。
$ sudo mkdir -p /etc/nftables $ cat << 'EOF' | sudo tee /etc/nftables/simple-firewall.nft #!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority 0; policy drop; # 関連・確立済みのコネクションは通す ct state established,related accept # 不正なコネクションは落とす ct state invalid drop # ループバックは通す iif lo accept # ICMPv4 の特定タイプは通す ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept # ICMPv6 の特定タイプは通す ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept # SSH (TCP/22) はレートリミットつきで通す tcp dport ssh limit rate 10/minute accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } } EOF
上記の設定を /etc/nftables.conf
から include する。
$ cat << 'EOF' | sudo tee /etc/nftables.conf >/dev/null #!/usr/sbin/nft -f flush ruleset include "/etc/nftables/simple-firewall.nft" EOF
この状態で systemd の nftables サービスをリロードする。
$ sudo systemctl reload nftables
すると、先ほどのファイルに書いた内容が動作に反映される。
$ sudo nft list ruleset table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept ct state invalid drop iif "lo" accept ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept ip6 nexthdr ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept tcp dport 22 limit rate 10/minute burst 5 packets accept } chain forward { type filter hook forward priority filter; policy drop; } chain output { type filter hook output priority filter; policy accept; } }
再起動して設定が永続化されていることを確認する
念の為、システムを再起動しても設定が反映され直すことを確認しておこう。
$ sudo shutdown -r now
再起動が終わったら、もう一度ログインして nftables の設定を確認する。
$ sudo nft list ruleset table inet filter { chain input { type filter hook input priority filter; policy drop; ct state established,related accept ct state invalid drop iif "lo" accept ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept ip6 nexthdr ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept tcp dport 22 limit rate 10/minute burst 5 packets accept } chain forward { type filter hook forward priority filter; policy drop; } chain output { type filter hook output priority filter; policy accept; } }
ちゃんと、先ほどと同じ設定が読み込まれていることが確認できる。
めでたしめでたし。