Ftplib ConnectionRefusedError: [Errno 111] Connection refused (python 3.5)
Asked Answered
B

1

3

I have a script that should connect to a FTP

from ftplib import FTP

with FTP('IP') as ftp:
   ftp.login(user='my user', passwd='my password')
   ftp.cwd('/MY_DIR')
   ftp.dir()

I have an error : ConnectionRefusedError: [Errno 111] Connection refused


The ftp is an EC2 with vsftpd

pasv_enable=YES
pasv_min_port=1024
pasv_max_port=1048
pasv_address=IP
pasv_addr_resolve=YES

Already tried :

The code work on other FTP with and without TLS (hosted on 1and1, OVH...)


I tried this script in NodeJS

const ftpClient = require('ftp-client');

const client = new ftpClient({
   host: "IP",
   port: 21,
   user: "My user", // defaults to "anonymous"
   password: "My password" // defaults to "@anonymous"
});

client.connect(() => {

  client.download('/MY_DIR/file','/tmp/file', (res) => {
        console.log(res)
  })
});

Works perfectly fine so I exclude a firewall problem


I have tried enable TLS

ssl_enable=YES
require_ssl_reuse=NO

then sudo service vsftpd restart

and use
FTP_TLS instead of FTP but did not work


Also I tried disable passive mode by setting

pasv_enable=NO

then sudo service vsftpd restart

and ftp.set_pasv(False)

didn't work either

Berthold answered 27/4, 2018 at 10:5 Comment(1)
Related: Cannot list FTP directory using ftplib – but FTP client works.Dorladorlisa
B
6

Solution

After using filezilla to debug the method, turn out that our FTP returned 0.0.0.0 despite we defined in /etc/vsftpd.conf

pasv_adress=IP

this post helped us : https://www.centos.org/forums/viewtopic.php?t=52408

You have to comment

listen_ipv6=YES

and enable

listen=YES

in /etc/vsftpd.conf


Also you can override the ftplib's class FTP if you can't access to vsftpd.conf of the FTP

class CustomFTP(ftplib.FTP):

    def makepasv(self):
        if self.af == socket.AF_INET:
            host, port = ftplib.parse227(self.sendcmd('PASV'))
        else:
            host, port = ftplib.parse229(self.sendcmd('EPSV'), self.sock.getpeername())

        if '0.0.0.0' == host:
            """ this ip will be unroutable, we copy Filezilla and return the host instead """
            host = self.host
        return host, port

to force the previous host if '0.0.0.0' is send

Berthold answered 27/4, 2018 at 16:27 Comment(3)
Thanks for this answer, it saved me a ton of time!Classicist
Thanks for your help! I also had to catch if the returned host was not starting with "192.168". I guess the server I connect to is wrongly configured...Hookworm
The vsftpd issue is discussed in details here: vsftpd returns 0,0,0,0 in response to PASV.Dorladorlisa

© 2022 - 2024 — McMap. All rights reserved.