Skip to content
Published on

Wiresharkとネットワークセキュリティ完全ガイド:パケットスニッフィングから侵入検知まで開発者のための実践セキュリティ

Authors

1. なぜ開発者(かいはつしゃ)にネットワークセキュリティが重要(じゅうよう)なのか

セキュリティは選択(せんたく)ではなく必須(ひっす)

2025年のIBM Cost of a Data Breach Reportによると、データ漏洩(ろうえい)事故の平均(へいきん)コストは488万ドルに達(たっ)しています。これは前年比(ぜんねんひ)10%上昇(じょうしょう)した数値(すうち)であり、史上最高値(しじょうさいこうち)です。さらに衝撃的(しょうげきてき)なのは、セキュリティ事故の60%以上がアプリケーションレイヤーで発生(はっせい)しているという点です。

OWASP Top 10 2025を見ると、開発者が直接関与(かんよ)すべき脆弱性(ぜいじゃくせい)がほとんどです:

順位(じゅんい)脆弱性開発者関連度(かんれんど)
1Broken Access Control非常(ひじょう)に高い
2Cryptographic Failures高い
3Injection (SQL, XSS, LDAP)非常に高い
4Insecure Design非常に高い
5Security Misconfiguration高い
6Vulnerable Components高い
7Authentication Failures非常に高い
8Data Integrity Failures高い
9Logging/Monitoring Failures中程度(ちゅうていど)
10SSRF (Server-Side Request Forgery)非常に高い

2026年のサイバー脅威環境(きょういかんきょう)

2026年はサイバーセキュリティ史上(しじょう)最も危険(きけん)な年として記録(きろく)されています。米(べい)イラン紛争(ふんそう)の激化(げきか)に伴(ともな)い、国家(こっか)支援ハッキンググループの活動(かつどう)が700%以上急増(きゅうぞう)しました。主なトレンド:

  • APT グループ活動急増: 国家支援グループが金融(きんゆう)、エネルギー、医療(いりょう)インフラを集中攻撃(こうげき)
  • サプライチェーン攻撃拡大(かくだい): npm、PyPIなどのパッケージリポジトリを通じたマルウェア配布(はいふ)が3倍増加
  • AI基盤攻撃: LLMを活用(かつよう)したフィッシングメール、自動化(じどうか)された脆弱性スキャニングが日常化
  • ランサムウェア進化(しんか): 二重恐喝(きょうかつ)(データ流出(りゅうしゅつ)+暗号化(あんごうか))戦略が標準化

DevSecOpsとShift-Leftセキュリティ

従来(じゅうらい)のセキュリティは開発完了後のテスト段階(だんかい)で実施(じっし)されていました。しかしShift-Leftアプローチは開発初期段階からセキュリティを統合(とうごう)します。

従来のアプローチ:
  設計 → 開発 → テスト → [セキュリティテスト] → デプロイ
  ← 問題発見時のコストが指数的に増加 →

Shift-Left:
  [セキュリティ設計][セキュアコーディング][セキュリティテスト][セキュリティモニタリング]
  ← 早期発見でコスト削減 →

開発者がネットワークパケットを読めると:

  • API呼び出しで機密(きみつ)データが平文(ひらぶん)で送信されていないか直接確認可能
  • TLS設定エラーをデプロイ前に発見可能
  • サードパーティライブラリの怪しいネットワーク活動を検知可能
  • パフォーマンスボトルネックとセキュリティ脆弱性を同時に診断(しんだん)可能

2. Wireshark完全征服(せいふく)

2-1. インストールと初期設定(しょきせってい)

macOS:

brew install --cask wireshark

Ubuntu/Debian:

sudo apt update
sudo apt install wireshark
sudo usermod -aG wireshark $USER
# ログアウト後、再ログインが必要

Windows:

公式(こうしき)サイト(wireshark.org)からインストーラーをダウンロードします。インストール時にNpcapも一緒にインストールしてください。

2-2. インターフェース構成(こうせい)

Wiresharkのメイン画面は3つのパネルで構成されています:

  1. パケットリストパネル(上段):キャプチャされた全パケットの要約情報
  2. パケット詳細(しょうさい)パネル(中段):選択したパケットのプロトコル階層別詳細情報
  3. パケットバイトパネル(下段):生のバイナリデータ(Hex + ASCII)

2-3. Capture Filters vs Display Filters

この2つのフィルタはWiresharkを効果的に使用するための核心(かくしん)です。最も重要な違いは適用(てきよう)タイミングです。

区分(くぶん)Capture FilterDisplay Filter
適用タイミングキャプチャ開始前キャプチャ後(リアルタイム変更可能)
文法BPF (Berkeley Packet Filter)Wireshark独自文法
パフォーマンス高い(カーネルレベルフィルタリング)低い(全パケットキャプチャ後フィルタリング)
柔軟性(じゅうなんせい)制限的(せいげんてき)非常に柔軟
host 192.168.1.1ip.addr == 192.168.1.1
port 80tcp.port == 80
tcp and port 443tcp.port == 443

Capture Filter例:

host 10.0.0.1
port 443
net 192.168.0.0/24
tcp and port 80
not arp

Display Filter例:

ip.addr == 10.0.0.1
tcp.port == 443
http.request.method == "GET"
dns.qry.name contains "google"

2-4. 必須Display Filter 30選(せん)

