Ubuntu – Trying to connect to vsftpd, Failed to retrieve directory listing

vsftpd

Something is really not working here. I have the following error in using FileZilla to connect to a remote machine running vsftpd:

Command:    LIST
Error:  Connection timed out
Error:  Failed to retrieve directory listing

I am trying to set up FTP services on 3 machines behind a residential ISP firewall. All are Ubuntu 12.04 Server LTS, and I am restricted from using port 21 externally at the remote site.

Well.. Ok, I confess, it's myself who is imposing the restriction. I just wanted to sound like I was working for a real company. Anyway, only 1 of the 3 systems could have been assigned to 21, so it would still be an issue.

I have tried the solutions for adding "pasv_…" lines, but I still cannot get past the LIST stage of connecting.

So, having failed that, what might the problem be?

I read on this site that I need to forward ports 20 and 21. Right now the remote sites have ports like 10000, 11000, 12000 forwarded to the internal port 21 on each of the systems. Should I forward some additional ports in to 20? it doesn't make sense because that port isn't even open, vsftpd is only listening on 21.

All I want is for a successful ftp connection through these forwarded ports, I am frustrated because I have successfully forwarded for services like SSH, apache2, etc and I don't get what is broken here.

thx Joren for correcting my formatting!


EDIT: I have been messing around with my testing VPS which is directly exposed to the internet, I installed vsftpd just to see what happens, and the output of 'netstat -tuna' shows that a successful connection from my filezilla client looks like this:

tcp        0      0 vps.vps.vps.vps:21       fi.le.zil.la:54288      ESTABLISHED
tcp        0      0 vps.vps.vps.vps:46403    fi.le.zil.la:54289      TIME_WAIT

Note: the FTP server at my VPS also didn't work at first, due to a completely unrelated issue involving virtualized environments ("500 OOPS: priv_sock_get_cmd"). Read: I am starting to see that Ubuntu's vsftpd doesn't work 'out-of-the-box' like apache2 and sshd do, for any frustrated novice sysadmins out there, don't think you're stupid if it isn't working first thing…

My testing VPS doesn't have a firewall, so all ports are directly available for access by the FTP daemon. After running this test, I see that it is possible that this secondary connection is being blocked at the remote site where I'm having issues (random ports such as 46403).

At least now I have confirmed that there are no NAT issues with my Filezilla, because clearly filezilla is opening random ports and talking with my VPS ok.

The one thing that makes no sense, is the config 'connect_from_port_20=YES' is set on my VPS FTP config, yet I can't see any connections using port 20!!! This is why I don't even know if this port needs to be forwarded behind a firewall.

One of my knowledge deficiencies is I don't even know what port 20 does, and I can't learn through experience because I've never seen any indication the port is ever used duing connecting, downloading or uploading.


