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