番号フィルタ用途(ようと)
1ip.addr == 10.0.0.1特定IP フィルタリング
2tcp.port == 443HTTPSトラフィック
3tcp.port == 80HTTPトラフィック
4http.request.method == "POST"POSTリクエストのみ
5http.request.method == "GET"GETリクエストのみ
6dns.qry.name contains "example"特定ドメインDNSクエリ
7tcp.flags.syn == 1 and tcp.flags.ack == 0SYNスキャン検知
8tcp.analysis.retransmissionTCP再送検知
9tcp.analysis.duplicate-ack重複ACK検知
10tcp.analysis.zero-windowZero Window検知
11http.response.code == 500サーバーエラー応答
12http.response.code >= 400全エラー応答
13tls.handshake.type == 1TLS Client Hello
14tls.handshake.type == 2TLS Server Hello
15arpARPパケットのみ
16icmpICMP(ping)パケットのみ
17dnsDNSパケットのみ
18tcp.analysis.flagsTCP問題のあるパケット
19http.cookie contains "session"セッションCookie含むリクエスト
20frame.time_delta > 11秒以上遅延パケット
21tcp.len > 0データのあるTCPパケット
22ip.src == 10.0.0.0/8内部ネットワークソース
23not arp and not dnsARP、DNS除外
24http.host contains "api"API呼び出しフィルタリング
25tcp.stream eq 5特定TCPストリーム
26frame.len > 1500MTU超過(ちょうか)パケット
27http.content_type contains "json"JSONレスポンス
28tcp.analysis.lost_segment損失(そんしつ)セグメント
29ip.ttl < 10低いTTL(ルーティング問題)
30tls.handshake.extensions_server_nameSNIベースフィルタリング

2-5. Follow Stream機能(きのう)

TCP Stream追跡はWiresharkの最も強力な機能の一つです:

  1. パケットを右クリックします
  2. Follow > TCP Stream を選択
  3. その接続の全データフローを確認できます
# TCP Stream例(HTTPリクエスト/レスポンス)
GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session=abc123; HttpOnly; Secure

[Response Body]

HTTP StreamはHTTP/2マルチプレキシング環境で個別HTTPトランザクションを追跡する際に有用です。

2-6. Statisticsメニュー活用

Conversations:どのIP間で最もトラフィックが往来しているか確認

Source          Destination     Packets   Bytes
10.0.0.5        52.85.132.99    1,234     890KB
10.0.0.5        142.250.80.46   567       234KB
10.0.0.5        104.18.32.68    345       156KB

Protocol Hierarchy:プロトコル別トラフィック比率確認

Ethernet (100%)
  ├── IPv4 (98.5%)
  │   ├── TCP (85.2%)
  │   │   ├── TLS (62.1%)
  │   │   ├── HTTP (15.3%)
  │   │   └── Other (7.8%)
  │   ├── UDP (12.8%)
  │   │   ├── DNS (8.2%)
  │   │   └── QUIC (4.6%)
  │   └── ICMP (0.5%)
  └── ARP (1.5%)

I/O Graphs:時間帯別トラフィックパターンを可視化します。DDoS攻撃やトラフィックスパイクの検知に必須です。

2-7. プロファイル設定とカラムカスタム

プロファイルを作成すると用途別に最適化された環境を切り替えられます:

プロファイル例:
  - Default: 一般分析
  - Security: セキュリティ分析(色規則、セキュリティ関連カラム)
  - Performance: パフォーマンス分析(遅延時間、再送カラム)
  - DNS: DNS分析専用

便利なカスタムカラム:

  • Delta Time:前パケットとの時間差
  • TCP Stream Index:ストリーム番号
  • HTTP Host:HTTPリクエストのHostヘッダー
  • TLS SNI:TLS Server Name Indication

3. tcpdump実践(じっせん)(サーバー環境)

3-1. 基本文法(きほんぶんぽう)とBPFフィルタ

tcpdumpはサーバーでGUIなしにパケットをキャプチャするツールです。WiresharkとBPF(Berkeley Packet Filter)文法が同じです。

基本構造:

tcpdump [オプション] [BPFフィルタ式]

主要(しゅよう)オプション:

-i eth0        # インターフェース指定
-w output.pcap # ファイルに保存
-r input.pcap  # ファイル読み込み
-c 100         # パケット100個のみキャプチャ
-n             # DNS逆引き無効化(速度向上)
-nn            # ポート番号も名前変換しない
-v / -vv / -vvv  # 詳細度増加
-X             # Hex + ASCII出力
-A             # ASCIIのみ出力
-s 0           # 全パケットキャプチャ(デフォルト: 262144 bytes)
-tttt          # タイムスタンプを読みやすい形式で

3-2. 実践コマンド20選

番号コマンド用途
1sudo tcpdump -i eth0基本キャプチャ
2sudo tcpdump -i eth0 -w capture.pcapファイルに保存
3sudo tcpdump -i eth0 host 10.0.0.1特定ホスト
4sudo tcpdump -i eth0 port 443特定ポート
5sudo tcpdump -i eth0 src 10.0.0.1ソースIPフィルタ
6sudo tcpdump -i eth0 dst port 80宛先ポートフィルタ
7sudo tcpdump -i eth0 net 192.168.0.0/24サブネットフィルタ
8sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'SYNパケットのみ
9sudo tcpdump -i eth0 -c 1000 -w sample.pcap1000個のみキャプチャ
10sudo tcpdump -i eth0 -nn port 53DNSトラフィック
11sudo tcpdump -i eth0 icmpICMP(ping)のみ
12sudo tcpdump -i eth0 'port 80 and host 10.0.0.1'複合フィルタ
13sudo tcpdump -i eth0 -A port 80HTTP内容表示
14sudo tcpdump -i eth0 'tcp[32:4] = 0x47455420'GETリクエストのみ
15sudo tcpdump -i eth0 greater 10001000バイト超過
16sudo tcpdump -i eth0 arpARPパケットのみ
17sudo tcpdump -i eth0 -tttt -c 50 port 443タイムスタンプ付き
18sudo tcpdump -i any port 8080全インターフェース
19sudo tcpdump -i eth0 not port 22SSH除外
20sudo tcpdump -i eth0 -G 3600 -w 'capture_%Y%m%d_%H.pcap'時間別ローテーション

