-
-
Notifications
You must be signed in to change notification settings - Fork 273
Description
With pyftpdlib listening on IPv6, if a client connects from an IPv6 Link-Local IP [fe80:...]
the connection will fail and the server logs the following:
$ python3 -m pyftpdlib -Vi ::
[I 2025-08-21 19:48:20] concurrency model: async
[I 2025-08-21 19:48:20] masquerade (NAT) address: None
[I 2025-08-21 19:48:20] passive ports: None
[I 2025-08-21 19:48:20] >>> starting FTP server on :::2121, pid=1033053 <<<
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[] FTP session opened (connect)
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[anonymous] USER 'anonymous' logged in.
[E 2025-08-21 19:48:23] unhandled exception in instance <FTPHandler(id=140507583070288, addr='fe80::5054:ff:fe2a:b374:42344', user='anonymous')>
Traceback (most recent call last):
File "/usr/lib/python3.13/site-packages/asyncore/__init__.py", line 83, in read
obj.handle_read_event()
~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/site-packages/asyncore/__init__.py", line 420, in handle_read_event
self.handle_read()
~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/ioloop.py", line 967, in handle_read
asynchat.async_chat.handle_read(self)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/usr/lib/python3.13/site-packages/asynchat/__init__.py", line 171, in handle_read
self.found_terminator()
~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1574, in found_terminator
self.pre_process_command(line, cmd, arg)
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1693, in pre_process_command
self.process_command(cmd, arg, **kwargs)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1704, in process_command
method(*args, **kwargs)
~~~~~~^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 2253, in ftp_EPSV
self._make_epasv(extmode=True)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 2152, in _make_epasv
self._dtp_acceptor = self.passive_dtp(self, extmode)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 420, in __init__
af = self.bind_af_unspecified((local_ip, 0))
File "/usr/lib/python3.13/site-packages/pyftpdlib/ioloop.py", line 1072, in bind_af_unspecified
raise OSError(err)
OSError: [Errno 22] Invalid argument
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[anonymous] FTP session closed (disconnect).
the issue can be reproduced by connecting from curl:
curl 'ftp://[fe80::5054:ff:fe2a:b374%virhost0]:2121/'
in the curl-command, because the IPv6-address is Link-Local, the IP fe80::5054:ff:fe2a:b374
must be suffixed with the zone index, such as the name of the NIC which holds the address (virhost0
as above), otherwise curl will complain that the address is invalid and refuse to connect.
conversely, this is also the issue on pyftpdlib's side; the value of local_ip
in self.bind_af_unspecified((local_ip, 0))
is just the client-IP itself, without the required zone-index suffix, so python throws the exception.
BTW, thank you for such an excellent library! it has been serving me very well, to the point that I haven't found a bug until just now :-)