6

I installed vsFTP in a Debian box. When manually upload file using ftp command, it's ok. i.e, the following session works:

john@myhost:~$ ftp xxx.xxx.xxx.xxx 5111
Connected to xxx.xxx.xxx.xxx.
220 Hello,Welcom to my FTP server.
Name (xxx.xxx.xxx.xxx:john): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put st.zip
local: st.zip remote: st.zip
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 File receive OK.
12773 bytes sent in 0.00 secs (277191.8 kB/s)
ftp> 221 Goodbye.

(Please noted that as above, I configured vsFTP server to use a non-default port,e.g 5111 for some reason)

Now when I write a script in python to upload file programmatically, it failed. the error says 'time out', as the following session shows:

john@myhost:~$ ipython
Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14) 
Type "copyright", "credits" or "license" for more information.

IPython 0.8.4 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import ftplib

In [2]: ftp=ftplib.FTP()                                                    

In [3]: ftp.connect('xxx.xxx.xxx.xxx','5111')                                
Out[3]: "220 Hello,Welcom to my FTP server."

In [4]: ftp.login('ftpuser','ftpuser')                              
Out[4]: '230 Login successful.'

In [5]: f=open('st.zip','rb')                              

In [6]: ftp.storbinary('STOR %s' % 'my_ftp_file.zip', f)                            
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)

...

/usr/lib/python2.5/ftplib.pyc in ntransfercmd(self, cmd, rest)
    322             af, socktype, proto, canon, sa = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0]
    323             conn = socket.socket(af, socktype, proto)
--> 324             conn.connect(sa)
    325             if rest is not None:
    326                 self.sendcmd("REST %s" % rest)

/usr/lib/python2.5/socket.pyc in connect(self, *args)

error: (110, 'Connection timed out')

I guess there is some wrong config in my vsFTP server, but cannot figure it out. Anyone can help ?

my vsFTP config is:


listen=YES

connect_from_port_20=YES
listen_port=5111
ftp_data_port=5110

# Passive FTP mode allowed
pasv_enable=YES
pasv_min_port=5300
pasv_max_port=5400

max_per_ip=2
bluish
  • 26,356
  • 27
  • 122
  • 180
John Wang
  • 4,562
  • 9
  • 37
  • 54
  • This question / answer also helps https://stackoverflow.com/questions/50060037/ftplib-connectionrefusederror-errno-111-connection-refused-python-3-5 – Tim Oct 20 '20 at 08:44

1 Answers1

7

The timeout doesn't happen until you try to send the data, so you were able to connect to the server successfully. The only difference I see is that ftplib uses passive mode by default, whereas your command-line client does not appear to. Try doing

ftp.set_pasv(False)

before initiating the transfer and see what happens.

Note that non-passive mode is essentially obsolete because it cannot be used across NAT firewalls, so you should probably configure vsFTP to allow passive mode.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • That's works! Thank you Jim. But why the python ftplib can not use pasive mode automatically ? My vsFTP IS configured to allow passive mode indeed. Could it be a configuration mistake in vsFTP? I have edited my question post and added my vsftpd.conf there. – John Wang Jul 29 '10 at 02:13
  • The problem is not in ftplib but in vsFTP, which for some reason is not allowing passive mode. Are you sure the vsFTP config is in the right place? – Jim Garrison Jul 29 '10 at 14:55
  • Yes,Jim,It's a problem of the vsFTP config. Finally I found the reason:my vsFTP is deployed in a NAT. So even though I have set the vsFTP option "pasv_enable=YES", I should also have to set another option "pasv_address=my.external.ip.address". After that, everything is ok ! Thank you, thank to the warmhearted community! – John Wang Jul 30 '10 at 12:22