3-3. リモートサーバーキャプチャ → Wireshark分析

サーバーでキャプチャしたpcapファイルをローカルに持ってきてWiresharkで分析するワークフロー:

# 1. サーバーでキャプチャ
ssh user@server 'sudo tcpdump -i eth0 -c 5000 -w /tmp/capture.pcap port 443'

# 2. ローカルにコピー
scp user@server:/tmp/capture.pcap ./analysis/

# 3. Wiresharkで開く
wireshark ./analysis/capture.pcap

3-4. tcpdump + sshパイプライン(リアルタイム)

リモートサーバーのパケットをリアルタイムでローカルWiresharkで分析:

# 方法1: sshパイプ
ssh user@server 'sudo tcpdump -i eth0 -w - port 443' | wireshark -k -i -

# 方法2: named pipe使用
mkfifo /tmp/remote_capture
wireshark -k -i /tmp/remote_capture &
ssh user@server 'sudo tcpdump -i eth0 -w - port 443' > /tmp/remote_capture

# 方法3: 特定期間のみキャプチャ
ssh user@server 'sudo timeout 60 tcpdump -i eth0 -w - port 80' | wireshark -k -i -

この技法はプロダクションサーバーで発生するネットワーク問題をリアルタイムで分析する際に非常に有用です。


4. パケットで読むプロトコル分析

4-1. TCP 3-Way Handshakeパケット分析

TCP接続確立(かくりつ)の3-Way Handshakeをパケットレベルで分析します:

Step 1: SYN(クライアント → サーバー)
  Source: 10.0.0.5:54321
  Dest:   93.184.216.34:443
  Flags:  [SYN]
  Seq:    0 (ISN: Initial Sequence Number)
  Win:    65535
  Options: MSS=1460, SACK Permitted, Window Scale=6

Step 2: SYN-ACK(サーバー → クライアント)
  Source: 93.184.216.34:443
  Dest:   10.0.0.5:54321
  Flags:  [SYN, ACK]
  Seq:    0(サーバーのISN  Ack:    1(クライアントISN + 1  Win:    65535
  Options: MSS=1400, SACK Permitted, Window Scale=7

Step 3: ACK(クライアント → サーバー)
  Source: 10.0.0.5:54321
  Dest:   93.184.216.34:443
  Flags:  [ACK]
  Seq:    1
  Ack:    1
  Win:    65535

Wiresharkフィルタ:tcp.flags.syn == 1 でSYNパケットを見つけ、Follow TCP Streamで全ハンドシェイクを確認します。

問題診断ポイント:

  • SYNのみでSYN-ACKがない場合:サーバーが応答していない(ファイアウォールブロックの可能性)
  • SYN-ACKは来るが最終ACKがない場合:クライアント側の問題
  • RSTパケットが即座に来る場合:ポートが閉じているかファイアウォールが接続拒否

4-2. HTTPリクエスト/レスポンス分析

# HTTPリクエストパケット詳細
Frame 45: 342 bytes on wire
  Ethernet II: Src=aa:bb:cc:dd:ee:ff, Dst=11:22:33:44:55:66
  Internet Protocol Version 4: Src=10.0.0.5, Dst=93.184.216.34
  Transmission Control Protocol: Src Port=54321, Dst Port=80
  Hypertext Transfer Protocol:
    GET /api/v1/users?page=1 HTTP/1.1
    Host: api.example.com
    User-Agent: Mozilla/5.0 ...
    Accept: application/json
    Authorization: Bearer eyJhbGci...
    Cookie: session_id=abc123
    Connection: keep-alive

# HTTPレスポンスパケット詳細
Frame 47: 1280 bytes on wire
  Hypertext Transfer Protocol:
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Content-Length: 956
    Set-Cookie: session_id=xyz789; HttpOnly; Secure; SameSite=Strict
    X-Request-Id: req_abc123
    Strict-Transport-Security: max-age=31536000
    X-Content-Type-Options: nosniff

セキュリティ観点での確認事項(じこう):

  • Authorizationヘッダーが平文HTTPで送信されていないか
  • Set-CookieにHttpOnly、Secureフラグがあるか
  • セキュリティヘッダー(HSTS、X-Content-Type-Optionsなど)が設定されているか
  • レスポンスに機密情報が含まれていないか

4-3. DNSクエリ/レスポンスパケット構造

# DNSクエリ(Query)
Domain Name System (query)
  Transaction ID: 0x1a2b
  Flags: 0x0100 Standard query
  Questions: 1
  Queries:
    api.example.com: type A, class IN

# DNSレスポンス(Response)
Domain Name System (response)
  Transaction ID: 0x1a2b
  Flags: 0x8180 Standard query response, No error
  Questions: 1
  Answer RRs: 2
  Answers:
    api.example.com: type A, class IN, addr 93.184.216.34
      TTL: 300 (5 minutes)
    api.example.com: type A, class IN, addr 93.184.216.35
      TTL: 300 (5 minutes)

DNSセキュリティ点検:

  • DNSクエリが暗号化(あんごうか)されずに送信されていないか(DoH/DoT使用有無)
  • 異常に長いドメイン名(DNSトンネリング疑い)
  • 不明なDNSサーバーへのクエリ(DNSハイジャックの可能性)

4-4. TLS Handshakeパケット分析

TLS 1.3ハンドシェイクは1-RTT(Round Trip Time)で以前のバージョンより高速です:

Step 1: Client Hello
  TLS Record Layer:
    Content Type: Handshake (22)
    Version: TLS 1.0(互換性)
  Handshake Protocol: Client Hello
    Version: TLS 1.2(互換性のため)
    Random: [32 bytes]
    Session ID: [32 bytes]
    Cipher Suites (17 suites):
      TLS_AES_256_GCM_SHA384
      TLS_AES_128_GCM_SHA256
      TLS_CHACHA20_POLY1305_SHA256
    Extensions:
      server_name: api.example.com  (SNI)
      supported_versions: TLS 1.3
      key_share: x25519 [public key]
      signature_algorithms: ecdsa_secp256r1_sha256, rsa_pss_rsae_sha256

Step 2: Server Hello + Certificate + Finished
  Handshake Protocol: Server Hello
    Cipher Suite: TLS_AES_256_GCM_SHA384
    Key Share: x25519 [server public key]
  [Encrypted Extensions]
  [Certificate]
  [Certificate Verify]
  [Finished]

Step 3: Client Finished (Encrypted)
  [Change Cipher Spec]
  [Finished]

4-5. TLS復号化:SSLKEYLOGFILE環境変数設定

開発/デバッグ環境でTLSトラフィックを復号化できます:

# 1. 環境変数設定(bash)
export SSLKEYLOGFILE="$HOME/.ssl-keys.log"

# 2. ChromeまたはFirefoxを起動(この環境変数を自動認識)
# ブラウザがTLSセッションキーをファイルに記録します

# 3. curlでも使用可能
SSLKEYLOGFILE=$HOME/.ssl-keys.log curl https://api.example.com/health

Wireshark設定:

  1. Edit > Preferences > Protocols > TLS
  2. (Pre)-Master-Secret log filenameにキーファイルパスを入力
  3. 以降キャプチャされたTLSトラフィックが復号化されて表示されます

注意:プロダクション環境では絶対に使用しないでください。開発/ステージング環境でのみ使用してください。


5. 攻撃検知(こうげきけんち)実践

5-1. ARPスプーフィング検知

ARPスプーフィングはローカルネットワークでMACアドレスを偽造(ぎぞう)してトラフィックを傍受(ぼうじゅ)する攻撃です。

正常なARP動作:

Who has 10.0.0.1? Tell 10.0.0.5
10.0.0.1 is at aa:bb:cc:dd:ee:ff

ARPスプーフィング検知シナリオ:

# 攻撃者がゲートウェイ(10.0.0.1)を詐称
10.0.0.1 is at [攻撃者MAC: 11:22:33:44:55:66]  ← 異常!
10.0.0.1 is at [実際MAC: aa:bb:cc:dd:ee:ff]      ← 正常

# 同じIPに対して2つの異なるMACアドレス → ARPスプーフィング!

Wiresharkフィルタ:

arp.duplicate-address-detected
arp.duplicate-address-frame

検知スクリプト:

#!/bin/bash
# ARPテーブルモニタリング
while true; do
    arp -a | sort > /tmp/arp_current.txt
    if [ -f /tmp/arp_previous.txt ]; then
        diff /tmp/arp_previous.txt /tmp/arp_current.txt
        if [ $? -ne 0 ]; then
            echo "[ALERT] ARP table changed at $(date)"
            diff /tmp/arp_previous.txt /tmp/arp_current.txt
        fi
    fi
    cp /tmp/arp_current.txt /tmp/arp_previous.txt
    sleep 10
done

5-2. ポートスキャン検知

SYN Scan(Half-Open Scan)パターン:

Nmapのデフォルトスキャン方式です。SYNパケットだけ送って接続を完了しません。

攻撃者 → 対象:22  [SYN]
対象:22 → 攻撃者  [SYN,ACK]  ← ポート開放
攻撃者 → 対象:22  [RST]       ← 接続未完了

攻撃者 → 対象:23  [SYN]
対象:23 → 攻撃者  [RST,ACK]  ← ポート閉鎖

Wiresharkフィルタ:

# SYNスキャン検知(ACKなしのSYNのみ)
tcp.flags.syn == 1 and tcp.flags.ack == 0

# 短時間に多数のポートへSYN
tcp.flags.syn == 1 and tcp.flags.ack == 0 and ip.src == 10.0.0.100

Nmapスキャン種類別パケット特徴:

スキャン種類コマンドTCPフラグ特徴
SYN Scannmap -sSSYN最も一般的、Half-open
Connect Scannmap -sTFull handshake完全なTCP接続
FIN Scannmap -sFFINステルススキャン
XMAS Scannmap -sXFIN,PSH,URGChristmas Tree
NULL Scannmap -sN(なし)フラグなしパケット
ACK Scannmap -sAACKファイアウォール規則検知
UDP Scannmap -sUUDPICMPレスポンスで判断

5-3. DDoSパターン分析

SYN Flood:

# 大量のSYNパケットが様々なソースIPから同時に流入
# Wiresharkフィルタ
tcp.flags.syn == 1 and tcp.flags.ack == 0

# tcpdumpでSYNパケットカウント
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' -c 10000 2>&1 | tail -1
# 結果: 数秒で"10000 packets captured"が出ればSYN Flood疑い

HTTP Flood:

# 同一URLに対する大量リクエスト
# Wiresharkフィルタ
http.request.uri == "/api/login"

# 毎秒リクエスト数確認
# Statistics > I/O Graphでhttp.requestをY軸に設定

DNS Amplification:

# DNSレスポンスがクエリよりはるかに大きい場合(増幅比率)
# 小さなクエリ(約60 bytes)→ 大きなレスポンス(約3000+ bytes)

# Wiresharkフィルタ
dns.response and frame.len > 1000

# 増幅比率 = レスポンスサイズ / リクエストサイズ
# ANYクエリの増幅比率: 約28x ~ 54x

DDoS検知チェックリスト:

  1. I/O Graphでトラフィック急増を確認
  2. Conversationsで上位ソースIPを確認
  3. Protocol Hierarchyで特定プロトコル比率の急増を確認
  4. 同一パターンの繰り返しリクエストを確認
  5. 異常なソースIP帯域を確認(GeoIP活用)

5-4. SQLインジェクション検知

HTTP POST BodyからSQLキーワードを検索します:

# Wireshark Display Filter
http.request.method == "POST" and (
  http contains "UNION" or
  http contains "SELECT" or
  http contains "DROP" or
  http contains "DELETE" or
  http contains "1=1" or
  http contains "OR 1" or
  http contains "--" or
  http contains "/*"
)

実際のSQLインジェクションパケット例:

POST /api/login HTTP/1.1
Host: vulnerable-app.com
Content-Type: application/x-www-form-urlencoded

username=admin' OR '1'='1&password=anything

異常レスポンスサイズパターン:

  • 正常ログイン失敗レスポンス:約200 bytes
  • SQLインジェクション成功時:数千bytes(データ流出)
# 異常レスポンスサイズ検知
http.response and http.content_length > 10000

5-5. データ流出(りゅうしゅつ)検知

DNSトンネリング検知:

DNSトンネリングはDNSクエリにデータをエンコードしてファイアウォールを迂回(うかい)する技法です。

# 正常DNSクエリ
api.example.com(15文字)

# DNSトンネリングクエリ(異常に長いドメイン)
dGhpcyBpcyBhIHNlY3JldCBtZXNzYWdl.tunnel.evil.com(48文字)

Wiresharkフィルタ:

# 異常長DNSクエリ検知
dns.qry.name.len > 50

# TXTレコードクエリ(トンネリングに頻繁に使用)
dns.qry.type == 16

# 特定ドメインへの異常に多いクエリ
dns.qry.name contains "tunnel.evil.com"

異常アウトバウンドトラフィック検知:

# tcpdumpで大容量アウトバウンドモニタリング
sudo tcpdump -i eth0 'src net 10.0.0.0/8 and dst net not 10.0.0.0/8 and greater 10000' -c 100

# 異常ポートへのアウトバウンド
sudo tcpdump -i eth0 'src net 10.0.0.0/8 and not (dst port 80 or dst port 443 or dst port 53 or dst port 22)'

6. セキュリティツールエコシステム

6-1. Nmap:ネットワークスキャナー

Nmapはネットワーク探索(たんさく)とセキュリティ監査(かんさ)のためのオープンソースツールです。

# 基本ポートスキャン
nmap 192.168.1.1

# サービスバージョン検知
nmap -sV 192.168.1.1

# OS検知
nmap -O 192.168.1.1

# アグレッシブスキャン(サービス、OS、スクリプト、traceroute)
nmap -A 192.168.1.1

# 全ポートスキャン
nmap -p- 192.168.1.1

# NSEスクリプト活用
nmap --script vuln 192.168.1.1
nmap --script ssl-heartbleed 192.168.1.1
nmap --script http-sql-injection 192.168.1.1

6-2. Burp Suite:Webアプリセキュリティテスト

Burp SuiteはWebアプリケーションセキュリティテストの標準ツールです。

主要機能:

  • Proxy:ブラウザとサーバー間のリクエスト/レスポンスの傍受・修正
  • Scanner:自動脆弱性スキャン(SQLインジェクション、XSS、CSRFなど)
  • Intruder:自動化攻撃(ブルートフォース、ファジング)
  • Repeater:個別リクエストの修正・再送
  • Decoder:エンコード/デコードユーティリティ

6-3. OWASP ZAP:無料(むりょう)Webセキュリティスキャナー

# Dockerで素早くスキャン
docker run -t zaproxy/zap-stable zap-baseline.py -t https://target.com

# APIスキャン
docker run -t zaproxy/zap-stable zap-api-scan.py -t https://target.com/openapi.json -f openapi

# フルスキャン
docker run -t zaproxy/zap-stable zap-full-scan.py -t https://target.com

6-4. Snort / Suricata:IDS/IPS

# Suricataインストール(Ubuntu)
sudo apt install suricata

# ルール更新
sudo suricata-update

# IDSモードで実行
sudo suricata -c /etc/suricata/suricata.yaml -i eth0

# カスタムルール例
# /etc/suricata/rules/local.rules
# alert http any any -> any any (msg:"SQL Injection Attempt"; content:"UNION SELECT"; nocase; sid:1000001; rev:1;)
# alert dns any any -> any any (msg:"DNS Tunneling Suspected"; dns.query; content:".tunnel."; nocase; sid:1000002; rev:1;)

6-5. Metasploit:侵入(しんにゅう)テストフレームワーク

# Metasploit起動
msfconsole

# 脆弱性検索
# msf6> search type:exploit platform:linux apache

# モジュール使用例
# msf6> use exploit/multi/http/apache_log4j
# msf6> set RHOSTS target.com
# msf6> set RPORT 8080
# msf6> run

6-6. ツール比較表(ひかくひょう)

ツール用途ライセンス難易度(なんいど)主な対象
Wiresharkパケット分析無料/OSS中級ネットワークエンジニア、開発者
tcpdumpCLIパケットキャプチャ無料/OSS中級システム管理者
Nmapポートスキャニング無料/OSS初級セキュリティエンジニア
Burp SuiteWebセキュリティテスト有料/無料版上級ペンテスター
OWASP ZAPWebセキュリティスキャン無料/OSS中級開発者、QA
SnortIDS/IPS無料/OSS上級セキュリティ運用
SuricataIDS/IPS無料/OSS上級セキュリティ運用
Metasploit侵入テスト有料/無料版上級ペンテスター

7. ゼロトラストアーキテクチャ

7-1. 基本原則(きほんげんそく):Never Trust, Always Verify

従来のセキュリティモデルは「城(しろ)と堀(ほり)」アプローチでした。内部ネットワークは信頼(しんらい)し、外部のみをブロックします。しかしこのモデルは内部脅威やVPN侵害時に無力です。

ゼロトラストは根本的(こんぽんてき)に異なります:

従来モデル:
  [インターネット] --ファイアウォール-- [内部ネットワーク: すべて信頼]
  → 内部侵入時、横方向移動(Lateral Movement)が自由

ゼロトラスト:
  [すべてのリクエスト] --認証/認可-- [リソース]
  → すべてのアクセスを検証(場所に関係なく)

核心原則:

  1. 明示的検証(めいじてきけんしょう):すべてのリクエストを認証、認可、暗号化
  2. 最小権限(さいしょうけんげん):必要最小限の権限のみ付与(Just-In-Time、Just-Enough-Access)
  3. 侵害想定(しんがいそうてい):すでに侵害されたと想定して設計

7-2. マイクロセグメンテーション

ネットワークを小さな領域に分離して横方向移動を阻止(そし)します:

従来のネットワーク:
  [Webサーバー] ←→ [Appサーバー] ←→ [DBサーバー]
  すべて同じVLAN、自由な通信

マイクロセグメンテーション:
  [Webサーバー] --ポリシー-[Appサーバー] --ポリシー-[DBサーバー]
  各通信に別個のセキュリティポリシー適用
  - WebApp: ポート8080のみ許可
  - AppDB: ポート5432のみ許可
  - WebDB: ブロック

7-3. mTLS(相互認証(そうごにんしょう))実装

通常のTLSはサーバーのみ認証しますが、mTLSはクライアントも認証します:

通常TLS:
  ClientServer: 「あなたが本物のサーバーであることを証明してください」
  ServerClient: [サーバー証明書]
  → クライアントは検証されない

mTLS:
  ClientServer: 「あなたが本物であることを証明してください」
  ServerClient: [サーバー証明書] + 「あなたも証明してください」
  ClientServer: [クライアント証明書]
  → 双方向認証完了

Node.js mTLSサーバー例:

const https = require('https')
const fs = require('fs')

const options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'), // CA証明書
  requestCert: true, // クライアント証明書要求
  rejectUnauthorized: true, // 無効な証明書を拒否
}

const server = https.createServer(options, (req, res) => {
  const clientCert = req.socket.getPeerCertificate()
  console.log('Client CN:', clientCert.subject.CN)
  res.writeHead(200)
  res.end('Mutual TLS authenticated!\n')
})

server.listen(443)

7-4. Service Mesh(Istio)でのセキュリティ

Istioはマイクロサービス間通信に自動的にmTLSを適用します:

# Istio PeerAuthentication - mTLS強制
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT # mTLS必須

---
# Istio AuthorizationPolicy - 細かいアクセス制御
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-access
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  rules:
    - from:
        - source:
            principals: ['cluster.local/ns/production/sa/frontend']
      to:
        - operation:
            methods: ['GET', 'POST']
            paths: ['/api/v1/*']

7-5. ゼロトラストとKubernetes

# Kubernetes NetworkPolicy - Pod間通信制御
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: database
      ports:
        - protocol: TCP
          port: 5432
    - to: # DNS許可
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53

---
# Pod Security Standards
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      resources:
        limits:
          memory: '256Mi'
          cpu: '500m'

8. 開発者のためのセキュリティチェックリスト

8-1. HTTPS強制とHSTS

# Nginx設定
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # HSTSヘッダー(2年、サブドメイン含む、preload)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    # TLS設定
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
}

