FTP接続をおこなう
WSL(Ubuntu)からクラウド上 (AWS) にある EC2インスタンスにパッシブモードのFTPで接続する。
クライアントは lftp (https://launchpad.net/ubuntu/noble/arm64/lftp/4.9.2-2ubuntu1) を使ってftp接続を行う。(リンクはパッケージ (debファイル)をダウンロードするページです。)
Ubuntu (wsl)へのインストール方法 (lftp)
WindowsスタートメニューからPowershellのターミナルを起動し、ターミナルでwslを開く。
wsl -d Ubuntu-24.04
# aptでlftpを検索する
$ sudo apt search lftp
Sorting... Done
Full Text Search... Done
lftp/noble 4.9.2-2ubuntu1 amd64
Sophisticated command-line FTP/HTTP/BitTorrent client programs
# aptでlftpをインストールする
$ sudo apt update
$ sudo apt install lftp
サーバーの環境
OS: Amazon Linux 2023(AWS EC2インスタンスでクラウド環境にて起動)
サーバーにはvsftpdを使う。
準備
PASVコマンドがFTPサーバーのElastic IP (固定IP)を指定するように設定
クライアントがPASVコマンドをサーバーに対して送信すると、サーバー側はプライベートIPアドレスを返す。これはグローバルIPアドレスではないため、クライアント側から接続できない。vsftpdの設定ファイル (vsftpd.conf) でこのグローバルIPアドレス(=Elastic IP) を指定する必要がある。
# サーバーのグローバルIPにアクセスできるようにする。
# EC2インスタンスのElastic IPの値を設定。
pasv_address=xx.yy.zz.12
データコネクションの接続先ポートの範囲を限定する
データコネクションの接続先のサーバー側のポートがランダムに指定されるため、毎回ばらばらのポート番号に対してクライアントは接続を要求します。
そのため、ポートの範囲を限定することによって、EC2のセキュリティグループでインバウンドルールに指定することできるようにします。
ただし、0~1023はwell-knownポートであるため、はじかれる可能性があります。それ以外の範囲を指定するようにすれば大丈夫です。ただ、あまり広く範囲をとらない方が望ましいです。
# ポートの範囲の最小値
pasv_min_port=60000
# ポートの範囲の最大値
pasv_max_port=60100
ポートをEC2のセキュリティグループで開放する
上記で指定した範囲のポート番号に対してアクセスを許可するインバウンドルールを追加します。
上記手順を実行してもftpだとうまくいかない(ポート範囲の指定が反映していない)
$ ftp
ftp> open 35.19.1xx.1xx
Connected to 35.19.1xx.1xx.
220 (vsFTPd 3.0.5)
Name (35.19.1xx.1xx:username): root
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put ~/hello.txt /home/remote_user/hello.txt
local: /home/username/hello.txt remote: /home/remote_user/hello.txt
229 Entering Extended Passive Mode (|||29432|)
pasv_addressの固定IPに対して、pasv_min_portで指定したポート番号の下限値未満のポートに接続されてしまいました。29432という数字がftp実行結果で見えます。が、設定値は60000-60100のあいだです。シェルを閉じたり開いたりし、何回かやってみましたが上手くいかないようです。sudo systemctl restart vsftpd.service
を実行してvsftpdを再起動してみても、ダメでした。
上記手順の参考サイトはこちら
成功した方法:lftpを代わりに使う
接続先をグローバルIPを指定できるlftpでやってみたらできました。リモートのユーザーはrootでやっていますが、あとで変えたほうがいいです。ユーザーに対するアクセス許可のvsftpdでの設定はこちらの投稿を参考にしました。こちらの投稿ではrootユーザーをアクセス禁止にし、新しい専用のユーザーを作ってそちらでアクセスする方法も詳しく書いてあります。
$ lftp -u root ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
Password:
# 接続先のグローバルIPを指定。
lftp root@ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:~> set ftp:port-ipv4 35.19.1x.1x
# 接続先のポートの範囲を指定。
lftp root@ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:~> set ftp:port-range 65000-65535
# ASCIIモードでリモートユーザー (remote_user) のホームディレクトリにローカルのhello.txtというテキストファイルを転送する
lftp root@ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:~> put -a -O /home/remote_user /home/username/hello.txt -o
13 bytes transferred
これで無事にパッシブモードでFTP接続し、テキストファイルを転送することができました。
$ pwd
/home/remote_user
# リモートにファイルが転送されていることを確認
$ ls -la
total 40
drwx------. 3 remote_user remote_user 144 Apr 16 03:48 .
drwxr-xr-x. 5 root root 52 Mar 30 06:00 ..
-rw-------. 1 remote_user remote_user 1488 Apr 14 07:43 .bash_history
-rw-r--r--. 1 remote_user remote_user 18 Jan 28 2023 .bash_logout
-rw-r--r--. 1 remote_user remote_user 141 Jan 28 2023 .bash_profile
-rw-r--r--. 1 remote_user remote_user 492 Jan 28 2023 .bashrc
......
-rw-r--r--. 1 root root 13 Apr 16 03:48 hello.txt
参考サイト
パッシブモードについて
FTPのバイナリモードについて
lftpマニュアル