第2部 攻撃と防御の実践
第6章 ネットワーク防御とTLSの深掘り
通信は「見えない配管」ではありません。盗聴・改ざん・なりすましが起きる現場です。この章では、ネットワーク層の脅威を整理し、TLSの中身とセグメンテーションの設計判断まで一段深く踏み込みます。
🎯 この章で学ぶこと
- ネットワーク層で起きる脅威(盗聴・改ざん・なりすまし・中間者攻撃)の正体
- セグメンテーションで侵入後の横展開を止める設計
- TLSハンドシェイクの中身と前方秘匿性、TLS 1.2と1.3の違い
- ファイアウォール・IDS・IPS・WAFの役割分担と、Pythonでの証明書検証
6.1 ネットワーク層の脅威
アプリケーションがどれほど堅牢でも、その間を流れるパケットが平文であれば、経路上の誰かに中身を読まれ、書き換えられます。ネットワーク層の脅威は、大きく4つに整理できます。
| 脅威 | 何が起きるか | CIAのどれを侵すか | 代表的な防御 |
|---|---|---|---|
| 盗聴(Sniffing) | 経路上でパケットを読み取られる | 機密性 | 通信の暗号化(TLS) |
| 改ざん(Tampering) | 通信内容を書き換えられる | 完全性 | メッセージ認証・TLS |
| なりすまし(Spoofing) | 別のホストやユーザーに化ける | 機密性・完全性 | 証明書による相手認証 |
| 中間者攻撃(MITM) | 通信の途中に割り込み両者に成りすます | 機密性・完全性 | サーバー証明書検証・ピンニング |
特に危険なのが中間者攻撃(Man-in-the-Middle、MITM)です。攻撃者はクライアントとサーバーの間に入り込み、クライアントには「自分がサーバーだ」、サーバーには「自分がクライアントだ」と振る舞います。ARPスプーフィング、不正なWi-Fiアクセスポイント、DNSの汚染など、割り込みの入口はさまざまです。暗号化していない通信、あるいは証明書検証を省いた暗号化通信は、この攻撃に対して無力です。
かつては境界の内側は信頼できるとされました。しかし内部からの盗聴、持ち込み端末、侵害された端末を踏み台にした攻撃を考えれば、内部通信こそ暗号化すべきです。第3章のゼロトラストは、まさに「ネットワークの位置で信頼を決めない」という発想でした。
6.2 セグメンテーション — 横展開を止める
攻撃者が最初に侵入する地点(たとえばフィッシングで乗っ取った1台の端末)は、多くの場合、本当に狙いたい資産(顧客DBや基幹サーバー)とは別の場所です。そこから内部を渡り歩いて目的地に近づく動きを横展開(lateral movement)と呼びます。セグメンテーションは、この横展開を難しくするための分割です。
VLANとサブネット分割
ネットワークを用途ごとに分けます。たとえば「業務端末」「サーバー」「来客用Wi-Fi」「開発環境」を別セグメントにし、セグメント間の通信はファイアウォールやアクセス制御リストで必要最小限だけ許可します。来客用Wi-Fiから基幹サーバーへ到達できない、という当たり前の状態を意図的に作ります。
マイクロセグメンテーション
従来のセグメント分割は「ネットワークの区画」単位でしたが、マイクロセグメンテーションはワークロード(サーバーやコンテナ)単位で通信を制御します。「Webサーバーはアプリサーバーの8080番にだけ接続できる。DBサーバーはアプリサーバーからの5432番だけ受け付ける」というように、必要な経路だけを開けます。設計の原則は最小到達性——到達できる先を必要な範囲に絞ることです。
「侵入される前提」で設計するとき、セグメンテーションは決定的な役割を果たします。1台が乗っ取られても、そこから到達できる範囲が狭ければ、被害はそのセグメントに封じ込められます。逆に、フラットで何にでも到達できるネットワークは、1台の侵害が全社の侵害に直結します。「もし目の前の端末が攻撃者に握られていたら、そこから何に触れるか?」を各セグメントで自問してください。
6.3 TLSハンドシェイクの中身
TLS(Transport Layer Security)は、盗聴・改ざん・なりすましをまとめて防ぐための仕組みです。中身をブラックボックスにせず、ハンドシェイクで何が起きているかを理解しておくと、証明書エラーやプロトコル選択の判断が的確になります。
TLS 1.2の簡略化した流れは次の通りです。
Client Server
| ClientHello (対応する暗号スイート一覧) |
| -----------------------------------> |
| ServerHello (選んだ暗号スイート) |
| Certificate (サーバー証明書) |
| ServerKeyExchange (ECDHE公開値) |
| <----------------------------------- |
| ClientKeyExchange (ECDHE公開値) |
| Finished |
| -----------------------------------> |
| Finished |
| <----------------------------------- |
| === 以降はセッション鍵で暗号化 === |
鍵交換(ECDHE)と前方秘匿性
現代のTLSはECDHE(楕円曲線ディフィー・ヘルマン鍵共有・一時鍵)で共通鍵を作ります。ポイントは「一時(Ephemeral)」の部分です。ハンドシェイクごとに使い捨ての鍵ペアを生成するため、たとえ後日サーバーの秘密鍵が漏れても、過去に記録された通信を復号できません。この性質を前方秘匿性(PFS、Perfect Forward Secrecy)と呼びます。RSA鍵交換にはこの性質がないため、現在は非推奨です。
サーバー証明書の検証
証明書は「この公開鍵は確かにこのドメインのものだ」と、信頼された認証局(CA)が署名で保証するものです。クライアントは、(1)証明書の署名を信頼済みCAでたどれるか、(2)有効期限内か、(3)接続先ホスト名が証明書のドメインと一致するか(SAN)、を検証します。この検証こそがMITMを防ぐ要です。暗号化していても検証しなければ、攻撃者の証明書を受け入れてしまいます。
TLS 1.2と1.3の違い
| 項目 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| ハンドシェイクの往復 | 2往復(2-RTT) | 1往復(1-RTT、再開時は0-RTTも) |
| 鍵交換 | RSAも選べてしまう | (EC)DHEのみ=常に前方秘匿性 |
| 暗号スイート | 古い危険な方式も残る | 脆弱な方式を廃止・簡素化 |
| ハンドシェイクの暗号化 | 一部平文 | 証明書などを暗号化 |
実務ではTLS 1.2以上のみを許可し、TLS 1.3を優先、SSLv3やTLS 1.0/1.1は無効化するのが基本です。
6.4 ファイアウォール・IDS・IPS・WAFの役割分担
「どれを入れればいい?」ではなく「それぞれ何を見て、何を止めるか」を理解すると、多層防御として組み合わせられます。
| 機器・機能 | 主に見る層 | 判断の基準 | できること・限界 |
|---|---|---|---|
| ファイアウォール | L3/L4(IP・ポート) | 送信元/宛先IP・ポート・プロトコル | 通信の可否を制御。中身の攻撃は見ない |
| 次世代FW(NGFW) | L3〜L7 | アプリ識別・ユーザー・脅威情報 | アプリ単位の制御。設定が複雑 |
| IDS | L3〜L7 | 既知の攻撃パターン・異常 | 検知して警告するが止めない |
| IPS | L3〜L7 | 既知の攻撃パターン・異常 | インラインで遮断する。誤検知で正常通信を止める危険 |
| WAF | L7(HTTP) | SQLi・XSS等のWeb攻撃パターン | Webアプリを守る。ロジックの欠陥は防げない |
IDS(検知)とIPS(防御)の違いは「止めるかどうか」です。IPSはインラインに配置して攻撃を遮断できますが、誤検知が業務停止に直結します。WAFはHTTPの中身を見てWeb特有の攻撃を弾きますが、あくまで一時しのぎであり、アプリ本体の修正(第4章)を置き換えるものではありません。
脆弱性が見つかって修正リリースまで時間がかかるとき、WAFのルールで攻撃パターンを一時的に遮断できます。これは有効な緊急対応です。ただし恒久対策はコード修正であり、WAFに頼り切ってはいけません。攻撃者はWAFの回避手法(エンコーディング等)も研究しています。
6.5 実務の勘所
- 不要ポートを閉じる — 開いているポートは攻撃面です。使っていないサービスは止め、待ち受けポートを最小化します。「デフォルトで全開、必要なものだけ閉じる」ではなく「デフォルトで全閉、必要なものだけ開ける」が原則です。
- egress filtering(出口制御) — 入ってくる通信だけでなく、出ていく通信も制御します。マルウェアは外部のC2サーバーへ通信して指令を受けたり、データを持ち出したりします。出口を絞れば、侵入されても外部との通信を断ち、情報流出やリモート操作を阻害できます。見落とされがちですが効果が大きい対策です。
- 証明書ピンニング — モバイルアプリなどで、接続先の証明書(または公開鍵)をあらかじめ固定し、それ以外を拒否します。不正なCAが発行した証明書によるMITMを防げますが、証明書更新時の運用に注意が必要です。
- VPNの限界とゼロトラスト — VPNは「トンネルの中に入れば内部ネットワークに広くアクセスできる」モデルで、一度侵入されると横展開を許しがちです。近年は「接続元の位置で信頼せず、リクエストごとに認証・認可する」ゼロトラスト(第3章)へ移行が進んでいます。
「証明書エラーが出て面倒だから」と検証を無効化するのは、TLSの意味を根こそぎ捨てる行為です。暗号化はされても、相手が本物かを確認しなくなるため、MITMに対して丸裸になります。エラーが出たら、正しい原因(期限切れ・自己署名・ホスト名不一致・CA未登録)を突き止めて解消してください。開発環境でも安易に無効化する癖をつけると、本番にそのまま混入します。
6.6 Pythonで証明書検証を確認する
Pythonの標準ライブラリsslを使って、TLS接続とサーバー証明書の中身を確認してみましょう。既定で検証が有効になっている点に注目してください。
import ssl
import socket
hostname = "example.com"
# 既定のコンテキストは「証明書検証あり・ホスト名チェックあり」
context = ssl.create_default_context()
with socket.create_connection((hostname, 443), timeout=5) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as tls:
print("プロトコル:", tls.version()) # 例: TLSv1.3
print("暗号スイート:", tls.cipher()[0])
cert = tls.getpeercert()
print("発行先:", dict(x[0] for x in cert["subject"]))
print("発行者:", dict(x[0] for x in cert["issuer"]))
print("有効期限:", cert["notAfter"])
もしホスト名が証明書と一致しなかったり、期限切れだったりすると、wrap_socketの時点でssl.SSLCertVerificationErrorが送出されます。これは「バグ」ではなく正しく守られている証拠です。次のような無効化は、緊急のデバッグ以外で書いてはいけません。
# 絶対に本番で使わないこと(MITMに対して無防備になる)
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE # 検証を捨てている
同じことはrequestsライブラリのverify=Falseにも当てはまります。警告が出るのは、それが危険だからです。証明書の問題は「無効化」ではなく「解決」してください。
まとめ
- ネットワーク層の脅威は盗聴・改ざん・なりすまし・中間者攻撃に整理でき、暗号化と相手認証で守る
- セグメンテーション(VLAN・マイクロセグメンテーション)は侵入後の横展開を封じ込める設計上の要
- TLSはECDHEによる前方秘匿性と証明書検証でMITMを防ぐ。TLS 1.3を優先し古いバージョンは無効化する
- FW・IDS・IPS・WAFは見る層と止め方が違う。組み合わせて多層防御を作る
- 出口制御と証明書検証は地味だが効果大。verifyの無効化は絶対に避ける
練習問題
あるチームが「通信はHTTPSにしているので中間者攻撃は心配ない」と言っています。しかし彼らのクライアントは接続エラーを避けるため証明書検証を無効化していました。この構成にどんな問題があるか、MITMの観点で説明してください。
解答を見る
証明書検証を無効化した時点で、HTTPSの防御はほぼ意味を失います。TLSは「暗号化」と「相手が本物かの認証」の2本柱で成り立っており、検証を切ると後者が失われます。攻撃者は自分の証明書を提示してクライアントとの間にTLSセッションを張り、内容を復号・改ざんしたうえで本物のサーバーへ中継できます。通信は暗号化されて見えますが、暗号化している相手が攻撃者という状態です。正しい対応は、エラーの根本原因(期限切れ・自己署名・ホスト名不一致・CA未登録)を特定して解消することです。
フラットな(全端末が相互に到達できる)社内ネットワークで、1台の業務端末がマルウェアに感染しました。この構成が被害を拡大させやすい理由と、セグメンテーションによってどう改善できるかを述べてください。
解答を見る
フラットなネットワークでは、感染端末から他の端末やサーバーへ制限なく到達できるため、攻撃者は容易に横展開し、認証情報を集めながら基幹サーバーや顧客DBへ近づけます。1台の侵害が全体の侵害に直結します。
セグメンテーションでネットワークを用途別に分け、セグメント間の通信を必要最小限に絞れば(最小到達性)、感染はそのセグメントに封じ込められます。マイクロセグメンテーションでワークロード単位に「Webサーバーはアプリサーバーの特定ポートにだけ接続可」と制御すれば、感染端末が到達できる範囲がさらに狭まり、被害を局所化できます。
前方秘匿性(PFS)とは何か、そしてなぜ「一時鍵(Ephemeral)」であることが重要なのかを説明してください。
解答を見る
前方秘匿性とは、将来サーバーの長期秘密鍵が漏えいしても、過去に記録された通信を復号できないという性質です。ECDHEはハンドシェイクごとに使い捨ての鍵ペア(一時鍵)を生成してセッション鍵を導出し、その一時鍵はセッション終了後に破棄されます。セッション鍵はサーバーの長期秘密鍵からは復元できないため、長期鍵が後日漏れても過去の通信は守られます。対照的に、RSA鍵交換ではセッション鍵がサーバーの秘密鍵で保護されるため、秘密鍵が漏れると過去に盗聴・記録された全通信を復号され得ます。だからこそ一時鍵による鍵交換が重要で、TLS 1.3では(EC)DHEのみが使われます。