8-2. CORS設定

// Express.js - 安全なCORS設定
const cors = require('cors')

const corsOptions = {
  origin: ['https://app.example.com', 'https://admin.example.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400, // Preflightキャッシュ24時間
}

app.use(cors(corsOptions))

// 絶対にこうしないでください:
// app.use(cors());  // 全オリジン許可 = セキュリティ脆弱

8-3. Rate Limiting

// Express.js - Rate Limiting
const rateLimit = require('express-rate-limit')

// 一般API
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分
  max: 100, // 最大100リクエスト
  message: 'Too many requests, please try again later.',
  standardHeaders: true,
  legacyHeaders: false,
})

// ログインエンドポイント(より厳格)
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: 'Too many login attempts, please try again after 15 minutes.',
})

app.use('/api/', apiLimiter)
app.use('/api/login', loginLimiter)

8-4. Input Validation

// Joiを使用した入力検証
const Joi = require('joi')

const userSchema = Joi.object({
  username: Joi.string().alphanum().min(3).max(30).required(),
  email: Joi.string().email().required(),
  password: Joi.string()
    .min(12)
    .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/)
    .required(),
  age: Joi.number().integer().min(13).max(120),
})

app.post('/api/register', (req, res) => {
  const result = userSchema.validate(req.body)
  if (result.error) {
    return res.status(400).json({
      error: result.error.details[0].message,
    })
  }
  // 検証通過後の処理
})

