パッシブモードのFTPでAWSに接続する

# 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) を指定する必要がある。

```/etc/vsftpd/vsftpd.conf
# サーバーのグローバルIPにアクセスできるようにする。
# EC2インスタンスのElastic IPの値を設定。
pasv_address=xx.yy.zz.12
```

### データコネクションの接続先ポートの範囲を限定する
データコネクションの接続先のサーバー側のポートがランダムに指定されるため、毎回ばらばらのポート番号に対してクライアントは接続を要求します。

そのため、ポートの範囲を限定することによって、EC2のセキュリティグループでインバウンドルールに指定することできるようにします。

ただし、0～1023はwell-knownポートであるため、はじかれる可能性があります。それ以外の範囲を指定するようにすれば大丈夫です。ただ、あまり広く範囲をとらない方が望ましいです。

```/etc/vsftpd/vsftpd.conf
# ポートの範囲の最小値
pasv_min_port=60000

# ポートの範囲の最大値
pasv_max_port=60100
```


### ポートをEC2のセキュリティグループで開放する
上記で指定した範囲のポート番号に対してアクセスを許可するインバウンドルールを追加します。

## 上記手順を実行してもftpだとうまくいかない（ポート範囲の指定が反映していない）

```.bash
$ 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を再起動してみても、ダメでした。

#### 上記手順の参考サイトはこちら

https://dev.classmethod.jp/articles/to-be-aware-of-when-settingup-ftpserver-with-aws/

### 成功した方法：lftpを代わりに使う
接続先をグローバルIPを指定できるlftpでやってみたらできました。リモートのユーザーはrootでやっていますが、あとで変えたほうがいいです。ユーザーに対するアクセス許可のvsftpdでの設定は[こちら](https://qiita.com/hirai-11/items/8681d7a478db82f6b1e8#root%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%A7ftp%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B)の投稿を参考にしました。こちらの投稿ではrootユーザーをアクセス禁止にし、新しい専用のユーザーを作ってそちらでアクセスする方法も詳しく書いてあります。

```.bash
$ 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接続し、テキストファイルを転送することができました。

```.bash
$ 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
```

### 参考サイト
#### パッシブモードについて
https://dev.classmethod.jp/articles/survey-ftp-clients-passive-mode-behavior/

http://cos.linux-dvr.biz/archives/131#google_vignette

#### FTPのバイナリモードについて
[Binary mode FTP and unexpected line endings -FTP binary and ASCII transfer types and the case of corrupt files](https://www.jscape.com/blog/ftp-binary-and-ascii-transfer-types-and-the-case-of-corrupt-files)


#### lftpマニュアル

https://lftp.yar.ru/lftp-man.html