🚇
ネットワークの観察 - 第2回 SCPを解析する
はじめに
scpの接続はどのようになっているのでしょうか?今回はwiresharkを使用して確認してみます。
マシンスペック
MacBook Air M2 arm64
Docker上で実施
準備
wiresharkのインストール
brew install --cask wireshark
Dockerfile
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
openssh-server openssh-client \
tcpdump strace vim less iproute2 \
&& mkdir -p /var/run/sshd \
&& useradd -m test && echo 'test:test' | chpasswd \
&& ssh-keygen -A \
&& echo 'PermitRootLogin no' >> /etc/ssh/sshd_config \
&& echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
WORKDIR /work
CMD ["bash"]
docker-compose.yml
version: "3.9"
services:
ssh-server:
build: .
container_name: ssh-server
hostname: ssh-server
ports:
- "2222:22"
command: /usr/sbin/sshd -D -e
networks: [scpnet]
ssh-client:
build: .
container_name: ssh-client
hostname: ssh-client
command: tail -f /dev/null
networks: [scpnet]
packet-capture:
build: .
container_name: packet-capture
cap_add: [NET_ADMIN]
command: tail -f /dev/null
volumes:
- ./pcap:/pcap
networks: [scpnet]
networks:
scpnet:
driver: bridge
コンテナのビルド・起動
docker compose build
docker compose up -d
実験
SSHサーバでtcpdumpを起動
docker exec -d ssh-server \
tcpdump -i any -w /work/scp_transfer.pcap port 22
SSHクライアントコンテナに接続
docker exec -it ssh-client bash
転送用テストファイルを作成
echo "Top secret data: 12345" > secret.txt
scpを用いてSSHサーバへファイル転送
scp -P 22 secret.txt test@ssh-server:/home/test/
# パスワード: test
# 転送完了後
exit
tcpdumpを終了させる
docker exec ssh-server pkill tcpdump
キャプチャデータをローカルへコピー
docker cp ssh-server:/work/scp_transfer.pcap ./pcap/
確認
Wiresharkでパケット解析
open pcap/scp_transfer.pcap
データ
1 0.000000 xx.xx.xx.2 xx.xx.xx.3 TCP 80 53138 → 22 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM TSval=2009929106 TSecr=0 WS=128
2 0.000040 xx.xx.xx.3 xx.xx.xx.2 TCP 80 22 → 53138 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM TSval=3722494617 TSecr=2009929106 WS=128
3 0.000072 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=2009929106 TSecr=3722494617
4 0.000321 xx.xx.xx.2 xx.xx.xx.3 SSHv2 115 Client: Protocol (SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.13)
5 0.000331 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=1 Ack=44 Win=65152 Len=0 TSval=3722494618 TSecr=2009929107
6 0.012181 xx.xx.xx.3 xx.xx.xx.2 SSHv2 115 Server: Protocol (SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.13)
7 0.012256 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=44 Ack=44 Win=64256 Len=0 TSval=2009929119 TSecr=3722494630
8 0.012777 xx.xx.xx.2 xx.xx.xx.3 SSHv2 1608 Client: Key Exchange Init
9 0.012786 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=44 Ack=1580 Win=67200 Len=0 TSval=3722494630 TSecr=2009929119
10 0.013924 xx.xx.xx.3 xx.xx.xx.2 SSHv2 1192 Server: Key Exchange Init
11 0.046590 xx.xx.xx.2 xx.xx.xx.3 SSHv2 1280 Client: Diffie-Hellman Key Exchange Init
12 0.057282 xx.xx.xx.3 xx.xx.xx.2 SSHv2 1604 Server: Diffie-Hellman Key Exchange Reply, New Keys, Encrypted packet (len=284)
13 0.057299 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=2788 Ack=2696 Win=70144 Len=0 TSval=2009929164 TSecr=3722494675
14 0.076275 xx.xx.xx.2 xx.xx.xx.3 SSHv2 156 Client: New Keys, Encrypted packet (len=68)
15 0.122203 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=2696 Ack=2872 Win=70144 Len=0 TSval=3722494740 TSecr=2009929183
16 0.122225 xx.xx.xx.2 xx.xx.xx.3 SSHv2 116 Client: Encrypted packet (len=44)
17 0.122229 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=2696 Ack=2916 Win=70144 Len=0 TSval=3722494740 TSecr=2009929229
18 0.122253 xx.xx.xx.3 xx.xx.xx.2 SSHv2 116 Server: Encrypted packet (len=44)
19 0.122291 xx.xx.xx.2 xx.xx.xx.3 SSHv2 132 Client: Encrypted packet (len=60)
20 0.122870 xx.xx.xx.3 xx.xx.xx.2 SSHv2 336 Server: Encrypted packet (len=264)
21 0.167156 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=2976 Ack=3004 Win=72960 Len=0 TSval=2009929273 TSecr=3722494740
22 2.221207 xx.xx.xx.2 xx.xx.xx.3 SSHv2 156 Client: Encrypted packet (len=84)
23 2.261203 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=3004 Ack=3060 Win=70144 Len=0 TSval=3722496879 TSecr=2009931327
24 2.283432 xx.xx.xx.3 xx.xx.xx.2 SSHv2 100 Server: Encrypted packet (len=28)
25 2.283473 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=3060 Ack=3032 Win=72960 Len=0 TSval=2009931390 TSecr=3722496901
26 2.283617 xx.xx.xx.2 xx.xx.xx.3 SSHv2 184 Client: Encrypted packet (len=112)
27 2.283620 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=3032 Ack=3172 Win=70144 Len=0 TSval=3722496901 TSecr=2009931390
28 2.290516 xx.xx.xx.3 xx.xx.xx.2 SSHv2 700 Server: Encrypted packet (len=628)
29 2.331735 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=3172 Ack=3660 Win=75904 Len=0 TSval=2009931438 TSecr=3722496908
30 2.331742 xx.xx.xx.3 xx.xx.xx.2 SSHv2 116 Server: Encrypted packet (len=44)
31 2.331752 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=3172 Ack=3704 Win=75904 Len=0 TSval=2009931438 TSecr=3722496949
32 2.331802 xx.xx.xx.2 xx.xx.xx.3 SSHv2 124 Client: Encrypted packet (len=52)
33 2.332084 xx.xx.xx.3 xx.xx.xx.2 SSHv2 144 Server: Encrypted packet (len=72)
34 2.332201 xx.xx.xx.2 xx.xx.xx.3 SSHv2 116 Client: Encrypted packet (len=44)
35 2.333226 xx.xx.xx.3 xx.xx.xx.2 SSHv2 428 Server: Encrypted packet (len=356)
36 2.333380 xx.xx.xx.2 xx.xx.xx.3 SSHv2 140 Client: Encrypted packet (len=68)
37 2.333485 xx.xx.xx.3 xx.xx.xx.2 SSHv2 148 Server: Encrypted packet (len=76)
38 2.333612 xx.xx.xx.2 xx.xx.xx.3 SSHv2 132 Client: Encrypted packet (len=60)
39 2.333717 xx.xx.xx.3 xx.xx.xx.2 SSHv2 148 Server: Encrypted packet (len=76)
40 2.333843 xx.xx.xx.2 xx.xx.xx.3 SSHv2 156 Client: Encrypted packet (len=84)
41 2.333952 xx.xx.xx.3 xx.xx.xx.2 SSHv2 124 Server: Encrypted packet (len=52)
42 2.334157 xx.xx.xx.2 xx.xx.xx.3 SSHv2 164 Client: Encrypted packet (len=92)
43 2.334298 xx.xx.xx.3 xx.xx.xx.2 SSHv2 140 Server: Encrypted packet (len=68)
44 2.334490 xx.xx.xx.2 xx.xx.xx.3 SSHv2 140 Client: Encrypted packet (len=68)
45 2.334716 xx.xx.xx.3 xx.xx.xx.2 SSHv2 140 Server: Encrypted packet (len=68)
46 2.334852 xx.xx.xx.2 xx.xx.xx.3 SSHv2 124 Client: Encrypted packet (len=52)
47 2.334955 xx.xx.xx.3 xx.xx.xx.2 SSHv2 140 Server: Encrypted packet (len=68)
48 2.335071 xx.xx.xx.2 xx.xx.xx.3 SSHv2 108 Client: Encrypted packet (len=36)
49 2.335333 xx.xx.xx.3 xx.xx.xx.2 SSHv2 196 Server: Encrypted packet (len=124)
50 2.335393 xx.xx.xx.2 xx.xx.xx.3 SSHv2 108 Client: Encrypted packet (len=36)
51 2.335411 xx.xx.xx.2 xx.xx.xx.3 SSHv2 132 Client: Encrypted packet (len=60)
52 2.335420 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [FIN, ACK] Seq=3824 Ack=4664 Win=78848 Len=0 TSval=2009931442 TSecr=3722496953
53 2.335432 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [ACK] Seq=4664 Ack=3825 Win=70144 Len=0 TSval=3722496953 TSecr=2009931442
54 2.336449 xx.xx.xx.3 xx.xx.xx.2 TCP 72 22 → 53138 [FIN, ACK] Seq=4664 Ack=3825 Win=70144 Len=0 TSval=3722496954 TSecr=2009931442
55 2.336468 xx.xx.xx.2 xx.xx.xx.3 TCP 72 53138 → 22 [ACK] Seq=3825 Ack=4665 Win=78848 Len=0 TSval=2009931443 TSecr=3722496954
まとめ
区間(#) | 相対時刻例 | フェーズ/イベント | 主なパケット例 | 何が起きているか(推測含む) |
---|---|---|---|---|
1–3 | 0.0000s | TCP 3-way ハンドシェイク | SYN / SYN,ACK / ACK | クライアントxx.xx.xx.2が22/TCPへ接続開始。 |
4 & 6 | 0.0003s / 0.012s | プロトコルバージョン交換(平文) | SSH-2.0-OpenSSH_9.6p1 ... |
ここまで平文。双方がSSHバージョンを通知。 |
8 & 10 | 0.0127s / 0.0139s | KEXINIT 交換 | Client/Server: Key Exchange Init | 利用する暗号・圧縮アルゴリズム候補を提示。 |
11–12 | 0.046–0.057s | Diffie-Hellman鍵交換&New Keys | Client DH Init/Server Reply + NewKeys | 共有秘密生成。以降の通信を暗号化モードへ切替。 |
14–20 | 0.076–0.122s | 暗号化開始直後の初期制御 | Encrypted packet (len 44–336) | 認証要求・応答やチャネル初期化準備など(内容は暗号化)。 |
21 | 0.167s | ACKのみ | ACK | 小休止。次の操作待ち。 |
22–51 | 2.22–2.335s | 実データ転送/制御のバースト(scp本体想定) | 多数のEncrypted packet(36–196B など) | ファイルデータやメタ情報を暗号化して送受信。サイズから小ファイル転送と推定。 |
52–55 | 2.335–2.336s | セッション終了(TCP FIN/ACK) | FIN,ACK → FIN,ACK → ACK | 正常クローズ。双方がFINを送って接続終了。 |
最後に
本実験から、scp通信は最初のバージョン交換を除き、鍵交換後は全て暗号化されたパケットでやり取りされていることが確認できました。
パケットから読み取れるのは、サイズ・タイミング・方向のみで、ファイル内容や認証情報は覗けません
皆さんの学習に役立てていただけると幸いです。
Discussion