nftablesを調べる/使う その3

はじめに

その2ではnftablesのデフォルト設定のINPUTチェーンに注目してルール内容について見ていきました。今回は普段から使うようなコマンドを実行してみようと思います。

ルール全体の削除、テーブル作成からルール追加まで

今の状態は ipアドレスファミリ filterテーブルのチェーンがそれぞれINPUT, FORWARD, OUTPUT が存在しています。これからすべてのルールを削除し、新しくルールを1から作っていきたいと思います。

[root@ip-172-30-3-189 ~]# nft list ruleset
table ip filter {
        chain INPUT {
                type filter hook input priority filter; policy accept;
                ct state related,established counter packets 3485 bytes 16848128 accept
                meta l4proto icmp counter packets 0 bytes 0 accept
                iifname "lo" counter packets 0 bytes 0 accept
                meta l4proto tcp ct state new tcp dport 22 counter packets 1 bytes 64 accept
                counter packets 1 bytes 362 reject with icmp type host-prohibited
        }

        chain FORWARD {
                type filter hook forward priority filter; policy accept;
                counter packets 0 bytes 0 reject with icmp type host-prohibited
        }

        chain OUTPUT {
                type filter hook output priority filter; policy accept;
        }
}

# ルール全体を削除
[root@ip-172-30-3-189 ~]# nft flush ruleset

# 全体ルールの確認
[root@ip-172-30-3-189 ~]# nft list ruleset
[root@ip-172-30-3-189 ~]# 
# なにもでてこない

これに新たにテーブル、チェーン、ルールを追加します。

# テーブル追加
# nft add <アドレスファミリ>  <テーブル名>  <フラグ>
# create add <アドレスファミリ>  <テーブル名>  <フラグ>
[root@ip-172-30-3-189 ~]# nft create table ip town

# チェーン追加
# add chain [<アドレスファミリ>]  <テーブル名>  <チェーン名> [ <ベースチェーンのパラメータ>]
# create chain [ <アドレスファミリ>]  <テーブル名>  <チェーン名> [ <ベースチェーンのパラメータ>]
[root@ip-172-30-3-189 ~]# nft create chain ip town INPUT { type filter hook input priority 1 \; policy accept \; }

# ルール追加
# add rule [<アドレスファミリ>] <テーブル名> <チェーン名> <ステートメント>
# insert rule [<アドレスファミリ>] <テーブル名> <チェーン名> <ステートメント>
[root@ip-172-30-3-189 ~]# nft add rule ip town INPUT tcp dport 22  accept
[root@ip-172-30-3-189 ~]# nft add rule ip town INPUT drop


# 確認する
[root@ip-172-30-3-189 ~]# nft -a list ruleset
table ip town { # handle 4
        chain INPUT { # handle 1
                type filter hook input priority filter + 1; policy accept;
                tcp dport 22 accept # handle 2  # SSH許可
                drop # handle 3  # 明示的に許可したルールに当てはまらないパケットをdropする。
        }
}

とりあえずはSSH接続を許可しました。ちなみに、チェーン追加のときにpolicyをdropで追加するとSSHを許可するルールが存在しないためSSH接続が切れます。(一敗)

ルールのリストを取得するとき -a をオプションとしてつけることで、それぞれのテーブル、チェーン、ルールに紐付いたhandleの数字がわかりますね、てっきり自分で明示的に追加したものだけかと思いっていましたが自然と付与されるようです。
まぁ、よく考えればこれまでiptablesではルールに紐付いた数字を指定してルールを削除していたので、それと同じことでした。

さて、この状態だとSSH以外の通信を許可していないため、yumを使ってパッケージをインストールしようとしても名前解決やローカルホストから外部へ通信したときの応答もブロックすることになります。

そういうわけでお決まりの、既に確立した接続の通信と確立した通信に関連するものを許可するルール、ついでにローカルループバックの許可を追加します。

# drop以下にルールを設定しても適用されないため、handle 2 の下に追加する。
[root@ip-172-30-3-189 ~]# nft add rule ip town INPUT handle 2 ct state related,established accept 
# ローカルホストからの通信を許可する、今度はhandle 2 へ insert するので上に追加する。iif lo は入力インターフェイスのインデックスもしくはインターフェイス名を指定している。
[root@ip-172-30-3-189 ~]# nft insert rule ip town INPUT handle 2 iif lo accept

# 確認
[root@ip-172-30-3-189 ~]# nft -a list ruleset
table ip town { # handle 4
        chain INPUT { # handle 1
                type filter hook input priority filter + 1; policy accept;
                iif "lo" accept # handle 7  # ローカルホストからの通信を許可
                tcp dport 22 accept # handle 2
                ct state established,related accept # handle 6  # ステートがestablished, relatedを許可
                drop # handle 3
        }
}

なんだかいつもの感じがでてきました。これにあとはhttpやhttpsとか必要なサービスのポートを許可していったりすれば、とりあえずそれでいい感じのような気もしてきます。 ひとまずこのルールを保存して今回はここまでにしておきます。

[root@ip-172-30-3-189 ~]# nft list ruleset > ruleset.txt
[root@ip-172-30-3-189 ~]# cat ruleset.txt 
table ip town {
        chain INPUT {
                type filter hook input priority filter + 1; policy accept;
                iif "lo" accept
                tcp dport 22 accept
                ct state established,related accept
                drop
        }
}

次回は…といきたいところですが、次どうするかのネタを考えていなかったため考え中。これまで触ってきたことはiptablesでもやってきたことをnftablesに置き換えた処理なので、nftables特有なものがあればそれも触ってみたいと思います。