ラズパイ間でリンクローカルアドレスFTP

## この記事について

「[ラズパイとWindowsでリンクローカルアドレスFTP（１）SSL無し](https://qiita.com/Saito5656/items/62b65dab4ddaef12eb0f)」と「[ラズパイとWindowsでリンクローカルアドレスFTP（２）SSL有り](https://qiita.com/Saito5656/items/e2ce01bbc74d7eb65005)」でラズパイ <-> WindowsPCのFTP転送を説明しました。  

本稿ではラズパイ <-> ラズパイでのFTP環境を構築する手順を説明します。  

<img width= 550 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565396/197afe1d-1edf-01b6-4a0f-eb00eb4fcbf6.png>

## 環境

### FTPクライアント

* Raspberry Pi 4 Model B Rev 1.2 / Raspberry Pi OS Lite 64-bit (Debian GNU/Linux 11 (bullseye))  
* hostname ： MyFTP  
* local-link static ip ： 169.254.100.101  

### FTPサーバー

* Raspberry Pi 4 Model B Rev 1.2 / Raspberry Pi OS Desktop 64-bit (Debian GNU/Linux 11 (bullseye))  
* hostname ： MyFTPserver  
* local-link static ip ： 169.254.80.79  

## SSL無し  

### FTPクライアント構築  

[ラズパイとWindowsでリンクローカルアドレスFTP（１）SSL無しのFTPクライアント構築](https://qiita.com/Saito5656/items/62b65dab4ddaef12eb0f#ftp%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E6%A7%8B%E7%AF%89)と同様の手順になります。  

### FTPサーバー構築

サーバー用のラズパイにvsftpdとiptables-persistentをインストールします。  

#### パッケージインストール  

```sh
#アップデート
sudo apt update  
sudo apt -y upgrade  

#python関連インストール
sudo apt install -y python3-dev python3-pip 　

#vsftpdとiptablesインストール
sudo apt install -y vsftpd iptables iptables-persistent

sudo apt update  
sudo reboot
```

#### vsftpd設定

ipv6は無効にするのでlisten=YESにします。  
それ以外は一般的な設定を用います。  

```sh: /etc/vsftpd.conf
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
ascii_upload_enable=YES
ascii_download_enable=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
```

起動時設定を有効にしてスタートします。  

```sh
sudo systemctl enable vsftpd
sudo systemctl start vsftpd
```

#### filer設定  

リンクローカルアドレス外とFTP通信させたくないのでfilter設定します。
[「ラズパイとWindowsでリンクローカルアドレスFTP（１）SSL無し」のfilter設定](https://qiita.com/Saito5656/items/62b65dab4ddaef12eb0f#filer%E8%A8%AD%E5%AE%9A)と同じです。  

### 動作確認  

#### サンプルファイル作成  

サーバーに転送するサンプルファイル:test.txtを作成します。  

``` sh
user@MyPi:~ $ echo "Hello FTP!" | tee test.txt
user@MyPi:~ $ ls
test.txt
```


#### クライアントからサーバーにログイン  

今回ラズパイFTPサーバーのリンクローカルアドレスは169.254.80.79でした。  

```sh
user@MyFTPserver:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.80.79  netmask 255.255.0.0  broadcast 169.254.255.255
```

FTPクライアントからFTPサーバーに接続します。  

```sh
user@MyPi:~ $ ftp
ftp> open 169.254.80.79
Connected to 169.254.80.79.
220 (vsFTPd 3.0.3)
```

サーバーのuserとログインパスワードを入力してサーバーにログインします。  

```sh
Name (169.254.80.79:user): user
331 Please specify the password.
Password: ラズパイFTPサーバーのログインパスワード
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
```

#### クライアントからサーバーにFTP転送  

最初はサーバー上にファイルが存在しません。

```sh
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
226 Directory send OK.
```

サーバーにtest.txtをputします。  

```sh
ftp> put test.txt
local: test.txt remote: test.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
11 bytes sent in 0.00 secs (114.2786 kB/s)
ftp>
```

test.txtがサーバー上にあることを確認します。  

```sh
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
-rw-------    1 1000     1000           11 Nov 23 04:47 test.txt
226 Directory send OK.
ftp>
```

#### サーバーからクライアントにFTP転送  

先ほど転送したtest.txtのファイル名を変更します。  

```sh
ftp> rename test.txt test1.txt
350 Ready for RNTO.
250 Rename successful.
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
-rw-------    1 1000     1000           11 Nov 23 04:47 test1.txt
226 Directory send OK.
ftp>
```

クライアントからサーバー上のtest1.txtをgetします。  

```sh
ftp> get test1.txt
local: test1.txt remote: test1.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for test1.txt (11 bytes).
226 Transfer complete.
11 bytes received in 0.00 secs (48.6072 kB/s)
ftp>
```

ftpから抜けてuser directoryにtest1.txtが存在することを確認します。  

```sh
ftp> exit
221 Goodbye.
user@MyPi:~ $ ls
test1.txt  test.txt
```

ラズパイFTPサーバーに対してラズパイFTPクライアントからput/getできることが確認できました。


## SSL有り  

### FTPクライアント構築  

[ラズパイとWindowsでリンクローカルアドレスFTP（２）SSL有りのFTPクライアント構築](https://qiita.com/Saito5656/items/e2ce01bbc74d7eb65005#ftp%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E6%A7%8B%E7%AF%89)と同様の手順になります。  

### FTPサーバー構築

[SSL無しと同様](https://qiita.com/Saito5656/items/3074af79f4d3d0eb01b6#ftp%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89)にサーバー用のラズパイにvsftpdとiptables-persistentをインストールします。  

SSL無しの手順と異なるのは  

* 自己署名入り証明書の発行  
* /etc/vsftpd.confでssl有効化と証明書の紐づけ  

の２点です。  

#### 自己署名入り証明書の発行  

ほぼ「[ftpサーバーの基本設定とSSL [ vsftpd ]](https://tech.kurojica.com/archives/59221/)」をそのまま使わせていただきました。御礼申し上げます。

入力項目はブランクでも証明書は作成できますが簡単に入力しておきました。パスワードは設定します。  

```sh
sudo openssl genrsa -aes256 2048 > vsftpd.key
sudo openssl req -new -key vsftpd.key -x509 -days 365 -out vsftpd.pem
mv vsftpd.key vsftpd.key.bak
sudo openssl rsa -in vsftpd.key.bak -out vsftpd.key
sudo chown root:root vsftpd.pem vsftpd.key
```

#### 証明書の配置

配置するdirectoryを作成します。

```sh
sudo mkdir -p /etc/pki/tls/private
sudo mkdir -p /etc/pki/tls/certs
```

作成した証明書と秘密鍵を配置します。  

```sh
sudo mv vsftpd.pem /etc/pki/tls/certs
sudo mv vsftpd.key /etc/pki/tls/private
```

#### vsftpd設定  

[SSL無しで設定した内容](https://qiita.com/Saito5656/items/3074af79f4d3d0eb01b6#vsftpd%E8%A8%AD%E5%AE%9A)に以下を追加して保存します。  

```sh: /etc/vsftpd.conf追加分
rsa_cert_file=/etc/pki/tls/cert/vsftpd.pem
rsa_private_key_file=/etc/pki/tls/private/vsftpd.key
ssl_enable=YES
```

起動時設定を有効にしてスタートします。  

```sh
sudo systemctl enable vsftpd
sudo systemctl start vsftpd
```

### 動作確認  

[「ラズパイとWindowsでリンクローカルアドレスFTP（２）SSL有り」の動作確認](https://qiita.com/Saito5656/items/e2ce01bbc74d7eb65005#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)と同様に、クライアント(MyFTP)のサンプルファイルをサーバー(MyFTPserver)に転送し、サーバー上でrenameしてクライアントで取得します。  


#### サンプルファイル作成  

サーバーに転送するサンプルファイル:test.txtを作成します。  

``` sh
user@MyPi:~ $ echo "Hello FTP!" | tee test.txt
user@MyPi:~ $ ls
ftp.crt　test.txt
```

lftpでFTPサーバーにログインします。リンクローカルアドレスはSSL無しと同様に169.254.80.79です。  

```sh
user@MyPi:~ $ lftp -u user 169.254.80.79
Password: ラズパイFTPサーバーのログインパスワード
lftp user@169.254.80.79:~>
```

サーバーに認証されていることを確認します

```sh
lftp user@169.254.80.79:~> ls
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
lftp user@169.254.80.79:/>
```

まだ何もファイルないことが確認できます。
認証に失敗しているとここでエラーが出ます。  

#### クライアントからサーバーにFTP転送  

サーバーにtest.txtをputします。  

```sh
lftp user@169.254.80.79:/> put test.txt
11 bytes transferred
lftp user@169.254.80.79:/>
```

test.txtがサーバー上にあることを確認します。  

```sh
lftp user@169.254.80.79:~> ls
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
-rw-------    1 1000     1000           11 Nov 23 05:30 test.txt
lftp user@169.254.80.79:~>
```

#### サーバーからクライアントにFTP転送  

先ほど転送したtest.txtのファイル名を変更します。  

```sh
lftp user@169.254.80.79:/> mv test.txt test1.txt
mv test.txt=>test1.txt [Waiting for response...]
rename successful
lftp user@169.254.80.79:/> ls
drwxr-xr-x    2 1000     1000         4096 May 03  2023 Bookshelf
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Desktop
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Documents
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Downloads
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Music
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Pictures
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Public
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Templates
drwxr-xr-x    2 1000     1000         4096 Nov 18 23:29 Videos
-rw-------    1 1000     1000           11 Nov 23 05:30 test1.txt
lftp user@169.254.80.79:/>
```

クライアントからサーバー上のtest1.txtをgetします。  

```sh
lftp user@169.254.80.79:/> get test1.txt
11 bytes transferred
lftp user@169.254.80.79:/>
```

lftpから抜けてラズパイのuser directoryにtest1.txtが存在することを確認します。  

```sh
lftp user@169.254.80.79:/> exit
user@MyPi:~ $ ls
ftp.crt　test1.txt  test.txt
```

SSLを有効化したラズパイFTPサーバーに対してラズパイFTPクライアントからput/getできることが確認できました。

## 参考文献  

* [Oracle® Linux 6セキュリティ・ガイド 3.3.1 opensslコマンドについて](https://docs.oracle.com/cd/E39368_01/security/ol_openssl_sec.html)
* [ftpサーバーの基本設定とSSL [ vsftpd ]](https://tech.kurojica.com/archives/59221/)
* [とほほのOpenSSL入門](https://www.tohoho-web.com/ex/openssl.html)