nftables で基本的なフィルタリングを設定してみた

こんにちは。サイオステクノロジーの貝野です。

RHEL8 より、新たなパケットフィルタリングツールとして nftables が導入されましたね。
そこで、本日は nftables で基本的なフィルタリングを設定する方法をご紹介します。

nftablesって?

nftables は、カーネル3.13 で初めてリリースされました。

nftables によるフィルタリングの設定は、iptables コマンドの代わりに nft コマンドを使用します。また iptables コマンドや ip6tables コマンドなど、従来別々に管理されていたユーティリティが nft に統一されました。

そして nftables の大きな特徴として、カスタムテーブルを作成できるという点があります。
用途ごとにテーブルやチェインを分けて管理できると運用しやすいですね。

テーブルの設定

まずはテーブルの設定から。
以下のコマンドで、テーブルを追加します。

nft add table family table
  • family には、ip、ip6、inet、arp、bridge、netdev のいずれかを設定します。
  • table には、任意のテーブル名を設定します。

family は、iptables の iptables、ip6tables などの各ユーティリティに相当するものです。
各 family と、それぞれ対応する iptables ユーティリティは以下の通り。

nftables ファミリー iptables ユーティリティ
ip iptables
ip6 ip6tables
inet iptables と ip6tables
arp arptables
bridge ebtables
netdev なし

【補足】

 

【コマンド実行例】

今回は、最も基本的な ip (IPv4) のフィルタリングを設定します。
family に ip を指定し、testtable というテーブルを作成しました。

$ nft add table ip testtable

ちなみに、family の指定がない場合は、デフォルトである ip (IPv4) が設定されるため、以下のコマンドでも同じ設定ができます。

nft add table testtable

チェインの設定

テーブルの追加が完了したら、次はチェインの設定をします。
以下のコマンドで、チェインを追加します。

nft add chain family table chain { type type hook hook priority priority \; }
  • family には、テーブル作成時に定義した family を設定します。
  • table には、テーブル名を設定します。
  • chain には、任意のチェイン名を設定します。
  • type には、filter、route、nat のいずれかを設定します。
  • hook には、prerouting、input、forward、output、postrouting のいずれかを設定します。
  • priority には、チェインの優先度 (整数値) を設定します。
    値が小さいほど、優先度は高くなります。また、負の値を設定することもできます。

【補足】

 

なお、選択した type ごとに、利用可能な family、hook が異なります。組み合わせは以下の通り。

type family hook
filter すべて すべて
nat ip、ip6 prerouting、input、output、postrouting
route ip、ip6 output

【コマンド実行例】

type に filter、hook に input を指定し、testchain というチェインを作成しました。

$ nft add chain ip testtable testchain { type filter hook input priority 0 \; }

ルールの設定

それでは、実際にルールを定義してみます。
簡単な設定例を以下にご案内します。

例1:80番ポートからの接続を drop する

$ nft add rule ip testtable testchain tcp dport 80 drop

例2:特定アドレス (例では 10.1.3.0/24) から送信されたパケットを drop する

$ nft add rule ip testtable testchain ip daddr 10.1.3.0/24 drop

定義済みのルールを確認するには、以下のコマンドを実行します。

$ nft list ruleset
table ip testtable {
        chain testchain {
                type filter hook input priority 0; policy accept;
                tcp dport https drop
                ip daddr 10.1.3.0/24 drop
        }
}

なお、テーブルやチェインを定義していない状態でルールを追加しようとすると、以下のようなエラーが出力されます。

$ nft add rule ip testtable testchain tcp dport 80 drop
Error: Could not process rule: No such file or directory
add rule ip testtable input tcp dport 80 drop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ルールの削除

最後は、作成したルールを削除する方法です。
上で作成したテーブル、チェインに登録したルールを削除してみます。

複数あるルールのうち、ひとつだけを削除したい場合、まずはルールのハンドル (変数) を確認する必要があります。

以下のコマンドでハンドルを確認します。

$ nft --handle --numeric list chain testtable testchain
table ip testtable {
        chain testchain { # handle 1
                type filter hook input priority 0; policy accept;
                tcp dport https drop # handle 2
                ip daddr 10.1.3.0/24 drop # handle 3
        }
}

各ルールの横に、# handle 2 や # handle 3 と記載されています。
この 2 や 3 が、各ルールのハンドルになります。

例えば、ハンドルが 3のルールを削除する場合、以下のコマンドを実行します。

$ nft delete rule testtable testchain handle 3

ルールの削除後、定義済みのルールを再度確認すると、上で指定したハンドルのルールが削除されています。

$ nft list ruleset
table ip testtable {
        chain testchain {
                type filter hook input priority 0; policy accept;
                tcp dport https drop
        }
}

また、チェイン内のすべてのルールを一括で削除したい場合は以下のコマンドが使用可能です。

$ nft flush chain testtable testchain

おわりに

nftables の基本的な設定方法についてご紹介しました。
今まで iptables をメインで使用されていた方、iptables と比較してみていかがでしたでしょうか。

今回は IPv4 を対象とした、INPUT チェインに関するご案内のみでしたが、他の family やチェインを組み合わせたフィルタリングについては、またの機会にご紹介できればと思います。

参考情報

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です