午後をつぶした沈黙
ファイアウォールのルールは、パケットをどうするかを決めます。通す、返事なしで捨てる(drop)、返事を付けて断る(reject)のどれかです。その選び方で、相手側に何が見えるか、故障がどれだけ早く見つかるかが決まります。
ある開発者が、テスト用サーバーに届きません。ページは固まったままです。待って、もう一度試して、ネットワークチームに電話します。
拒否されたなら、サーバーが動いていることが一秒でわかったはずです。沈黙は、何も教えてくれませんでした。
今日は、ファイアウォールが静かにも、はっきりにもなれる理由と、それを決めるものを学びます。
このレッスンのゴール
メモ
ファイアウォールのルールを書き、相手側に何が見えるかを説明できる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| ファイアウォール | どのパケットを通すか決めるルールの集まり | |
| チェーン | 順番に読まれるルールの列 | |
| ポリシー | どのルールにも当たらないパケットの扱い | |
| drop | パケットを、返事なしで捨てること | |
| reject | パケットを断り、送り主に知らせること | |
| フック | パケットの道のりで、チェーンが読まれる地点 | input |
学生が入力するセルは、このプレビューでは空白です。
チェーンは、ポリシー付きの列
ファイアウォールは、ルールをチェーンに入れておきます。パケットは、上から順にルールと照らされます。最初に当たったルールが決め、残りは読まれません。
どのルールにも当たらなければ、ポリシーが決めます。ここのゲートウェイのチェーンはポリシーがdropで、ルールが許したものだけを通します。
ゲートウェイのforwardチェーンを読む
sudo ip netns exec gw nft list chain inet filter forwardここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
例: そのチェーンを一行ずつ読む
| 行 | やさしく言うと |
|---|---|
| hook forward ... policy drop | 通り抜けるパケットを見て、ルールが許さないものは捨てる |
| ct state established,related accept | すでに開いている接続への返事を通す |
| iifname "to-lan" accept | LANのケーブルから入るものを、すべて通す |
学生が入力するセルは、このプレビューでは空白です。
一台の機器のルールでポートを捨てる
今度は、ゲートウェイではなく、LANの機器に、自分でルールを書きます。practice という専用のテーブルに入れ、何も保存しません。
まずテーブル、次にその機器に届くパケットを見る input フックのチェーン、最後にルールを一つ作ります。
LANの機器にテーブルを作る
sudo ip netns exec lan nft add table inet practiceここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
inputフックにチェーンを足す
sudo ip netns exec lan nft add chain inet practice guard '{ type filter hook input priority 0 ; policy accept ; }'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ポート8081を捨てるルールを足す
sudo ip netns exec lan nft add rule inet practice guard tcp dport 8081 dropここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ルールの無いポート80に聞く
sudo ip netns exec gw curl --noproxy '*' -sS -m 3 -o /dev/null -w '%{http_code}\n' http://10.0.0.2/ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ルールが捨てるポート8081に聞く
sudo ip netns exec gw curl --noproxy '*' -sS -m 3 http://10.0.0.2:8081/ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
rejectははっきりノーと言う
dropは返事をしないので、送り主はあきらめるまで待ちます。rejectは、すぐに拒否を返すので、送り主は一瞬でわかります。
dropは、外に対して静かです。rejectは、自分の同僚に親切で、故障が早く見つかります。
チェーンを空にする
sudo ip netns exec lan nft flush chain inet practice guardここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ポート8081を断るルールを足す
sudo ip netns exec lan nft add rule inet practice guard tcp dport 8081 reject with tcp resetここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
もう一度ポート8081をノックする
sudo ip netns exec gw nc -zv -w 2 10.0.0.2 8081ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
「塞いだポートは、いつも Connection refused と出る」と考える人が多いのですが、違います。出るのは、ファイアウォールがrejectしたときだけです。dropでは、送り主にはタイムアウトが見え、それは電源の切れた機器と同じに見えます。
最初に当たったルールが勝つ
ルールは上から読まれます。add で足したルールは一番下に入り、insert で足したルールは一番上に入ります。
ここで、ゲートウェイ(10.0.0.1)の一台だけをポート8081に通し、ほかの全員は断られたままにします。
rejectの上にacceptを差し込む
sudo ip netns exec lan nft insert rule inet practice guard ip saddr 10.0.0.1 tcp dport 8081 acceptここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ゲートウェイから8081にもう一度聞く
sudo ip netns exec gw curl --noproxy '*' -sS -m 3 http://10.0.0.2:8081/ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
練習用のテーブルを消す
sudo ip netns exec lan nft delete table inet practiceここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
発展: 当たった回数を数える
テーブルとチェーンをもう一度作ります。ルール tcp dport 8081 counter reject with tcp reset を足し、nc でポート8081を3回ノックします。
sudo ip netns exec lan nft list table inet practice でテーブルを読みましょう。カウンターは何と言っていますか。ネットワークチームがカウンターを欲しがるのはなぜでしょう。最後にテーブルを消します。