OK, I found some problems (there's clearly more then one thing wrong) – This has to do with port forwarding.

Suspect original problem (before customizing vsftpd.conf)

  1. Filezilla initially connects to remote port 10000, ==> goes to 21 on internal FTP server (ok)
  2. FTP server opens a random port (NOT 20) like 45678, but the router obviously doesn't have a rule for this randomly assigned port. It sends a message telling filezilla to also connect to 45678.
  3. Filezilla client opens up its own port on my end behind NAT(ok)
  4. Filezilla sends connection request to 45678, but the remote router doesn't accept the connection, as there is no forwarding rule for that port.

Now, the problem(s) I created:

pasv_enable=YES
pasv_min_port=10000
pasv_max_port=10000
  1. Filezilla connects to remote port 10000, ==> goes to 21 on internal FTP server (ok)
  2. FTP server opens the only port it can, 10000, [stupid moment] because I have that port in my head associated with that system. But 10000 is actually the WAN side counterpart for 21 on this system. Server sends a message for FileZilla to connect to 10000, and listens internally on 10000
  3. Filezilla client opens up its own random port on my end (ok)
  4. Filezilla tries the secondary connection at port 10000, the remote router deflects it to port 21 again where it must be ignored or lost, while the FTP server waits for a connection to internal port 10000 that never arrives. (fail)

Second problem I created: I tried to bind port 21 this time, but I think that messed up filezilla.

pasv_enable=YES
pasv_min_port=21
pasv_max_port=21
  1. Filezilla connects to remote port 10000, ==> goes to 21 on internal FTP server (ok)
  2. FTP server opens port 21 (or maybe fails because 21 is already used) if it succeeded, it sent a message for filezilla to connect to port 21.
  3. Filezilla client opens up its own random port on my end (ok)
  4. Filezilla sends a request for LIST to 21, which the router is not going to accept…(fail)

Conclusion: as long as the port is being changed by a router, the FTP server will never be able to tell the client to connect to the right port. If you try to use the internal port, the client will run up against the router. If you try to specifiy the external port, the router will deflect the incoming connection to a different number — which the server was not expecting.


I will test a solution and report back here with the results.

I think, because the FTP server protocol appears to tell the client which port to connect to, that secondary connection MUST have the same external port number as internal.

I will call this a 'secondary connection' and I think it has something to do with the port 20 thing that I don't understand.

So, I will contact the remote site and have an additional port forwarded directly, so the FTP server can open a connection internally, and the client will be able to send a connection request to that exact port number.

New plan:

(note: the '%' is meant to show the port getting changed by the remote router.)

 

server #1
    primary connection: 21 <--%--> 10000 
    secondary connection 10001 <-----> 10001
    vsftp.conf:
        pasv_min_port=10001
        pasv_max_port=10001

server #2
    primary connection 21 <--%--> 11000
    secondary connection 11001 <-----> 11001
    vsftp.conf:
        pasv_min_port=11001
        pasv_max_port=11001

server #3
    primary connection 21 <--%--> 12000
    secondary connection 12001 <-----> 12001
    vsftp.conf:
        pasv_min_port=12001
        pasv_max_port=12001

Best Answer

My router (fritz.box, germany) had to be configured unlocking the higher ports in same wa outgoing as ingoing! (above: this "pasv_min.. and ...max" here inserted/prescribed by debian-vsftpd):

Adding a range of unblocked ports in the Fritz!Box-Router with the corresponding button:
"Other Applications" -> "Portokoll": TCP, von Port: 13450, bis Port: 13500 (or high-ports within a range ~50), "an Computer": RasPi, "an IP_Adresse": (outgreyed, the internal LAN-IP-Adress for my "RasPi" given by the fritz.box-router) -> and here it comes: "an Port" (=the same range!): 13450, "bis Port": 13450, and this is working fine with vsftpd and FTPS (AUTH TLS / SSL-Tranfer with OpenSSL + strong DES-CBC3-SHA cipher)...

This will forward the right ports and connect requests from and to my little RasPi-"Server" (behind the F.B.-NAT) to the incomig/outgoing external IP-request ON THE SAME RANGE OF HIGH(ER)-PORTS, like right-connected "cables" to the same ports on the internal part...

A possible vsftp-config-file "/etc/vsftpd.conf":

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
force_dot_files=YES

ssl_enable=YES
force_local_data_ssl=NO
force_local_logins_ssl=NO
allow_anon_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
# rsa_cert_file=/etc/ssl/private/vsftpd.pem   # not working alright, so single-lined:
rsa_cert_file=/etc/ssl/private/vsftpd.crt
rsa_private_key_file=/etc/ssl/private/vsftpd.key

pasv_enable=YES
# pasv_promiscuous=YES
# port_promiscuous=YES
pasv_addr_resolve=YES
pasv_address=[yourDNSadress.no-ip.com] # for Dynamic-DNS the routers daily changing IP.
# port_enable=YES
pasv_min_port=13450
pasv_max_port=13500
file_open_mode=0755
Related Question