I came across this topic a while back: https://forum.howtoforge.com/threads/pure-ftpd-sni-with-letsencrypt.85488/#post-438345 Post #4 forms a great baseline. Though it isn't truely ISPC integrated and therefor doesn't support alternative names in a certificate. This tutorial lets you enable SNI based certificates (including alternative names) in Pure-FTPD, making use of your ISPC database to determan which ceritificate to use and its path. (Based on an Ubuntu 24.04, MariaDB and Acme.sh ISPC installation) Summary: - Create file with database info (user, pass, db, host, query) - Create script for wrapper to use - Enable in wrapper - Startup Install: Unlike steps 1 to 3 in the original post, on Ubuntu 24.04 it's not necessary to compile and install a new Pure-FTPD package. Pure-CERTD already is installed, as it's part of the Pure-FTPD-Common package. It just isn't enabled yet in Pure-FTPD. How that is in other versions and distro's I don't know. Step 1 Create database variables file Code: nano /etc/pure-ftpd/db/ExtCert.conf Code: user="<db user>" password="<db pass>" dbname="<db name>" hosts="<db host>" query="SELECT domain,document_root,ssl_letsencrypt FROM web_domain WHERE domain_id = (SELECT parent_domain_id FROM web_domain WHERE domain = '$sni_name' AND (type = 'alias' OR type = 'subdomain') AND ssl_letsencrypt_exclude = 'n' AND active = 'y' AND server_id = <server id>) AND type = 'vhost' AND web_domain.ssl = 'y' AND active = 'y' AND server_id = <server id> UNION SELECT domain,document_root,ssl_letsencrypt FROM web_domain WHERE domain = '$sni_name' AND type = 'vhost' AND web_domain.ssl = 'y' AND active = 'y' AND server_id = <server id>;" Replace <...> with your server's info. Code: chmod 600 /etc/pure-ftpd/db/ExtCert.conf Step 2 Create TLS SNI parser shell script Code: nano /bin/pure-cert-check.sh Code: #! /usr/bin/bash #echo "$(env)" > /root/sni_log sni_name=${CERTD_SNI_NAME} source /etc/pure-ftpd/db/ExtCert.conf result=$(mariadb --host="$hosts" --user="$user" --password="$password" --database="$dbname" --silent --execute="$query") cert=$(echo $result | awk '{print $1}') path=$(echo $result | awk '{print $2}') le=$(echo $result | awk '{print $3}') if [[ $cert != '' ]] then if [[ $le = 'y' ]] then certpath=$path"/ssl/"$cert"-le.crt" keypath=$path"/ssl/"$cert"-le.key" echo 'action:strict' echo 'cert_file:'$certpath echo 'key_file:'$keypath echo 'end' elif [[ $le = 'n' ]] then certpath=$path"/ssl/"$cert".crt" keypath=$path"/ssl/"$cert".key" echo 'action:strict' echo 'cert_file:'$certpath echo 'key_file:'$keypath echo 'end' else echo 'action:default' echo 'end' fi else echo 'action:default' echo 'end' fi Code: chmod +x /bin/pure-cert-check.sh The script gets the SNI name used in the connection and looks it up in ISPC's database. If it is an alias or subdomain then the corresponding vhost is returned. LE excluded hostnames are excluded in the return. Furthermore the vhost's document_root is returned and if the certificate is LE or not. With that the path to the certificate and key are constructed. If the SNI name lookup doesn't return anything then Pure-FTPD's default certificate will be used. Step 3 Append a line in to /usr/sbin/pure-ftpd-wrapper Code: 'NoTruncate' => ['-0'], +++ 'ExtCert' => [ '-3 %s', \&parse_string], 'PassivePortRange' => ['-p %d:%d', \&parse_number_2], Step 4 ExtCert create (pure-ftpd.conf won't work...) Code: echo "/var/run/ftpd-certs.sock" > /etc/pure-ftpd/conf/ExtCert Step 5 Start pure-certd daemon Edit: Post #4 contains an alternative option which creates a service!!! Code: pure-certd --run /bin/pure-cert-check.sh --socket /var/run/ftpd-certs.sock --pidfile /var/run/pure-certd.pid -B Add a cronjob to run the command at startup Code: nano /var/spool/cron/crontabs/root Code: * * * * * /usr/local/ispconfig/server/server.sh 2>&1 | while read line; do echo `/bin/date` "$line" >> /var/log/ispconfig/cron.log; done * * * * * /usr/local/ispconfig/server/cron.sh 2>&1 | while read line; do echo `/bin/date` "$line" >> /var/log/ispconfig/cron.log; done +++ @reboot pure-certd --run /bin/pure-cert-check.sh --socket /var/run/ftpd-certs.sock --pidfile /var/run/pure-certd.pid -B Step 6 Restart Pure-FTPD service Code: systemctl restart pure-ftpd-mysql.service It's not the cleanest but does exactly what it is supposed to do.
is /etc/pure-ftpd/db/ExtCert.conf actually needed? /etc/pure-ftpd/db/mysql.conf is already edited by ispconfig, and contains the db connection settings and already contains various queries for ispconfig. could the query not just get added to this file, and have pure-cert-check.sh reference the mysql.conf file instead?
Maybe. Like I said, it's not the cleanest but it works. I kept it in line like Postfix. That too has multiple .cf files, each with $user, $pass, $dbname, $host and $query.
Or better yet, don't start it by hand and through a cronjob on reboot but create a service! Step 5 Start pure-certd daemon Code: nano /etc/systemd/system/pure-certd.service Code: [Unit] Description=Pure FTPD Certd service After=mariadb.service StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=root Group=root ExecStart=/sbin/pure-certd --run /bin/pure-cert-check.sh --socket /var/run/ftpd-certs.sock --pidfile /var/run/pure-certd.pid -B [Install] WantedBy=multi-user.target Then enable and start the service: Code: systemctl enable pure-certd.service Code: systemctl start pure-certd.service If you're using MySQL instead of MariaDB then change line 3 to: Code: After=mysql.service Continue to step 6 in the first post.