iptables後継のnftables基本操作
目次
2019年9月24日、皆さん待望のCentOS 8がリリースされました。
CentOS 6から7になった際も色々と変化がありましたが、CentOS 7から8でもやはり何点か変化があります。
主要な変化としては以下の様なものが挙げられるでしょう。
- カーネルやミドルウェアのバージョン変更
- yumからdnfへ移行
- iptablesからnftablesへの移行
これらの差異については他サイトへ譲るとして、今回はnftablesの操作について簡単に紹介します。
nftablesの起動・終了
nftables
はサービスとして導入されています。
そのためsystemctl
コマンドで操作が可能です。
# systemctl start nftables # systemctl stop nftables
設定ファイル
nftables
サービスの起動時、設定ファイルとして/etc/nftables.conf
を読み込みます。
ルールの表示
nftables
の操作にはnft
コマンドを使います。
ルールを表示するには、nft list ruleset
を実行します。
# nft list ruleset table inet filter { chain input { type filter hook input priority 0; policy accept; } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }
nftablesではiptablesと同様にルールは上から評価されます。
そのためルールの順番が重要です。
操作するルールの位置を表示するためには、--handle
パラメータを使います。
# nft list ruleset --handle table inet filter { # handle 0 chain input { # handle 1 type filter hook input priority 0; policy accept; iifname "lo" accept # handle 4 } ..(snip)..
説明のため異なるルールを表示していますが、table
やchain
、ルールの末尾にhandleが付くようになりました。
ルールの操作をする際には、この番号を使う事になります。
ルールの構造
nft list ruleset
の結果を見ると、iptablesとは出力が全く異なることが分かります。
nftablesでは、
名前 | 説明 |
---|---|
table | アドレスファミリー毎にchainをまとめるもの |
chain | ruleをまとめるもの |
rule | 通信制御ルール |
というような概念となっています。
table inet filter
は、アドレスファミリー:inet
、テーブル名:filter
というテーブルを示します。
chain input
は、チェイン名:input
というチェインを示します。
アドレスファミリー
アドレスファミリーは以下の種類が定義されます。
family | 説明 |
---|---|
ip | IPv4を示します |
ip6 | IPv6を示します |
inet | インターネット(IPv4とIPv6)の両方を示します |
arp | ARPを示します。IPv4 ARPを操作できます |
bridge | ブリッジを示します。ブリッジデバイスを通るパケットを操作できます |
netdev | NICドライバがネットワークスタックに渡した直後の、進入する全てのトラフィックを分類できます。DDoS対策などに有用です |
inet
を使っておけば、IPv4、IPv6の両方を扱えます。
netdev
は、iptablesでは扱えなかったファミリーです。Linux kernel 4.2以降が必要です。
チェイン
上の例ではinput
、forward
、output
チェインが存在しています。
このチェインはiptablesのように事前に定義されたものではなく、単なるチェイン名として名付けられているだけです。
元々はこれらのチェインも存在しません(例示のためにこちらで追加したものです)。
実際にパケットの流入(input)、送出(output)、転送(forward)時に処理をすることを示しているのは、チェインの中のtype filter hook input priority 0; policy accept;
というような行です。
このような行を含み、inputやoutput等の基本的なパケットフィルタリングを行うチェインをベースチェインと呼んでいます。
デフォルトでチェインは用意されていないので、まず最初にベースチェインを作成する必要があります。
iptablesにおけるINPUT
チェインの様なベースチェインを作成するには、以下の様なコマンドを使います。
## チェインの追加 # nft add chain inet filter input { type filter hook input priority 0\; } ## チェインの表示 # nft list chain inet filter input table inet filter { chain input { type filter hook input priority 0; policy accept; } }
上記で追加したベースチェインは以下のような設定になっています。
- チェイン (
chain inet filter input
の部分)- ファミリー:
inet
(IPv4/IPv6) - テーブル名:
filter
- チェイン名:
input
- ファミリー:
- ルール (
type filter hook input priority 0
の部分)- ベースチェインのタイプ(type):
filter
- フック(hook):
input
- プラオリティ(priority):
0
- ポリシー:
accept
(デフォルト)
- ベースチェインのタイプ(type):
nft add
を実行する際、ルール末尾の;
(セミコロン)はシェルが特別な意味を持つ文字なので、エスケープが必要です。
チェインのタイプ一覧
type filter
のfilter
部分は、filter
の他に以下から選択できます。
type | 利用可能なファミリー | 利用可能なフック | 説明 |
---|---|---|---|
filter | all | all | 標準のチェーンタイプ |
nat | ip, ip6 | prerouting input output postrouting |
アドレス変換を行うチェーンタイプ |
route | ip, ip6 | output | 通過したパケットの再度ルート探索を行う IPヘッダの変更を行うルールなどを活用してポリシールーティングなどに利用できる |
チェインのフック一覧
hook input
のinput
部分は、input
の他に以下から選択できます。
※ファミリーがip, ip6, inetの場合
hook | 説明 |
---|---|
prerouting | システムに流入しようとするパケットを処理する ルーティングに影響する値をフィルタ、変更したい場合に利用する |
input | システムに流入したパケットを処理する |
forward | 他のホストに転送されたパケットを処理する |
output | システムによって送出したパケットを処理する |
postrouting | システムから流出していくパケットを処理する |
ルールの追加
ルールを追加するには、nft add rule
またはnft insert rule
を実行します。
書式:nft add|insert rule family table chain statement
## inputチェイン末尾にルールを追加 # nft add rule inet filter input iifname ens3 tcp dport http accept ## inputチェイン先頭にルールを追加 # nft insert rule inet filter input iifname ens3 tcp dport http accept
ルールを特定の位置に追加するには、position
にhandleの番号を指定します。
書式:nft add|insert rule family table chain position statement
## handle4の後に追加 # nft add rule inet filter input handle 4 iifname ens3 tcp dport http accept ## #handle4の前に追加 # nft insert rule inet filter input handle 4 iifname ens3 tcp dport http accept
ルールの書式
上記の例では、statement
はiifname ens3 tcp dport http accept
の部分に該当します。
このstatement
は以下の様な意味を持ちます。
- 入力インタフェース名(iifname)
- ens3
- TCP宛先ポート(tcp dport)
- http
- 処理
- accept
statement
に該当する部分にはさらに複雑なルールも指定でき、以下に挙げるような表現を使うことができます。
全容は非常に大量の表現がある為、主要なものに絞って紹介します。
メタ表現
パケットに関連したメタデータにマッチさせることができます。
Keyword | 値のタイプ | 説明 |
---|---|---|
meta length | integer (32bit) | パケット長(バイト) |
iifname | ifname |
入力インタフェース名 |
oifname | ifname |
出力インタフェース名 |
pkttype | pkt_type |
パケットタイプUnicast , Broadcast , Multicast |
TCPヘッダ用表現
Keyword | 値のタイプ | 説明 |
---|---|---|
sport | inet_service |
Source port。送信元ポート |
dport | inet_service |
Destination port。送信先ポート |
flags | tcp_flags |
TCPのフラグnft describe tcp flags により出力されるフラグを指定可能 |
sport/dport
値のタイプであるinet_service
ですが、この値にはポート番号をそのまま指定するほか、/etc/services
に定義されているサービス名での指定が可能です。
例えば、tcp dport 80
とtcp dport http
は同じ指定となります。
UDPヘッダ用表現
Keyword | 値のタイプ | 説明 |
---|---|---|
sport | inet_service |
Source port。送信元ポート |
dport | inet_service |
Destination port。送信先ポート |
length | integer (16bit) | 全体のパケット長 |
ICMPヘッダ用表現
Keyword | 値のタイプ | 説明 |
---|---|---|
type | icmp_type |
ICMPタイプnft describe icmp type により出力されるタイプを指定可能 |
code | integer (8bit) | ICMPコード |
gateway | integer (32bit) | ゲートウェイのIPアドレス |
mtu | integer (16bit) | 経路MTU探索のMTU |
ICMPv6ヘッダ用表現
Keyword | 値のタイプ | 説明 |
---|---|---|
type | icmpv6_type |
ICMPv6タイプnft describe icmpv6 type により出力されるタイプを指定可能 |
code | integer (8bit) | IMCPv6コード |
CT (Conntrack, Connection Tracking) 表現
ステートフルなファイアウォールのため、パケットの状態にマッチさせることができます。
Keyword | 値のタイプ | 説明 |
---|---|---|
state | ct_state |
パケットのステートnft describe ct state により出力される値を指定可能 |
direction | ct_dir |
パケットの方向original またはreply を指定可能 |
status | ct_status |
パケットの状態 nft describe ct statusにより出力される値を指定可能 |
処理の表現
Keyword | 説明 |
---|---|
accept | ルールの評価をここで終了し、パケットを許可 |
drop | ルールの評価をここで終了し、パケットを破棄 |
queue | ルールの評価をここで終了し、ユーザスペースのアプリケーションにパケットを渡す |
continue | ルールの評価を続ける |
return | 現在のチェインから抜けて、一つ前のチェインの次のルール評価を続ける ベースチェインで return すると、処理はaccept される |
jump chain | 別のchainへ飛んで、chainの最初のルールから評価を始める chainの全ルールの評価が終わった、もしくは return した場合に次の行から評価を続ける |
goto chain | 別のchainへ飛んで、chainの最初のルールから評価を始める chainの全ルールの評価が終わった、もしくは return しても次の行の評価はしない(終了する) |
サンプル表現
## 以下全てtype filter hook inputのベースチェイン内のルール # ステートがestablishedまたはrelatedのパケットを許可 iifname ens3 ct state established, related accept iifname ens3 ct state { established, related } accept # このように書いてもよい # 22/tcp宛のパケットを許可 iifname ens3 tcp dport ssh accept # 22/tcp、80/tcp宛のパケットを許可 iifname ens3 tcp dport { ssh, http } accept # icmpの宛先到達不可能通知、エコー応答通知を許可 iifname "ens3" icmp type { destination-unreachable, echo-request } accept
なぜだか分かりませんが、ct state
では{ }
で囲わなくても良さそうです。
ルールの削除
ルールを削除するには、nft delete rule
を実行します。
## ルールをhandle付で表示 # nft list ruleset --handle table inet filter { # handle 0 chain input { # handle 1 type filter hook input priority 0; policy accept; iifname "lo" accept # handle 4 } ..(snip).. ## handle4のルールを削除 # nft delete rule inet filter input handle 4
ルールを全て削除するには、nft flush ruleset
を実行します。
ルールの保存
(2020/03/05 嘘が混ざっていたので修正)
ルールを保存するには、ルールを/etc/nfttables/rules.nft
へ出力します。
ファイル名は何でも良いですが、/etc/sysconfig/nftables.conf
でincludeしているファイル名である必要があります。
# echo -e "#!/usr/sbin/nft -f\n\nflush ruleset\n\n" > /etc/nftables/rules.nft # nft list ruleset >> /etc/nftables/rules.nft
nftables.confの方は以下の様にしておきます。
# # This this will contain your nftables rules and # is read by the systemd service when restarting # # These provide an iptables like set of filters # (uncomment to include) # include "/etc/nftables/bridge-filter.nft" # include "/etc/nftables/inet-filter.nft" # include "/etc/nftables/ipv4-filter.nft" # include "/etc/nftables/ipv4-mangle.nft" # include "/etc/nftables/ipv4-nat.nft" # include "/etc/nftables/ipv6-filter.nft" # include "/etc/nftables/ipv6-mangle.nft" # include "/etc/nftables/ipv6-nat.nft" include "/etc/nftables/rules.nft"
最近のコメント