「Nftables」の版間の差分
(→ジャンプ: 翻訳) |
(→基本的なファイアウォール: 翻訳) |
||
| 338行目: | 338行目: | ||
# nft list table filter |
# nft list table filter |
||
| + | 特定の宛先への出力を破棄: |
||
| − | Drop output to a destination: |
||
# nft add rule ip filter output ip daddr 1.2.3.4 drop |
# nft add rule ip filter output ip daddr 1.2.3.4 drop |
||
| + | 宛先がローカルのポート 80 のパケットを破棄: |
||
| − | Drop packets destined for local port 80: |
||
# nft add rule ip filter input tcp dport 80 drop |
# nft add rule ip filter input tcp dport 80 drop |
||
2016年12月22日 (木) 02:31時点における版
nftables は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。
nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。
nftables の公式 wiki には詳しい情報が載っています。
目次
インストール
Linux カーネル 3.13 から nftables を使うことはできますが、できるかぎり最新のカーネルを使用すること推奨します。nftables のユーザーランドユーティリティは nftables パッケージで利用できます。AUR には nftables-gitAUR パッケージも存在します。
基本的な実装
他のファイアウォールと異なり、nftables ではコマンドラインで作成される一時的なルールと、ファイルに保存して読み込まれる永続的なルールを区別しています。デフォルトファイルの /etc/nftables.conf には "inet filter" という名前のシンプルな ipv4/ipv6 ファイアウォールテーブルが既に記述されています。
デフォルトルールセットのロード
nftables.service を起動・有効化してください。
以下のコマンドでルールセットを確認できます:
# nft list ruleset
inet filter テーブルの設定が表示された場合、デスクトップとしてインターネットを問題なく利用できます。
nft
nftables のユーザースペースユーティリティ nft は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。そのため、nftables はデフォルトのテーブルやチェインを提供していません。しかしながらユーザーが iptables のような設定をエミュレートすることが可能です。
nft は ifconfig や iproute2 と同じような感じで動作します。iptables のように引数のスイッチを使う代わりに、長く構造化された連続のコマンドになります。例えば:
nft add rule ip6 filter input ip6 saddr ::1 accept
add はコマンドです。rule は add のサブコマンドです。ip6 は rule の引数で、ip6 ファミリーを使うことを宣言しています。filter と input は rule の引数で、それぞれ使用するテーブルとチェインを指定しています。残りはルールの定義で、マッチ (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 (IPv4) がデフォルトのファミリーです。特に指定がなければ ip が使われます。
IPv6 は ip6 で指定できます。
IPv4 と IPv6 の両方に適用されるルールを作成するには 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)
フック
チェインは6つのフックを使うことができ、ingress 以外は iptables で使われているチェインと対応しています:
- ingress
- input
- output
- forward
- prerouting
- postrouting
ingress フックは既存の tc ユーティリティを置き換えます。
プライオリティ
プライオリティは nftables がどのパケットを初めに通過させるかを示します。整数で指定し、高い値を与えるほど優先されます。
編集
チェインを編集するには、以下のようにコマンドを実行してください:
# nft chain <table> <family> <chain> { [ type <type> hook <hook> device <device> priority <priority> \; policy <policy> \; ] }
例えば、デフォルトテーブルの input チェインのポリシーを "accept" から "drop" に変更するには:
# nft chain inet filter input { policy drop \; }
削除
チェインはルールが存在しない場合にのみ削除することができます。
# 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 (メタプロパティ。例: インターフェイス)
- icmp (ICMP プロトコル)
- icmpv6 (ICMPv6 プロトコル)
- ip (IP プロトコル)
- ip6 (IPv6 プロトコル)
- tcp (TCP プロトコル)
- udp (UDP プロトコル)
- sctp (SCTP プロトコル)
- ct (接続のトラッキング)
以下はマッチ引数の一部です (完全なリストは nft(8) を見て下さい):
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 (パケットを許可)
- reject (パケットを拒否)
- drop (パケットを破棄)
- snat (送信元 NAT を実行)
- dnat (宛先 NAT を実行)
- log (パケットを記録)
- counter (パケットカウンタを保持、nftables ではカウンタはオプションです)
- return (チェインの横断を停止)
- jump <chain> (他のチェインにジャンプ)
- goto <chain> (他のチェインにジャンプ、元のチェインに戻らない)
挿入
先頭に追加
nft insert rule コマンドでチェインにルールを挿入することができます。
# nft insert rule filter input ct state established,related accept
特定の場所に追加
Nftables はハンドルを使用してルールの位置を定義します。情報を取得するには、-a フラグを付けてルールセットを確認してください:
# nft list ruleset -a
特定のハンドラが付いているルールの後にルールを追加するには:
# nft add rule table_name chain_name position handler_number [rule-definition]
削除
個々のルールはハンドルを使わないと削除することができません。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
特定の宛先への出力を破棄:
# nft add rule ip filter output ip daddr 1.2.3.4 drop
宛先がローカルのポート 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 inet filter {
chain input {
type filter hook input priority 0; policy drop;
# established/related connections
ct state established,related accept
# invalid connections
ct state invalid drop
# loopback interface
iif lo accept
# ICMP
# routers may also want: mld-listener-query, nd-router-solicit
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept
# SSH (port 22)
tcp dport ssh accept
# HTTP (ports 80 & 445)
tcp dport { http, https } accept
}
}
Limit rate IP/IPv6 ファイアウォール
firewall.2.rules
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# no ping floods:
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 10/second accept
ip protocol icmp icmp type echo-request limit rate 10/second accept
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
}
}
ジャンプ
設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと 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
}
}
実践的なサンプル
インターフェイスによってルールを変える
複数のネットワークインターフェイスが存在する場合、それぞれのインターフェイスごとに別々のフィルターチェインを設定したい場合があるかもしれません。例えば、ホームルーターを構築するとき、LAN 上でアクセスできるウェブサーバーを実行しつつ (nsp3s0 インターフェイス)、インターネットからはアクセスできないようにしたい場合 (enp2s0 インターフェイス) などは以下のように設定します:
table inet filter {
chain input { # this chain serves as a dispatcher
type filter hook input priority 0;
iifname lo accept # always accept loopback
iifname enp2s0 jump input_enp2s0
iifname enp3s0 jump input_enp3s0
reject with icmp type port-unreachable # refuse traffic from all other interfaces
}
chain input_enp2s0 { # rules applicable to public interface interface
ct state {established,related} accept
ct state invalid drop
udp dport bootpc accept
tcp dport bootpc accept
reject with icmp type port-unreachable # all other traffic
}
chain input_enp3s0 {
ct state {established,related} accept
ct state invalid drop
udp dport bootpc accept
tcp dport bootpc accept
tcp port http accept
tcp port https accept
reject with icmp type port-unreachable # all other traffic
}
chain ouput { # we let everything out
type filter hook output priority 0;
accept
}
}
もしくは iifname ステートメントを特定のインターフェイスで使用して、他のインターフェイスについてはデフォルトルールを設定するという方法もあります。
マスカレード
nftables には特殊なキーワード masquerade が存在し、送信元アドレスが自動的に出力インターフェイスのアドレスに設定されます (ソース)。ルーターのインターフェイスが多数の ISP に接続されているときなど、インターフェイスの IP アドレスが一定でない場合に有用です。通常は、インターフェイスの IP アドレスが変わるたびにネットワークアドレス変換 (NAT) のルールを更新する必要があります。
masquerade を使用するには:
- カーネルのバージョンが 3.18 以上である必要があります。
- カーネルコンフィグで以下のマスカレード設定が有効になっている必要があります。
CONFIG_NFT_MASQ=m
masqueradeキーワードはnatタイプのチェインでのみ使うことができ、inetファミリーのテーブルでは利用できません。ipファミリーやip6ファミリーのテーブルを使ってください。- マスカレードは一種のソース NAT であり、出力パスでのみ機能します。
2つのインターフェイスが存在し nsp3s0 が LAN に接続され、enp2s0 がインターネットに接続されているマシンでの設定例:
table ip nat {
chain prerouting {
type nat hook prerouting priority 0;
}
chain postrouting {
type nat hook postrouting priority 0;
oifname "enp0s2" masquerade
}
}
Syslog にログを出力する
Linux カーネル 3.17 未満を使っている場合、ログ出力を有効にするには xt_LOG を modprobe する必要があります。