ネットワーク●●○○○

ファイアウォール

Firewall ・ ふぁいあうぉーる

通信をヘッダとルールで照合し、許可か破棄かを決める関所。境界防御の基本装置。

✦ 30秒で試す — 航海行きは通れたのに、帰りの返事だけが門前払い管理者の接続はどうなる?予想してみる

概要

ファイアウォールは、ネットワークの出入り口に立って通信を1つずつ検査し、あらかじめ書いたルールに照らして「通す」か「捨てる」かを決める仕組みです。名前の由来は建物の延焼を防ぐ「防火壁」で、信頼できる内側のネットワークと、何が来るか分からない外側のインターネットの間に置かれる関所にあたります。専用のハードウェア製品もあれば、OS に組み込まれたソフトウェア(Linux の nftables や iptables、Windows Defender ファイアウォール)もあり、クラウドのセキュリティグループのような仮想的なものもあります。

判断の材料は、パケットの先頭に付いている「ヘッダ」です。送信元と宛先の IPアドレス、送信元と宛先のポート番号、プロトコル(TCP か UDP か)の5つを組にして、「外から Web サーバの 443 番へは許可」「外から 22 番(SSH)へは管理者の IP だけ許可」「それ以外は捨てる」のようにルールを書きます。クラウドで仮想マシンを立てたとき最初に設定するセキュリティグループも、本質はこのルール集です。

「サーバは動いているのに外から接続できない」というトラブルの原因の定番がファイアウォールです。攻撃を防ぐ壁であると同時に、自分の通信も遮る壁になるため、ルールがどの順に・何を見て判定されるのかを知っておくと、デバッグの速さが大きく変わります。

なぜ生まれたか

インターネットの原型である ARPANET は、互いに顔の見える研究機関同士のネットワークとして設計されていて、「悪意のある通信を弾く」という発想がほとんどありませんでした。1988年の Morris ワームが数千台のマシンを止めたことで、ネットワークにつながること自体がリスクだと広く知られるようになります。とはいえ回線を切るわけにはいきません。「つながったまま、危ない通信だけを選り分けたい」という要求が生まれました。

最初に形になったのは、ルータを通るパケットのIPアドレスとポート番号を見て通すか捨てるかを決めるパケットフィルタです(1980年代末に DEC などで研究されました)。ただ、ヘッダだけを1枚ずつ見る方式には「内側から始めた通信の戻り」を安全に通せないという弱点がありました(詳細で説明します)。これを接続の状態を覚えることで解決したのがステートフルインスペクションで、1994年に Check Point が製品化して広まりました。「境界に検問所を1つ置けば、内側の無数のマシンを個別に守らなくてよい」という境界防御の考え方は管理の手間の面で非常に合理的で、以後30年にわたり企業ネットワークの安全の土台になりました。

詳細

パケットのどこを見るか

TCP/IP のパケットには、配達に必要な情報がヘッダとして付いています。ファイアウォール(ここでは最も基本的なパケットフィルタ型)が見るのは、このうち「送信元 IP・送信元ポート番号・宛先 IP・宛先ポート番号・プロトコル」の5つ組です。中身(HTTP のリクエストや、その中に紛れ込んだ攻撃文字列)は見ません。ルールは「この5つ組の条件に当てはまったら、許可する/破棄する」という行の並びです。

ルールは上から照合し、最初に一致した行で決まる

届いたパケットはルールの一覧と上から順に照合され、最初に一致した行のアクションがそのまま適用されます(first match)。どの行にも当てはまらなかったときの既定の動作は「すべて破棄」にするのが原則です。必要なものだけを明示的に許可するこの方針(既定拒否)は、最小権限の原則のネットワーク版といえます。

外からの通信HTTPS 443宛て管理者の SSH 22DB 5432宛てファイアウォール上から順に照合 → 最初の一致で決定1. 許可: 任意 → Web:4432. 許可: 管理者IP → 任意:223. 拒否: 任意 → 任意:22既定: どれにも当たらなければ破棄内部ネットワーク許可破棄(送り主には何も返さない)2 と 3 を入れ替えると管理者も 22 で止まる
ファイアウォールの判定 — ルールに上から照合し、最初に一致した行で決まる。どれにも当たらなければ既定で破棄する

