i know, to date, the general recommendation to configure ftp is to use a single certificate, for the servers FQDN, and tell clients to use that for the host. obviously if a client tries using their own website domain to access ftp, it's ok for clear text, but will show cert warnings for TLS, which leads to lots of emails from clients asking about 'is it safe?', or 'what host do i use?' etc, or just going back to unencrypted ftp. i know some of you will suggest dropping ftp and just use ssh, but if clients struggle with ftp, they're not going to cope with ssh, especially since i would only allow key-based ssh access. however, i've found a document that suggests we can use SNI with pure-ftpd by using pure-certd. so i'm just asking here if anyone has actually managed to do this? if not, is it worth creating a feature request for it? if it can be made to work with ispconfig/letsencrypt i think it would make secure ftp a lot easier to setup and support whilst simultaneously reducing the amount of questions from clients, but not much point creating a feature request if i'm the only one who'd want it. i'm including the relevant part of the document below, the full link is here: https://download.pureftpd.org/pub/pure-ftpd/doc/README.TLS
I imagine the suggestion is usually to switch to SFTP rather than FTP, and most ftp clients support both. Setting up only rsa key access for a client would be an issue, though not a huge one (most customers who can take instructions to configure their FTP program now would likely be able to follow instructions to paste in the keys, and those which need help following instructions for FTP would still need help to setup SFTP). I'd never considered pure-ftpd for SNI, but it is intriguing. It's a feature request for postfix/dovecot, and if that is ever implemented, keeping pure-ftpd in mind would make sense (it should be easier, as you already have http on all the ftp servers; not so with all mail servers).
pure-ftpd with SNI support (working & tested implementation) using Let's Encrypt (certbot) You have already install a Debian server + pure-ftpd-mysql + certbot as minimal configuration and pure-ftpd has configured to accept tls connections. --- Geather files (Debian) apt source pure-ftpd-mysql cd pure-ftpd-1.0.49 append the pure-certd binary in to build tree nano debian/rules append sbin binary pure-certd append sbin binary pure-certd end of the line that start with sbin Step 1 Configure ./configure --with-mysql --with-tls --with-everything Step 2 build package dpkg-buildpackage -uc -us Step 3 Install package that includes pure-certd apt install -f ../pure-ftpd-mysql_1.0.49-4.1_amd64.deb Step 4 Create TLS SNI parser shell script nano /bin/pure-cert-check.sh #! /usr/bin/sh #echo "$(env)" > /root/sni_log echo 'action:strict' echo 'cert_file:/etc/letsencrypt/live/'${CERTD_SNI_NAME}'/fullchain.pem' echo 'key_file:/etc/letsencrypt/live/'${CERTD_SNI_NAME}'/privkey.pem' echo 'end' Step 5 Start pure-certd daemon pure-certd --run /bin/pure-cert-check.sh --socket /var/run/ftpd-certs.sock --pidfile /var/run/pure-certd.pid -B Step 6 Append a line in to /usr/sbin/pure-ftpd-wrapper 'NoTruncate' => ['-0'], +++ 'ExtCert' => [ '-3 %s', \&parse_string], 'PassivePortRange' => ['-p %d:%d', \&parse_number_2], Step 7 ExtCert create (pure-ftpd.conf won't work...) echo "/var/run/ftpd-certs.sock" > /etc/pure-ftpd/conf/ExtCert Step 8 systemctl restart pure-ftpd-mysql.service You should see something like; Aug 19 23:42:20 testing systemd[1]: Stopping pure-ftpd-mysql.service... Aug 19 23:42:20 testing pure-ftpd-mysql[207068]: Stopping ftp server: pure-ftpd. Aug 19 23:42:20 testing systemd[1]: pure-ftpd-mysql.service: Succeeded. Aug 19 23:42:20 testing systemd[1]: Stopped pure-ftpd-mysql.service. Aug 19 23:42:20 testing systemd[1]: Starting pure-ftpd-mysql.service... Aug 19 23:42:20 testing pure-ftpd-mysql[207077]: Starting ftp server: Aug 19 23:42:20 testing pure-ftpd-mysql[207084]: Running: /usr/sbin/pure-ftpd-mysql -l mysql:/etc/pure-ftpd/db/mysql.conf -l pam -u 1000 -p 35000:50000 -E -A -Y 1 -O clf:/var/log/pure-ftpd/transfer.log **-3 /var/run/ftpd-certs.sock** -P 165.227.130.119 -J HIGH -j -B Aug 19 23:42:20 testing systemd[1]: Started pure-ftpd-mysql.service. in the syslog. Step 8 Use it! Cert 1 Cert 2 Have nice day... P.S when you search all over the web (pure-ftpd sni support) this is the 1st page index of the google that is why i put this in here. I couldn't find any other step by step document then i experimented a way, succeeded to do this and i'm sharing it.
Hi, I'm trying to apply your tutorial, but the above step is not clear to me. Where exactly should I add the line (but there are three lines actually) in hte pure-ftpd-wrapper file? Kind regards Aldo
Hi Aldo, I assume that you are using debian distribution. I didn't test other ones. The file pure-ftpd-wrapper is actually using files under the directory /etc/pure-ftpd/conf config files but some reason the ExtCert file wasn't wrapping in the run time. That is why i am adding the line in the wrapper file, normally the line with ExtCert should be in the wrapper file but in bullseye there wasn't or pure-ftpd developers forget to put it... The line 'ExtCert' => [ '-3 %s', \&parse_string], has no definite line number, i've just tried out and find that it works in line 94 in wrapper file. If the wrapper file buildup with 3 lines then there is an issue that i don't know, if it is a full file like screenshot that i appened in this message then just append a line to line94; 'ExtCert' => [ '-3 %s', \&parse_string], thats all. I wrote a full tutorial in my blog, the commands are global so it should not be hard to use, it's Turkish you can use translator allways. Blog post is: https:// yasinkarabulak.com/tr/gnu-linux/hosting-ortami/ftp-server/tls-sni-destekli-pure-ftpd-ftps-server-kurulumu/ ---- Best regards.
Hi Yasin, thank you very much for your very clear answer. I made some steps ahead, but the system doesn't work as expected (i.e., doesn't work at all now): the certificate handler script is now invoked correctly, with the correct environment variable the script handles correctly the SNI, echoing the correct strings to stdout BUT... the pure-ftpd server terminates incorrectly the TLS session and the connection is dropped In syslog I can find the right messages + a error like: Code: Mar 29 23:30:03 s0 pure-ftpd: (?@IPADDRESS) [INFO] SNI: [SERVER_NAME_REQUESTED_BY_CLIENT] Mar 29 23:30:04 s0 pure-ftpd: (?@IPADDRESS) [ERROR] Cert handler not ready I guess that the socket file in /var/run/ looks right: Code: srw------- 1 root root 0 29 mar 23.28 ftpd-certs.sock (are the permissions correct?) I looked at your blog pages also (very well done), but couldn't find any other clue to solve the issue. If you have any other hint... Kind regards Aldo
Solved! I forgot to add "echo end" as last instruction of my shell script for SNI handling. Now it works as expected! Thank you very much again for your hints, Yasin. I coudn't configure pure-certd on myself. Kind regards Aldo
Resuming this thread because a new problem arose. SNI works but... After the first-time connection to a domain, subsequent connections with FileZilla client show a pop-up warning saying: Code: Warning! You have previously connected to this server and it has supported TLS session resumption on the data connection. Only continue after you have spoken to the server administrator or server hosting provider. TLS session resumption on the data connection is an important security feature to protect against data connection stealing attacks. If you continue, transferred files may be intercepted or their contents replaced by an attacker. Host: <here the hostname is showed> Port: 21 [ OK ] [ Cancel ] Googling this error showed that just few people in the world faced such issue, I guess because pure-ftpd SNI mechanism is not (yet?) widely adopted and maybe pure-ftpd doesn't properly manage TLS together with SNI. In fact, disabling the SNI management in pure-ftpd there is no problem connecting to my server, provided that only the proper FQDN of the server is used for the connection. Any suggestion? Kind regards Aldo