8-5. SQLパラメータ化クエリ

// Node.js + PostgreSQL - 安全なクエリ
const { Pool } = require('pg')
const pool = new Pool()

// 絶対にしないでください(SQLインジェクション脆弱):
// const query = `SELECT * FROM users WHERE id = ${userId}`;

// 正しい方法: パラメータ化クエリ
async function getUser(userId) {
  const result = await pool.query('SELECT id, username, email FROM users WHERE id = $1', [userId])
  return result.rows[0]
}

// ORM使用(Prisma)
async function getUserPrisma(userId) {
  return await prisma.user.findUnique({
    where: { id: userId },
    select: { id: true, username: true, email: true },
  })
}

8-6. JWT/OAuth2セキュリティ

// JWTセキュリティベストプラクティス
const jwt = require('jsonwebtoken')

// Access Token: 短い有効期限
const accessToken = jwt.sign({ userId: user.id, role: user.role }, process.env.JWT_SECRET, {
  expiresIn: '15m', // 15分
  algorithm: 'RS256', // RSA非対称キー使用
  issuer: 'api.example.com',
  audience: 'app.example.com',
})

// Refresh Token: DBに保存、ローテーション適用
const refreshToken = jwt.sign(
  { userId: user.id, tokenVersion: user.tokenVersion },
  process.env.REFRESH_SECRET,
  { expiresIn: '7d' }
)

