WSL2 への FTP 接続は localhost じゃダメなのねえ~

WSL2 上の AlmaLinux で動かしている FTPサーバ(vsFTPd)にホスト側(親の Windows 側)から接続して put や get をしたいのだがうまくいかなくてハマってしまった。

WSL2 の AlmaLinux で起動している vsFTPd にパッシブモードで接続するんで(アクティブモードではデータ用接続が Windows 側で止められてしまうし、勝手に FW を触る権限もわしら外注作業員には許されてないけんね)、vsFTPd の設定にその旨を追加し put しようとしたんだけどうまくいかない。

<サーバ側の設定> ※関係あるところだけ

pasv_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

<クライアント操作>

C:\work>ncftp -u admin -p adminpassword localhost
NcFTP 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/temp
Directory successfully changed.
ncftp /var/www/html/temp > lcd /work/test
ncftp /var/www/html/temp > lls data*
data1.dat
ncftp /var/www/html/temp > set passive yes ←明示的にパッシブモードを指定
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: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  > O
put 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  > O
data1.dat:                                             120.00 B    0.00 B/s

正常に put できた。やっほう。

WSL2 を使ってテストをするのもなかなか大変だ。デーモンが起動時から listen しているポート以外への接続では気を付けないと。

トラックバック(0)

このブログ記事を参照しているブログ一覧: WSL2 への FTP 接続は localhost じゃダメなのねえ~

このブログ記事に対するトラックバックURL: https://blog.netandfield.com/mt/mt-tb.cgi/7309

コメントする

このブログ記事について

このページは、shinodaが2026年9月17日 00:09に書いたブログ記事です。

ひとつ前のブログ記事は「俺もついに豚人間の仲間入り(笑)」です。

次のブログ記事は「「あんていラーメン(味玉付き)」1,280円か・・・」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら