WSL2 上の AlmaLinux で動かしている FTPサーバ(vsFTPd)にホスト側(親の Windows 側)から接続して put や get をしたいのだがうまくいかなくてハマってしまった。
WSL2 の AlmaLinux で起動している vsFTPd にパッシブモードで接続するんで(アクティブモードではデータ用接続が Windows 側で止められてしまうし、勝手に FW を触る権限もわしら外注作業員には許されてないけんね)、vsFTPd の設定にその旨を追加し put しようとしたんだけどうまくいかない。
<サーバ側の設定> ※関係あるところだけ
pasv_enable=YES#pasv_address=127.0.0.1pasv_address=172.28.196.77pasv_addr_resolve=NOpasv_min_port=50000pasv_max_port=50010
<クライアント操作>
C:\work>ncftp -u admin -p adminpassword localhostNcFTP 3.2.6 (Nov 15, 2016) by Mike Gleason (http://www.NcFTP.com/contact/).Connecting to 127.0.0.1...(vsFTPd 3.0.5)Logging in...Login successful.Logged in to localhost.ncftp /home/admin > cd /var/www/html/tempDirectory successfully changed.ncftp /var/www/html/temp > lcd /work/testncftp /var/www/html/temp > lls data*data1.datncftp /var/www/html/temp > set passive yes ←明示的にパッシブモードを指定ncftp /var/www/html/temp > put data1.datThe remote file "data1.dat" already exists.Local: 120 bytes, dated 09/10/26 14:30:04.Remote: 0 bytes, dated 09/10/26 23:42:16.[O]verwrite? [R]esume? [A]ppend to? [S]kip? [N]ew Name?[O!]verwrite all? [R!]esume all? [S!]kip all? [C]ancel > Oput data1.dat: server said: Failed to establish connection. ←失敗しちゃう
サーバ側には 0バイトの data1.dat ファイルができている。制御用の接続はちゃんと生きてるんで、空のファイルを作成して、実際にデータ用の接続経由でデータを送ろうとして失敗してるんだなあ・・・
結局原因は、「Windows」と「WSL(仮想的なLinux)」の間での通信で、制御用接続(21番ポート)へのフォワードはうまくいっているが、データ用接続(50000~50010番ポートのいずれか)へのフォワードがうまくいっていないからであった。
WSL2 が立ち上がっている場合、Windows は「WSL2側で常に接続待ちになっているポートのみ」は「localhost」への接続の場合は WSL2 側にフォワードをしてくれるのだ。
「常に接続待ちになっているポート」というのは、「WSL2 上の OS で動くアプリが起動時に口を開けてまっているポート」のことで、httpd なら 80番と 443番。あるいは 8080番など。FTPd なら、21番ポート(20番はサーバからクライアントへの接続用なので違う)である。
つまり、httpd や FTPd が起動時に開けるポート番号だ。
起動後のデーモンが、例えばパッシブ通信のために一時的に開けたポート番号はフォワードされないのである。
つまり、localhost の 21番ポートに接続に行くと、Windows が自分自身の 127.0.0.1 のポート21番ではなく、WSL2(今回は AlmaLinux)の 127.0.0.1 の 21番ポートにフォワードしてくれるが、これが localhost の 50010 番宛てだと、WSL2 ではなく自分自身(Windows)の 50010番ポートにデータを投げるのである(フォワードしない)
解決策は「localhost(127.0.0.1)」への接続ではなく、「実際の WSL2 の中で動いている OS の IPアドレス」へ接続することである。
そうすれば、フォワードは必要ない。指定した IP アドレスのポート番号に向けてデータを流すだけなので、「誤って自分自身(Windows)にデータを流すことはない」わけだ。
<対応>
まず、WSL2 側で自分の IP を調べる(困ったことに、WSL2 は起動する度にランダムに IP アドレスを割り付ける。まあ、といっても、特別なことがなければ前回割り当てられた IP アドレスと同じものが割り当てられるけど)。
[root@KING html]# ip addr show eth0 | grep inet
inet 172.28.196.77/20 brd 172.28.207.255 scope global eth0
inet6 fe80::215:5dff:fe93:63da/64 scope link proto kernel_ll
次に、vsFTPd のパッシブモードの宛先 IP をこの IPアドレス(172.28.196.77)に変更する。
[root@KING html]# tail /etc/vsftpd/vsftpd.conf
use_localtime=YESpasv_enable=YES
#pasv_address=127.0.0.1
pasv_address=172.28.196.77
pasv_addr_resolve=NO
pasv_min_port=50000
pasv_max_port=50010
そして、Windows 側の FTP クライアントでこの IP アドレスに接続する。
C:\work>ncftp -u admin -p adminpassword 172.28.196.77
NcFTP 3.2.6 (Nov 15, 2016) by Mike Gleason (http://www.NcFTP.com/contact/).
Connecting to 172.28.196.77...
<略>
これで、put してみると、
ncftp /var/www/html/temp > put data1.dat
The remote file "data1.dat" already exists.
Local: 120 bytes, dated 09/10/26 14:30:04.
Remote: 0 bytes, dated 09/10/26 23:56:39.
[O]verwrite? [R]esume? [A]ppend to? [S]kip? [N]ew Name?
[O!]verwrite all? [R!]esume all? [S!]kip all? [C]ancel > Odata1.dat: 120.00 B 0.00 B/s
正常に put できた。やっほう。
WSL2 を使ってテストをするのもなかなか大変だ。デーモンが起動時から listen しているポート以外への接続では気を付けないと。

コメントする