// 検証ミドルウェア
function verifyToken(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1]
  if (!token) return res.status(401).json({ error: 'No token' })

  try {
    const decoded = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
      algorithms: ['RS256'],
      issuer: 'api.example.com',
      audience: 'app.example.com',
    })
    req.user = decoded
    next()
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' })
  }
}

8-7. シークレット管理

# HashiCorp Vault使用例
vault kv put secret/myapp/db \
  username="dbuser" \
  password="supersecret" \
  host="db.internal.example.com"

# アプリケーションから読み取り
vault kv get -field=password secret/myapp/db
// AWS Secrets Manager
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager')

async function getSecret(secretName) {
  const client = new SecretsManagerClient({ region: 'us-east-1' })
  const response = await client.send(new GetSecretValueCommand({ SecretId: secretName }))
  return JSON.parse(response.SecretString)
}

// 使用
const dbCreds = await getSecret('production/database')

8-8. セキュリティヘッダー

// Helmet.jsでセキュリティヘッダー設定
const helmet = require('helmet')

app.use(
  helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", 'data:', 'https:'],
        connectSrc: ["'self'", 'https://api.example.com'],
        fontSrc: ["'self'", 'https://fonts.gstatic.com'],
        objectSrc: ["'none'"],
        mediaSrc: ["'none'"],
        frameSrc: ["'none'"],
      },
    },
    crossOriginEmbedderPolicy: true,
    crossOriginOpenerPolicy: true,
    crossOriginResourcePolicy: { policy: 'same-site' },
    hsts: { maxAge: 63072000, includeSubDomains: true, preload: true },
    noSniff: true, // X-Content-Type-Options: nosniff
    referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
    xssFilter: true, // X-XSS-Protection
  })
)

8-9. 依存関係(いぞんかんけい)脆弱性スキャン

# npm audit
npm audit
npm audit fix

# Snyk
npx snyk test
npx snyk monitor

# GitHub Dependabot(自動PR作成)
# .github/dependabot.yml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    schedule:
      interval: 'weekly'
    open-pull-requests-limit: 10
    reviewers:
      - 'security-team'
    labels:
      - 'dependencies'
      - 'security'

総合セキュリティチェックリスト:

項目(こうもく)重要度確認
HTTPS強制 + HSTS必須-
TLS 1.2+のみ許可必須-
CORSホワイトリスト必須-
Rate Limiting必須-
Input Validation必須-
パラメータ化クエリ必須-
JWT RS256 + 短い有効期限-
Refresh Tokenローテーション-
シークレットマネージャー使用必須-
CSPヘッダー-
X-Content-Type-Options-
Referrer-Policy-
依存関係脆弱性スキャン必須-
Dependabot有効化-
セキュリティログ/モニタリング必須-

9. セキュリティ資格証(しかくしょう)ロードマップ

入門(にゅうもん) → 中級 → 上級ルート

入門(01年目):
  CompTIA Security+
  ├── 難易度: ★★☆☆☆
  ├── 費用: 約$404(試験料)
  ├── 準備期間: 23ヶ月
  ├── 内容: セキュリティ基礎、脅威、暗号化、ネットワークセキュリティ
  └── キャリアインパクト: ITセキュリティ入門、政府/軍関連で必須

中級(13年目):
  CEH (Certified Ethical Hacker)
  ├── 難易度: ★★★☆☆
  ├── 費用: 約$1,199(試験料)
  ├── 準備期間: 34ヶ月
  ├── 内容: ハッキング技法、脆弱性分析、侵入テスト
  └── キャリアインパクト: セキュリティアナリスト、ペンテスター

  CISSP(セキュリティ管理者ルート)
  ├── 難易度: ★★★★☆
  ├── 費用: 約$749(試験料)
  ├── 準備期間: 46ヶ月(経験5年必要)
  ├── 内容: セキュリティ管理、ガバナンス、リスク管理
  └── キャリアインパクト: CISO、セキュリティアーキテクト

