🚊

ネットワークの観察 - 第3回 sftpを解析する

に公開

はじめに

sftpの接続はどのようになっているのでしょうか?今回は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 \
    && echo 'Subsystem sftp internal-sftp' >> /etc/ssh/sshd_config

WORKDIR /work
CMD ["bash"]

docker-compose.yml

version: "3.9"
services:
  sftp-server:
    build: .
    container_name: sftp-server
    hostname: sftp-server
    ports:
      - "2222:22"
    command: /usr/sbin/sshd -D -e
    networks: [sftpnet]

  sftp-client:
    build: .
    container_name: sftp-client
    hostname: sftp-client
    volumes:
      - ./workdir:/workdir
    command: tail -f /dev/null
    networks: [sftpnet]

networks:
  sftpnet:
    driver: bridge

Dockerビルド・起動

docker compose build
docker compose up -d

実験

SFTPサーバ側でパケットキャプチャ開始

docker exec -d sftp-server \
    tcpdump -i any -w /work/sftp_transfer.pcap port 22

SFTPクライアント側に接続

docker exec -it sftp-client bash

転送用テストファイルを作成(クライアント内)

echo "Sensitive information: SFTP Test" > /workdir/secret_sftp.txt

SFTPコマンドでサーバに接続しファイル転送

cd /workdir
sftp -P 22 test@sftp-server
# パスワードは "test"

# 以下、sftpプロンプト内の操作
put secret_sftp.txt
quit

tcpdumpを終了させる

docker exec sftp-server pkill tcpdump

キャプチャデータをローカルへコピー

docker cp sftp-server:/work/sftp_transfer.pcap ./pcap/

結果

Wiresharkによる解析

open pcap/sftp_transfer.pcap

データ