この「最初の一致で決まる」性質のせいで、ルールの順序そのものが意味を持ちます。広い拒否ルールを狭い許可ルールより上に置くと、許可ルールは一度も使われなくなります(「影になったルール」と呼ばれる、設定ミスの代表例です)。ルールが数百行に育った現場では、「どの行が実際に効いているか」を誰も説明できなくなりがちで、定期的な棚卸しと、変更前に「この5つ組はどの行に当たるか」を試す仕組みが欠かせません。

破棄の仕方にも2種類あります。黙って捨てる「drop」と、「届かない」と返事をする「reject」(TCP なら RST、あるいは ICMP の到達不能)です。drop は攻撃者に情報を与えませんが、正当な利用者のアプリはタイムアウトまで待たされます。社内向けには reject、外向けには drop、と使い分けることが多いです。

ステートフルインスペクション — 「行き」を覚えて「帰り」を通す

ヘッダを1枚ずつ見るだけのフィルタ(ステートレス)には、根本的な弱点があります。内側の PC が外の Web サイトを見に行くと、応答のパケットが外から内へ入ってきます。この応答の送信元ポートはサーバの 443 で決まっていますが、宛先ポートは PC が接続のたびに選ぶ使い捨ての番号(エフェメラルポート。OS によって 32768〜60999 や 49152〜65535 などの範囲から選ばれる)で、毎回変わります。静的なルールで応答を通そうとすると、「宛先ポート 1024 以上は全部許可」や「送信元ポートが 443 なら許可」のような広い穴を開けるしかありません。後者なら、攻撃者は送信元ポートを 443 に偽るだけで内側のどのポートにも届いてしまいます。

これを解決したのがステートフルインスペクションです。内側から始まった通信を見たら、その5つ組を接続テーブルに記録し、外から来たパケットがテーブルのどれかの「帰り」と一致すれば、ルールを見るまでもなく通します。一致しなければ通常どおりルールで照合します。TCP なら SYN から FIN までの状態を追い、状態を持たない UDP は「最後の通信から一定時間」を擬似的な接続とみなします。行きを覚えて帰りを通すという構造は NAT の変換テーブルとそっくりで、実際に多くの機器では両者が一体で実装されています。現在「ファイアウォール」と呼ばれるものの大半はこのステートフル型です。

攻撃者Webサーバファイアウォール内側のPC攻撃者Webサーバファイアウォール内側のPC接続テーブルに行きを記録テーブルの帰りと一致テーブルに無い → ルールで照合 → 破棄10.0.0.30:53712 → 93.184.216.34:443そのまま転送93.184.216.34:443 → 10.0.0.30:53712通す送信元ポートを443に偽って53712宛て

ルールの順序と、ステートフルの意味を部品で確かめてください。外から来る3種類のパケットを流し、ルールの行をつかんで並べ替えると、どの行で決まるかが変わります。内側の PC から Web を見に行くと、ステートフルかどうかで「帰り」の運命が分かれます。

⚡ 体験: ファイアウォールのルールを並べ替えて、パケットを流す
方式
外(インターネット)内側のネットワークファイアウォール上から順に照合⋮⋮許可任意 → Web:443⋮⋮拒否任意 → 任意:22⋮⋮許可198.51.100.8 → 任意:22既定: どれにも当たらなければ破棄ステートレス: 接続を覚えない閲覧者203.0.113.50管理者198.51.100.8攻撃者203.0.113.66外の Web サイト93.184.216.34Web サーバ10.0.0.10DB10.0.0.20:5432内側の PC10.0.0.30→ :443→ :22→ :5432Web を見るパケットを運ぶと、ここにヘッダが出ます送信元 IP—送信元ポート—宛先 IP—宛先ポート—種類—
見つけたこと 0 / 4: まだ

外の3人がパケットを送ろうとしています。左のパケットをつかんで、ファイアウォールへ運んでください(タップでも送れます)。ルールが上から1行ずつ照合されます。

クラウドでの姿 — セキュリティグループとネットワーク ACL

クラウドのファイアウォールは、この2つの型をそのまま並べて提供しています。AWS を例にとると、仮想マシンの単位に付けるセキュリティグループはステートフルで、書けるのは許可ルールだけ、順序はなく「どれか1つに当たれば許可」です。一方、サブネットの単位に付けるネットワーク ACL はステートレスで、番号の小さい順に照合する first match です。ネットワーク ACL で戻りの通信を忘れて通信が片道になる、というのは初めて触る人がよく踏む罠で、まさにエフェメラルポートの問題そのものです。Kubernetes の NetworkPolicy のように、コンテナ単位で同じ考え方を適用する仕組みもあります。

