凡ジニアのtxt

エンジニアリングができないエンジニア

Wiresharkを使って、FTPパケットのやりとりを見よう

はじめに

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が作成されたことを確認して、必要なパッケージをインストールします。今回は、ftptcpdumpだけインストールします。

~ $ :~$ 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の挙動確認

FTP Serverであるftpd_serverIPv4アドレスを確認します。その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"
            },
        },
....

後ほど、WiresharkFTPのパケットを見るので、もう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.pcaplocalhostへコピーします。

# localhostにpcapのコピー
~ $ :~$ docker cp b1457c177a5a:ftp.pcap ~/Desktop

Wiresharkを使った挙動の確認

今回は、下図に流れに沿ってFTPの挙動を確認します。

  1. FTP ClientがFTP ServerのPort 21へ接続要求を行う

  2. FTP ServerがFTP Clientに対して、TCP接続を行う

  3. FTP Serverがデータコネクション用のPort 20を通知

  4. FTP ClientがFTP ServerのPort 20へファイルを送信

f:id:aki5151:20211019110109p:plain

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

f:id:aki5151:20211019110124p:plain

所感

実運用において問題が発生した際に、正常な通信の挙動を把握していないと、どのプロセス段階で問題が起きているが把握出来なかった。今回、Wiresharkを使ってFTPの正常な挙動を確認してみた。このようなことを積み重ねさえすれば、トラブルシューティングのノウハウの土台となるはずである。

参考文献

【Docker】FTPサーバコンテナ構築手順と使い方(Pure-ftpd Server) | インフラエンジニアの技術LOG

Docker Hub