1	0.000000	xx.xx.xx.3	xx.xx.xx.2	TCP	80	34594 → 22 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM TSval=4107120424 TSecr=0 WS=128
2	0.000048	xx.xx.xx.2	xx.xx.xx.3	TCP	80	22 → 34594 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM TSval=3957282714 TSecr=4107120424 WS=128
3	0.000099	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=4107120425 TSecr=3957282714
4	0.000397	xx.xx.xx.3	xx.xx.xx.2	SSHv2	115	Client: Protocol (SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.13)
5	0.000411	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=1 Ack=44 Win=65152 Len=0 TSval=3957282715 TSecr=4107120425
6	0.010983	xx.xx.xx.2	xx.xx.xx.3	SSHv2	115	Server: Protocol (SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.13)
7	0.011032	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=44 Ack=44 Win=64256 Len=0 TSval=4107120435 TSecr=3957282725
8	0.011265	xx.xx.xx.3	xx.xx.xx.2	SSHv2	1608	Client: Key Exchange Init
9	0.011272	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=44 Ack=1580 Win=67200 Len=0 TSval=3957282726 TSecr=4107120436
10	0.012303	xx.xx.xx.2	xx.xx.xx.3	SSHv2	1192	Server: Key Exchange Init
11	0.043874	xx.xx.xx.3	xx.xx.xx.2	SSHv2	1280	Client: Diffie-Hellman Key Exchange Init
12	0.054721	xx.xx.xx.2	xx.xx.xx.3	SSHv2	1604	Server: Diffie-Hellman Key Exchange Reply, New Keys, Encrypted packet (len=284)
13	0.054735	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=2788 Ack=2696 Win=70144 Len=0 TSval=4107120479 TSecr=3957282769
14	3.555931	xx.xx.xx.3	xx.xx.xx.2	SSHv2	156	Client: New Keys, Encrypted packet (len=68)
15	3.601136	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=2696 Ack=2872 Win=70144 Len=0 TSval=3957286316 TSecr=4107123980
16	3.601169	xx.xx.xx.3	xx.xx.xx.2	SSHv2	116	Client: Encrypted packet (len=44)
17	3.601175	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=2696 Ack=2916 Win=70144 Len=0 TSval=3957286316 TSecr=4107124026
18	3.601211	xx.xx.xx.2	xx.xx.xx.3	SSHv2	116	Server: Encrypted packet (len=44)
19	3.601275	xx.xx.xx.3	xx.xx.xx.2	SSHv2	132	Client: Encrypted packet (len=60)
20	3.602409	xx.xx.xx.2	xx.xx.xx.3	SSHv2	336	Server: Encrypted packet (len=264)
21	3.645211	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=2976 Ack=3004 Win=72960 Len=0 TSval=4107124070 TSecr=3957286317
22	6.327569	xx.xx.xx.3	xx.xx.xx.2	SSHv2	156	Client: Encrypted packet (len=84)
23	6.368100	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=3004 Ack=3060 Win=70144 Len=0 TSval=3957289083 TSecr=4107126752
24	6.398106	xx.xx.xx.2	xx.xx.xx.3	SSHv2	100	Server: Encrypted packet (len=28)
25	6.398129	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=3060 Ack=3032 Win=72960 Len=0 TSval=4107126823 TSecr=3957289113
26	6.398230	xx.xx.xx.3	xx.xx.xx.2	SSHv2	184	Client: Encrypted packet (len=112)
27	6.398235	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=3032 Ack=3172 Win=70144 Len=0 TSval=3957289113 TSecr=4107126823
28	6.407878	xx.xx.xx.2	xx.xx.xx.3	SSHv2	700	Server: Encrypted packet (len=628)
29	6.408210	xx.xx.xx.3	xx.xx.xx.2	SSHv2	652	Client: Encrypted packet (len=580)
30	6.408219	xx.xx.xx.2	xx.xx.xx.3	SSHv2	116	Server: Encrypted packet (len=44)
31	6.408253	xx.xx.xx.3	xx.xx.xx.2	SSHv2	124	Client: Encrypted packet (len=52)
32	6.412117	xx.xx.xx.2	xx.xx.xx.3	SSHv2	612	Server: Encrypted packet (len=540)
33	6.412331	xx.xx.xx.2	xx.xx.xx.3	SSHv2	144	Server: Encrypted packet (len=72)
34	6.412490	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=3804 Ack=4316 Win=78848 Len=0 TSval=4107126837 TSecr=3957289127
35	6.412526	xx.xx.xx.3	xx.xx.xx.2	SSHv2	116	Client: Encrypted packet (len=44)
36	6.413230	xx.xx.xx.2	xx.xx.xx.3	SSHv2	428	Server: Encrypted packet (len=356)
37	6.413327	xx.xx.xx.3	xx.xx.xx.2	SSHv2	140	Client: Encrypted packet (len=68)
38	6.413400	xx.xx.xx.2	xx.xx.xx.3	SSHv2	148	Server: Encrypted packet (len=76)
39	6.413764	xx.xx.xx.3	xx.xx.xx.2	SSHv2	124	Client: Encrypted packet (len=52)
40	6.413854	xx.xx.xx.2	xx.xx.xx.3	SSHv2	156	Server: Encrypted packet (len=84)
41	6.454867	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=3968 Ack=4832 Win=81664 Len=0 TSval=4107126879 TSecr=3957289128
42	10.788184	xx.xx.xx.3	xx.xx.xx.2	SSHv2	164	Client: Encrypted packet (len=92)
43	10.788756	xx.xx.xx.2	xx.xx.xx.3	SSHv2	124	Server: Encrypted packet (len=52)
44	10.788807	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=4060 Ack=4884 Win=81664 Len=0 TSval=4107131213 TSecr=3957293503
45	10.789589	xx.xx.xx.3	xx.xx.xx.2	SSHv2	172	Client: Encrypted packet (len=100)
46	10.789816	xx.xx.xx.2	xx.xx.xx.3	SSHv2	140	Server: Encrypted packet (len=68)
47	10.790317	xx.xx.xx.3	xx.xx.xx.2	SSHv2	124	Client: Encrypted packet (len=52)
48	10.790496	xx.xx.xx.2	xx.xx.xx.3	SSHv2	140	Server: Encrypted packet (len=68)
49	10.831597	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=4212 Ack=5020 Win=81664 Len=0 TSval=4107131256 TSecr=3957293505
50	14.880887	xx.xx.xx.3	xx.xx.xx.2	SSHv2	108	Client: Encrypted packet (len=36)
51	14.881823	xx.xx.xx.2	xx.xx.xx.3	SSHv2	196	Server: Encrypted packet (len=124)
52	14.881875	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=4248 Ack=5144 Win=81664 Len=0 TSval=4107135306 TSecr=3957297596
53	14.881973	xx.xx.xx.3	xx.xx.xx.2	SSHv2	108	Client: Encrypted packet (len=36)
54	14.882005	xx.xx.xx.3	xx.xx.xx.2	SSHv2	132	Client: Encrypted packet (len=60)
55	14.882021	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [ACK] Seq=5144 Ack=4344 Win=72960 Len=0 TSval=3957297596 TSecr=4107135306
56	14.882023	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [FIN, ACK] Seq=4344 Ack=5144 Win=81664 Len=0 TSval=4107135306 TSecr=3957297596
57	14.885423	xx.xx.xx.2	xx.xx.xx.3	TCP	72	22 → 34594 [FIN, ACK] Seq=5144 Ack=4345 Win=72960 Len=0 TSval=3957297600 TSecr=4107135306
58	14.885484	xx.xx.xx.3	xx.xx.xx.2	TCP	72	34594 → 22 [ACK] Seq=4345 Ack=5145 Win=81664 Len=0 TSval=4107135310 TSecr=3957297600

まとめ

区間(#) 相対時刻(例) フェーズ / イベント 主なパケット例 何が起きているか(推測含む)
1–3 0.0000s TCP 3-way ハンドシェイク SYN / SYN,ACK / ACK xx.xx.xx.3 → 22/TCP 接続開始。
4 & 6 0.0004s / 0.011s プロトコルバージョン交換(平文) SSH-2.0-OpenSSH_9.6p1 ... ここまで平文。SSHバージョン文字列のやり取り。
8 & 10 0.011–0.012s KEXINIT 交換 Client/Server: Key Exchange Init 暗号・圧縮アルゴリズム候補を提示。
11–12 0.043–0.054s DH鍵交換 & New Keys Client DH Init / Server Reply+NewKeys 共有秘密生成。以降暗号化モードへ。
14–20 3.556–3.602s 暗号化後の初期制御 Encrypted packet (44–336B) 認証要求/応答、チャネル初期化(SFTP開始準備)など。
21 3.645s ACKのみ ACK 小休止。ユーザ入力/処理待ち。
22–41 6.327–6.455s データ転送バースト①(SFTP本体) Encrypted packet 52〜700Bなど多数 実データ/メタ情報転送。書き込み・応答が往復。
42–49 10.788–10.832s データ転送バースト② Encrypted packet 52〜172B 続きの転送や属性取得などのやり取り。
50–55 14.881s前後 終盤の制御パケット Encrypted 36/60/196B + ACK 後処理(close/stat など)と思われる制御メッセージ。
56–58 14.882–14.885s TCP セッション終了(FIN/ACK) FIN,ACK → FIN,ACK → ACK 正常クローズ。両端からFIN。

Discussion