giampaolo / pyftpdlib

Extremely fast and scalable Python FTP server library
MIT License
1.65k stars 267 forks source link

TLS SNI extension support #490

Open arekm opened 5 years ago

arekm commented 5 years ago

pyftpdlib supports tls connections but lacks SNI support.

SNI is TLS extension which allows client to indicate server name to which it wants to connect. Then server can provide ssl certificate for that hostname. Such feature enables support for ftp virtual hosting over TLS, even on single IP.

Relevant RFC: https://tools.ietf.org/html/rfc6066

pyopenssl supports SNI using get_servername(): https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Connection.get_servername

ftp servers with SNI support: proftpd 1.3.6+ - http://www.proftpd.org/docs/contrib/mod_tls.html

Few ftp clients that support SNI: lftp - https://lftp.yar.ru/ filezilla - https://filezilla-project.org/

The implementation should allow dynamic loading of certificates to allow millions of certificates to be used (which is not something unexpected with letsencrypt being available).

So for example on connection, when SNI hostname is known, specific method is called which has to return certificate, key, etc. And that method gets implemented by pyftpdlib user to for example do open('/etc/something/%s.pem' % sanitized_hostname).read() or load cert from sql database etc. If client doesn't provide SNI extension the hostname could be set to None and our method could load some default certificate.

So get_servername() checks hostname and calls some used implemented load_certs(servername) which needs to return tuple with (certfile, keyfile[optional]).

giampaolo commented 5 years ago

Uhmm... this looks like a desirable nice feature... but it also requires time which I don't have right now. If you're brave enough feel free to submit a PR (or at least a draft).