上級(3年目+:
  OSCP (Offensive Security Certified Professional)
  ├── 難易度: ★★★★★
  ├── 費用: 約$1,649(トレーニング + 試験)
  ├── 準備期間: 612ヶ月
  ├── 内容: 24時間実践侵入テスト試験
  └── キャリアインパクト: シニアペンテスター、レッドチーム

資格証別詳細比較

資格証対象実技比率更新周期平均年収上昇
CompTIA Security+入門者20%3年+15%
CEH中級者40%3年+20%
CISSP管理者0%(理論)3年+25%
OSCP専門家100%(実技)なし+35%
GPENペンテスター60%4年+25%
CISMマネージャー0%(理論)3年+20%

開発者向け推奨ルート

Web開発者:
  Security+CEHOSCPBug Bounty

クラウド開発者:
  Security+AWS Security SpecialtyCCSP

DevOpsエンジニア:
  Security+CKS (Kubernetes Security)OSCP

10. クイズ

ここまで学んだ内容を確認しましょう。

Q1. WiresharkでCapture FilterとDisplay Filterの最大の違いは?

正解:適用タイミングが異なります。

  • Capture Filter:キャプチャ開始前に設定し、BPF文法を使用します。カーネルレベルでフィルタリングするためパフォーマンスが良いですが、キャプチャ中に変更できません。
  • Display Filter:キャプチャ後に適用し、Wireshark独自の文法を使用します。既にキャプチャされたデータからフィルタリングするため、リアルタイムで変更可能です。

大量トラフィック環境ではCapture Filterで必要なトラフィックのみキャプチャし、Display Filterで精密に分析するのがベストプラクティスです。

Q2. TLSトラフィックをWiresharkで復号化するにはどの環境変数を設定する必要がありますか?

正解:SSLKEYLOGFILE

SSLKEYLOGFILE環境変数を設定すると、Chrome、Firefoxなどのブラウザが指定されたファイルにTLSセッションキーを記録します。Wiresharkでこのファイルを指定すれば(Edit - Preferences - Protocols - TLS)TLSで暗号化されたトラフィックの内容を確認できます。

注意:この機能は開発/デバッグ環境でのみ使用すべきであり、プロダクション環境では絶対に使用してはいけません。

Q3. SYN Flood DDoS攻撃をWiresharkで検知するにはどのフィルタを使用しますか?

正解:tcp.flags.syn == 1 and tcp.flags.ack == 0

このフィルタはACKフラグなしでSYNフラグのみ設定されたパケットを表示します。SYN Flood攻撃は大量のSYNパケットを送ってサーバーのTCP接続テーブルを溢れさせる攻撃です。

さらにStatistics - I/O Graphsでこのフィルタを適用すると、時間帯別のSYNパケット急増パターンを視覚的に確認できます。

Q4. ゼロトラストセキュリティモデルの3つの核心原則は?

正解:

  1. 明示的検証(Verify Explicitly):すべてのリクエストを常に認証・認可します。場所やネットワークに関係なく、すべてのアクセスを検証します。
  2. 最小権限(Least Privilege):Just-In-Time、Just-Enough-Access原則で必要最小限の権限のみ付与します。
  3. 侵害想定(Assume Breach):すでに侵害されたと想定し、横方向移動を最小化し、エンドツーエンド暗号化を適用します。

従来の「城と堀」モデルとは異なり、内部ネットワークも信頼しないことが核心です。

Q5. DNSトンネリングを検知するために確認すべき主な指標は?

正解:

  1. 異常に長いドメイン名:正常なDNSクエリは通常20〜30文字ですが、DNSトンネリングは50文字以上のエンコードされたデータを含みます。
  2. TXTレコードクエリの急増:DNSトンネリングはより多くのデータを送信するためにTXTレコードを頻繁に使用します。
  3. 特定ドメインへの異常なクエリ頻度:同じドメインに対して毎秒数十〜数百件のクエリが発生します。

Wiresharkフィルタ:dns.qry.name.len > 50 または dns.qry.type == 16(TXTレコード)で検知できます。


11. 参考資料(さんこうしりょう)

  1. Wireshark公式ドキュメント - wireshark.org/docs
  2. tcpdumpマニュアル - tcpdump.org/manpages
  3. OWASP Top 10 (2025) - owasp.org/Top10
  4. NISTゼロトラストアーキテクチャ (SP 800-207) - csrc.nist.gov
  5. IBM Cost of a Data Breach Report 2025 - ibm.com/security
  6. Nmapリファレンスガイド - nmap.org/book/man.html
  7. Metasploit Unleashed - offensive-security.com/metasploit-unleashed
  8. SANSネットワークフォレンジック - sans.org/cyber-security-courses/network-forensics
  9. Practical Packet Analysis, 3rd Edition - Chris Sanders (No Starch Press)
  10. The Web Application Hacker's Handbook - Dafydd Stuttard, Marcus Pinto
  11. CompTIA Security+ Study Guide - comptia.org/certifications/security
  12. OSCP Certification Guide - offensive-security.com/pwk-oscp
  13. Suricata IDSドキュメント - suricata.readthedocs.io
  14. Istioセキュリティドキュメント - istio.io/latest/docs/concepts/security
  15. Kubernetesネットワークポリシー - kubernetes.io/docs/concepts/services-networking/network-policies
  16. OWASP ZAPドキュメント - zaproxy.org/docs
  17. Burp Suiteドキュメント - portswigger.net/burp/documentation