nftables

提供: ArchWiki
2015年7月17日 (金) 21:54時点におけるKusakata (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

関連記事

nftables は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。

nftables の公式 wiki には詳しい情報が載っています。

最初のリリースは Linux 3.13 から使うことが可能で、このカーネルは現在 [core] リポジトリに入っています (linux)。(ユーザースペースコンポーネントの) nftables は [extra] リポジトリから利用でき (nftables)、AUR には nftables-gitAUR パッケージがあります。

概要

nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。

nft

nftables のユーザースペースユーティリティ nft は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。そのため、nftables はデフォルトのテーブルやチェインを提供していません。しかしながらユーザーが iptables のような設定をエミュレートすることが可能です。

ノート: nftables には "filter" テーブルが記述されている /etc/nftables.conf が含まれています。このテーブルのルールでは、特定のプロトコルだけを許可して、他のプロトコルは全て拒否するようになっています。

nft は ifconfig や iproute2 と同じような感じで動作します。iptables のように引数のスイッチを使う代わりに、長く構造化された連続のコマンドになります。例えば:

nft add rule ip6 filter input ip6 saddr ::1 accept

add はコマンドです。ruleadd のサブコマンドです。ip6rule の引数で、ip6 ファミリーを使うことを宣言しています。filterinputrule の引数で、それぞれ使用するテーブルとチェインを指定しています。残りはルールの定義で、マッチ (ip) とパラメータ (saddr)、パラメータの引数 (::1) そしてジャンプ (accept) からなります。

以下は nft で利用できるコマンドの不完全なリストです:

list
  tables [family]
  table [family] <name>
  chain [family] <table> <name>

add
  table [family] <name>
  chain [family] <table> <name> [chain definitions]
  rule [family] <table> <chain> <rule definition>

table [family] <name> (shortcut for `add table`)

insert
  rule [family] <table> <chain> <rule definition>

delete
  table [family] <name>
  chain [family] <table> <name>
  rule [family] <table> <handle>

flush
  table [family] <name>
  chain [family] <table> <name>

family は任意ですが、デフォルトは ip になります。

テーブル

テーブルの用途はチェインを保持することです。iptables のテーブルと違って、nftables には初めから組み込まれているテーブルはありません。テーブルは指定の5つのファミリーのうちどれか一つを持つことができ、それによって様々な iptables のユーティリティを一つに統一します:

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

ip がデフォルトのファミリーです。inet を使うには Linux 3.15 が必要で、ip と ip6 ファミリーを統一してルールを簡単に定義できます。

表示

ファミリーの現在のテーブルは nft list コマンドで一覧できます。

# nft list tables
# nft list tables ip6

テーブルの名前を指定することで完全なテーブルの定義を一覧できます:

# nft list table foo
# nft list table ip6 foo

作成

テーブルは2つのコマンド (片方はもう片方のショートカットです) で追加することができます。以下は foo という名前の ip テーブルと foo という名前の ip6 テーブルを追加する例です:

# nft add table foo
# nft table ip6 foo

ファミリーが異なっていれば同じ名前のテーブルを作ることが可能です。

削除

テーブルを削除することができるのはチェインが存在しない場合だけです。

# nft delete table foo
# nft delete table ip6 foo

チェイン

チェインの用途はルールを保持することです。iptables のチェインと違って、nftables には初めから組み込まれているチェインはありません。そのためチェインが netfilter フレームワークにあるタイプやフックをどれも使わない場合、iptables とは異なりチェインを通り抜けるパケットは nftables の影響を受けません。

表示

nft list table foo コマンドは foo テーブルの全てのチェインを表示します。個々のチェインからルールを一覧することもできます。

# nft list chain foo bar
# nft list chain ip6 foo bar

上記コマンドは ip と ip6 の foo テーブルの bar チェインを表示します。

作成

テーブルがファイル定義や nft add chain コマンドによって作成されたら、チェインを追加することができます。

# nft add chain foo bar
# nft add chain ip6 foo bar

上記コマンドは bar という名前のチェインを ip と ip6 の foo テーブルに追加します。

プロパティ

nftables には組み込みチェインが存在しないため、チェインは netfilter フレームワークの特定の機能にアクセスすることができます。

# nft add chain filter input \{ type filter hook input priority 0\; \}

上記コマンドは nftables に input という名前のチェインを filter テーブルに追加させ、そのタイプ・フック・プライオリティを定義します。これらのプロパティは基本的に iptables で組み込まれているテーブルやチェインを置き換えるものです。

タイプ

チェインには3つのタイプがあり、iptables で使われているテーブルと対応しています:

  • filter
  • nat
  • route (mangle)
フック

チェインは5つのフックを使うことができ、iptables で使われているチェインと対応しています:

  • input
  • output
  • forward
  • prerouting
  • postrouting
プライオリティ
ノート: Priorities do not currently appear to have any effect on which chain sees packets first.
ノート: プライオリティは符号なしの整数として設定するようになっているため、負のプライオリティを設定した場合、優先度は逆に高くなります。

プライオリティは nftables がどのパケットを初めに通過させるかを示します。整数で指定し、高い値を与えるほど優先されます。

削除

チェインはルールが存在しない場合にのみ削除することができます。

# nft delete chain foo bar
# nft delete chain ip6 foo bar

以上のコマンドは ip と ip6 の foo テーブルから bar チェインを削除します。

ルール

ルールの用途はパケットを識別(マッチ)して処理を実行(ジャンプ)することです。iptables と同じように、様々なマッチやジャンプが利用できますが、nftables には欠けている機能も存在します。

表示

テーブルを表示するのと同じ方法を使って、nft list コマンドでテーブルの中の現在のルールを表示することができます。個別のチェインからルールを表示することも可能です。

# nft list chain foo bar
# nft list chain ip6 foo bar

上記のコマンドで、ip と ip6 の foo テーブルの bar チェインのルールが表示されます。

作成

テーブルがファイル定義や nft add rule コマンドによって作成されたら、ルールを追加することができます。

# nft add rule foo bar ip saddr 127.0.0.1 accept
# nft add rule ip6 foo bar ip saddr ::1 accept

上記のコマンドで、ip と ip6 の foo テーブルの bar チェインにルールが追加され、saddr (ソースアドレス) が 127.0.0.1 (IPv4) や ::1 (IPv6) の場合に ip パケットにマッチして、パケットを許可します。

マッチ

nftables では様々なマッチを使うことができ、ほとんどは、iptables と対応するようになっています。一番大きな違いは汎用的なマッチと暗黙的なマッチが存在しないことです。汎用的なマッチとは、--protocol--source のように、いつでも使うことができるマッチで、暗黙的なマッチとは、--sport のように、特定のプロトコルでしか使えないマッチのことです。

以下は利用できるマッチの一部です:

  • meta (meta properties, e.g. interfaces)
  • icmp (ICMP protocol)
  • icmpv6 (ICMPv6 protocol)
  • ip (IP protocol)
  • ip6 (IPv6 protocol)
  • tcp (TCP protocol)
  • udp (UDP protocol)
  • sctp (SCTP protocol)
  • ct (connection tracking)

以下はマッチ引数の一部です (完全なリストは man 8 nft を見て下さい):

meta:
  oif <output interface INDEX>
  iif <input interface INDEX>
  oifname <output interface NAME>
  iifname <input interface NAME>

  (oif and iif accept string arguments and are converted to interface indexes)
  (oifname and iifname are more dynamic, but slower because of string matching)

icmp:
  type <icmp type>

icmpv6:
  type <icmpv6 type>

ip:
  protocol <protocol>
  daddr <destination address>
  saddr <source address>

ip6:
  daddr <destination address>
  saddr <source address>

tcp:
  dport <destination port>
  sport <source port>

udp:
  dport <destination port>
  sport <source port>

sctp:
  dport <destination port>
  sport <source port>

ct:
  state <new | established | related | invalid>

ジャンプ

ジャンプは iptables と同じように使うことができますが、ひとつのルールで複数のジャンプを使用できるようになっています。

# nft add rule filter input tcp dport 22 log accept

以下はジャンプの未完成なリストです:

  • accept (accept a packet)
  • reject (reject a packet)
  • drop (drop a packet)
  • snat (perform source NAT on a packet)
  • dnat (perform destination NAT on a packet)
  • log (log a packet)
  • counter (keep a counter on a packet; counters are optional in nftables)
  • return (stop traversing the chain)
  • jump <chain> (jump to another chain)
  • goto <chain> (jump to another chain, but do not return)

挿入

nft insert rule コマンドでチェインにルールを挿入することができます。

# nft insert rule filter input ct state established,related accept

削除

個々のルールはハンドルを使わないと削除することができません。nft --handle list コマンドを使うことでルールのハンドルを確認できます。--handle スイッチを付けると、nft はハンドルを出力するようになります。

以下ではルールのハンドルを確認してルールを削除しています。未解決の IP アドレスのような、数字の出力を表示するときは --number 引数を使うと良いでしょう。

# nft --handle --numeric list chain filter input
table ip fltrTable {
     chain input {
          type filter hook input priority 0;
          ip saddr 127.0.0.1 accept # handle 10
     }
}
# nft delete rule fltrTable input handle 10

nft flush table コマンドを使うことでテーブルの全てのチェインをフラッシュできます。個別のチェインをフラッシュするときは nft flush chain または nft delete rule コマンドを使います。

# nft flush table foo
# nft flush chain foo bar
# nft delete rule ip6 foo bar

最初のコマンドでは ip foo テーブルのチェイン全てをフラッシュします。2番目のコマンドは ip foo テーブルの bar チェインをフラッシュします。3番目のコマンドは ip6 foo テーブルの bar チェインの全てのルールを削除します。

アトミックリロード

現在のルールセットをフラッシュする:

# echo "flush ruleset" > /tmp/nftables

現在のルールセットをダンプする:

# nft list ruleset >> /tmp/nftables

/tmp/nftables を編集して次のコマンドで変更を適用:

# nft -f /tmp/nftables

ファイル定義

nft -f コマンドでファイル定義を利用することができます。このコマンドは iptables-restore コマンドと同じように動作します。ただし、iptables-restore と違って、既存のルールセットをフラッシュしないので、前もって flush コマンドを実行する必要があります。

/etc/nftables/filter.rules
flush table ip filter
table ip filter {
     chain input {
          type filter hook input priority 0;
          ct state established,related accept
          ip saddr 127.0.0.1 accept
          tcp dport 22 log accept
          reject
     }
}

ルールを (iptables-save のように) エクスポートするには:

# nft list ruleset

基本的なファイアウォール

以下の例は nft コマンドを使ってベーシックな IPv4 ファイアウォールを設定する方法を示しています。IPv4 と IPv6 の両方をフィルタリングしたい場合、/usr/share/nftables にある他のサンプルを見たり、/etc/nftables.conf のデフォルト (IPv4/IPv6 で動作するように設定済みです) を使うようにしてください。

iptables のようなチェインを設定するには、まず備え付けの IPv4 フィルターファイルを使う必要があります:

# nft -f /usr/share/nftables/ipv4-filter

作成されたチェインを表示するには:

# nft list table filter

Drop output to a destination:

# nft add rule ip filter output ip daddr 1.2.3.4 drop

Drop packets destined for local port 80:

# nft add rule ip filter input tcp dport 80 drop

チェインの全てのルールを削除:

# nft delete rule filter output

サンプル

シンプルな IP/IPv6 ファイアウォール

firewall.rules
# A simple firewall

flush ruleset

table firewall {
  chain incoming {
    type filter hook input priority 0;

    # established/related connections
    ct state established,related accept

    # invalid connections
    ct state invalid drop

    # loopback interface
    iifname lo accept

    # icmp
    icmp type echo-request accept

    # open tcp ports: sshd (22), httpd (80)
    tcp dport {ssh, http} accept

    # everything else
    drop
  }
}

table ip6 firewall {
  chain incoming {
    type filter hook input priority 0;

    # established/related connections
    ct state established,related accept

    # invalid connections
    ct state invalid drop

    # loopback interface
    iifname lo accept

    # icmp
    # routers may also want: mld-listener-query, nd-router-solicit
    icmpv6 type {echo-request,nd-neighbor-solicit} accept

    # open tcp ports: sshd (22), httpd (80)
    tcp dport {ssh, http} accept

    # everything else
    drop
  }
}

Limit rate IP/IPv6 ファイアウォール

firewall.2.rules
table firewall {
    chain incoming {
        type filter hook input priority 0;

        # no ping floods:
        ip protocol icmp limit rate 10/second accept
        ip protocol icmp drop

        ct state established,related accept
        ct state invalid drop

        iifname lo accept

	# avoid brute force on ssh:
        tcp dport ssh limit rate 15/minute accept

        reject
    }
}

table ip6 firewall {
    chain incoming {
        type filter hook input priority 0;

        # no ping floods:
        ip6 nexthdr icmpv6 limit rate 10/second accept
        ip6 nexthdr icmpv6 drop

        ct state established,related accept
        ct state invalid drop

        # loopback interface
        iifname lo accept

	# avoid brute force on ssh:
        tcp dport ssh limit rate 15/minute accept

        reject
    }
}

ジャンプ

設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと Error: Could not process rule: No such file or directory というエラーが発生します。

jump.rules
table inet filter {
    chain web {
        tcp dport http accept
        tcp dport 8080 accept
    }
    chain input {
        type filter hook input priority 0;
        ip saddr 10.0.2.0/24 jump web
        drop
    }
}

起動時にルールをロードする

システムの起動時にルールを自動的にロードするには、systemctl enable nftables を実行して nftables の systemd サービスを有効にしてください。

ルールは /etc/nftables.conf からデフォルトでロードされるようになっています。

ノート: systemd サービスが正しく動作するように必要な nftables 関連のモジュール全てのエントリを含む /etc/modules-load.d/nftables.conf を作成する必要があります。モジュールのリストは次のコマンドで取得可能です:
lsmod | grep nf
作成していないと、Error: Could not process rule: No such file or directory エラーで終了してしまいます。

Syslog にログを出力する

Linux カーネル 3.17 未満を使っている場合、ログ出力を有効にするには xt_LOG を modprobe する必要があります。

参照