境界防御の設計と DMZ

ファイアウォールを使った典型的な構成が、ネットワークを「外部」「DMZ」「内部」の3層に分ける設計です。DMZ(非武装地帯)は外に公開するサーバ(Web サーバやリバースプロキシなど)を置く中間の区画で、外からは DMZ までしか届かず、DMZ から内部へも必要最小限の通信しか許しません。公開サーバが乗っ取られても、被害が内部まで一気に及ばないように壁を段階的に築くわけです。

入ってくる通信(ingress)だけでなく、出ていく通信(egress)を絞ることも重要です。侵入されたサーバが外の攻撃者のサーバへ接続して指示を受けたり、データを持ち出したりするのは、出ていく方向の通信だからです。「DB サーバは外へ出ていく必要がない」なら、出口も閉じておきます。破棄したパケットのログは、ポートスキャンや侵入の試みを見つける監視の材料にもなります。

ただし、パケットフィルタが見るのはヘッダまでです。443 番を通る「形式の正しい HTTPS リクエスト」に載った SQLインジェクションや XSS は素通りします。アプリケーション層の中身まで検査するのは WAF の役割で、ファイアウォールと WAF は守る層の違う補完関係にあります。また、大量の通信で押しつぶす DDoS 攻撃には、接続テーブルを持つステートフル型ほど自分自身が先に溢れやすいという弱みもあり、上流の回線事業者や CDN での緩和と組み合わせます。

「境界の内側は安全」という前提の崩壊

クラウドとリモートワークの普及で、「壁の内側は信頼できる」という境界防御の大前提が揺らぎました。社内ネットワークに入り込んだ攻撃者が内部で自由に横移動する被害や、VPN 装置の脆弱性を突かれて境界ごと突破される事故が相次いだためです。そこで「ネットワーク上の場所を信頼の根拠にせず、すべてのアクセスを毎回確かめる」ゼロトラストの考え方が広まりました。

とはいえ、ゼロトラストはファイアウォールを不要にするものではありません。境界のファイアウォールで大まかな壁を築きつつ、サーバ単位・コンテナ単位の細かい通信制御(マイクロセグメンテーション)を重ねる多層防御がいまの標準です。「既定拒否・必要最小限の許可・層を重ねる」というファイアウォールが確立した原則は、形を変えて生き続けています。

試問

外の3人(閲覧者・管理者・攻撃者)と内側の PC のパケットを、ファイアウォールへ運んで流せます。ルールの行はつかんで並べ替えられ、方式は「ステートレス(1枚ずつ見る)」と「ステートフル(接続を覚える)」を切り替えられます。攻撃者は送信元ポートを 443 に偽り、Web サイトからの返事のふりをして DB(5432 番)を狙っています。

✦ 命題挑戦中

設定を1つに決め、その設定のまま、管理者の SSH と PC の帰りを通し、送信元を偽った攻撃者だけを止めよ

  • 管理者(198.51.100.8)の SSH(:22)が Web サーバに届く
  • 内側の PC が Web を見て、帰りのパケットを受け取る
  • 送信元ポートを 443 に偽った攻撃者のパケットが捨てられる
⚡ 体験: 1つの設定で、通すべきものだけを通す
方式
外(インターネット)内側のネットワークファイアウォール上から順に照合⋮⋮許可任意 → Web:443⋮⋮拒否任意 → 任意:22⋮⋮許可198.51.100.8 → 任意:22既定: どれにも当たらなければ破棄ステートレス: 接続を覚えない閲覧者203.0.113.50管理者198.51.100.8攻撃者203.0.113.66外の Web サイト93.184.216.34Web サーバ10.0.0.10DB10.0.0.20:5432内側の PC10.0.0.30→ :443→ :22→ :5432Web を見るパケットを運ぶと、ここにヘッダが出ます送信元 IP—送信元ポート—宛先 IP—宛先ポート—種類—

外の3人がパケットを送ろうとしています。左のパケットをつかんで、ファイアウォールへ運んでください(タップでも送れます)。ルールが上から1行ずつ照合されます。