はじめに
FTPを使ったアプリケーションに問題があった際に、正常であるFTPの挙動を確認しました。その際に、Wiresharkを使った方法を備忘録として残してます。
docker 環境
FTP Server: stilliard/pure-ftpd
FTP Client: Ubuntu 18.04
https://hub.docker.com/r/stilliard/pure-ftpd/
docker 環境の構築
今回はFTP ServerとClientを分けて、dockerホストを2つ作成します。最初に、docker環境上でFTP Serverを構築します。
FTP Server
前述したpure-ftpdのサンプルコマンドで、docker環境上でFTP Serverを立ち上げます。
~ $ :~$ docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e "PUBLICHOST=localhost" stilliard/pure-ftpd
ftp-userを作成するために、先ほど作成したftpd_server
にアクセスします。
# 先ほど作成したpure-ftpdのdocker process
~ $ :~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7382b1acd311 stilliard/pure-ftpd "/bin/sh -c '/run.sh…" About a minute ago Up About a minute 0.0.0.0:21->21/tcp, :::21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp, :::30000-30009->30000-30009/tcp ftpd_server
# /bin/bashを実行
~ $ :~$ docker exec -it 7382b1acd311 /bin/bash
# ftpアップロード先のディレクトリ test-ftp 作成
root@7382b1acd311:~# mkdir /home/ftpusers/test-ftp
# ftp-userの作成
# ftp-user: test-ftp
# Uplaod先:/home/ftpusers/test-ftp/
root@7382b1acd311:~# pure-pw useradd test-ftp -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/test-ftp/
Password:
Enter it again:
# ディレクトリのアクセス権の付与
root@7382b1acd311:~# chown test-ftp:ftpgroup /home/ftpusers/test-ftp/
# logout
root@7382b1acd311:~# exit
FTP Client
FTP Clientととして、docker環境上にUbuntu 18.04を起動する。
~ $ :~$ docker run -it -d --name ftpd_client ubuntu:18.04 /bin/bash
dockerが作成されたことを確認して、必要なパッケージをインストールします。今回は、ftp
とtcpdump
だけインストールします。
~ $ :~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1457c177a5a ubuntu:18.04 "/bin/bash" About a minute ago Up About a minute ftpd_client
7382b1acd311 stilliard/pure-ftpd "/bin/sh -c '/run.sh…" 16 minutes ago Up 16 minutes 0.0.0.0:21->21/tcp, :::21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp, :::30000-30009->30000-30009/tcp ftpd_server
~ $ :~$ docker exec -it b1457c177a5a /bin/bash
# パッケージの一覧を更新
root@b1457c177a5a:/# apt-get update
# ftpのインストール
root@b1457c177a5a:/# apt-get install ftp
# tcpdumpのインストール
root@b1457c177a5a:/# apt-get install tcpdump
FTP Serverであるftpd_server
のIPv4アドレスを確認します。そのIPv4は、FTP Clientのftpで使われるのでコピーしておきます。
~ $ :~$ docker inspect network bridge
....
"Containers": {
"7382b1acd3117c281148aacb75f11f1e509e128351da48094fe63d6dabff0b7c": {
"Name": "ftpd_server",
"EndpointID": "9906eba71be08fee78e4a7f2a09dae004db3214d375cdf86e316609fea57354a",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": "2001:db8:1::242:ac11:2/64"
},
},
....
後ほど、WiresharkでFTPのパケットを見るので、もう1つターミナルを立ち上げて、FTP Clientにアクセスします。その後、tcpdumpによってpcapを作成します。
~ $ :~$ docker exec -it b1457c177a5a /bin/bash
# tcpdumpを使って、pcapを取得
root@b1457c177a5a:/# tcpdump -w ftp.pcap
次に、FTP Clientからテストのファイルを作成して、ftpを実行します。
# テストファイル用の作成
root@b1457c177a5a:~# echo "test" > test.txt
# FTPの実行
root@b1457c177a5a:~# ftp 172.17.0.2
Connected to 172.17.0.2.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 5 allowed.
220-Local time is now 06:22. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (172.17.0.2:root): test-ftp
331 User test-ftp OK. Password required
Password:
230 OK. Current directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put test.txt
local: test.txt remote: test.txt
200 PORT command successful
150 Connecting to port 33289
226-File successfully transferred
226 0.001 seconds (measured here), 9.30 Kbytes per second
5 bytes sent in 0.00 secs (28.2243 kB/s)
ftp> exit
221-Goodbye. You uploaded 1 and downloaded 0 kbytes.
221 Logout.
FTP Serverでtest.txt
がアップロードされていることを、以下のコマンドで確認します。
# テストファイルがアップロードされているか確認
root@7382b1acd311:/# ls /home/ftpusers/test-ftp/
test.txt
最後に、docker環境内において、FTPのパケットが保存されたftp.pcap
をlocalhostへコピーします。
# localhostにpcapのコピー
~ $ :~$ docker cp b1457c177a5a:ftp.pcap ~/Desktop
今回は、下図に流れに沿ってFTPの挙動を確認します。
FTP ClientがFTP ServerのPort 21へ接続要求を行う
FTP ServerがFTP Clientに対して、TCP接続を行う
FTP Serverがデータコネクション用のPort 20を通知
FTP ClientがFTP ServerのPort 20へファイルを送信

WiresharkでFTPパケットのやりとりを表示したのが、下図になります。

所感
実運用において問題が発生した際に、正常な通信の挙動を把握していないと、どのプロセス段階で問題が起きているが把握出来なかった。今回、Wiresharkを使ってFTPの正常な挙動を確認してみた。このようなことを積み重ねさえすれば、トラブルシューティングのノウハウの土台となるはずである。
参考文献
【Docker】FTPサーバコンテナ構築手順と使い方(Pure-ftpd Server) | インフラエンジニアの技術LOG
Docker Hub