🚇

ネットワークの観察 - 第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