FEATURE: Elliptic Curve certificate (#444)

FEATURE: Elliptic Curve certificate (#444)

Mozilla recommends (P-256) as certificate type for intermediate compatibility.

ECDSA certificates are recommended over RSA certificates, as they allow the use of ECDHE with Windows 7 clients using Internet Explorer 11

Most modern browsers will use cipher suites with the ECDSA certificate. Older browsers will select the RSA certificate and a RSA cipher suite.

diff --git a/templates/web.letsencrypt.ssl.template.yml b/templates/web.letsencrypt.ssl.template.yml
index 4f46ccb..66b9741 100644
--- a/templates/web.letsencrypt.ssl.template.yml
+++ b/templates/web.letsencrypt.ssl.template.yml
@@ -10,7 +10,7 @@ hooks:
 
     - exec:
        cmd:
-         - cd /root && git clone https://github.com/Neilpang/acme.sh.git && cd /root/acme.sh && git reset --hard f62a4a0c0ccf6cd73b5746dd8b8790ce3c512833
+         - cd /root && git clone --branch 2.8.2 --depth 1 https://github.com/Neilpang/acme.sh.git && cd /root/acme.sh
          - touch /var/spool/cron/crontabs/root
          - install -d -m 0755 -g root -o root $LETSENCRYPT_DIR
          - cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --install --log "${LETSENCRYPT_DIR}/acme.sh.log"
@@ -53,27 +53,63 @@ hooks:
        path: /etc/runit/1.d/letsencrypt
        chmod: "+x"
        contents: |
-          #!/bin/bash
-          /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
+        #!/bin/bash
+        /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
 
-          LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --issue -d $$ENV_DISCOURSE_HOSTNAME -k 4096 -w /var/www/discourse/public
-
-          if [ ! "$(cd $$ENV_LETSENCRYPT_DIR/$$ENV_DISCOURSE_HOSTNAME && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]; then
-            # Try to issue the cert again if something goes wrong
-            LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --issue -d $$ENV_DISCOURSE_HOSTNAME -k 4096 --force -w /var/www/discourse/public
-          else
-            grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
-          fi
+        issue_cert() {
+          LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --issue -d $$ENV_DISCOURSE_HOSTNAME --keylength $1 -w /var/www/discourse/public
+        }
 
-          LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --installcert -d $$ENV_DISCOURSE_HOSTNAME --fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer --keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key --reloadcmd "sv reload nginx"
+        cert_exists() {
+          [[ "$(cd $$ENV_LETSENCRYPT_DIR/$$ENV_DISCOURSE_HOSTNAME$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
+        }
 
-          /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
+        ########################################################
+        # RSA cert
+        ########################################################
+        issue_cert "4096"
+
+        if ! cert_exists ""; then
+          # Try to issue the cert again if something goes wrong
+          issue_cert "4096"
+        fi
+
+        LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
+          --installcert \
+          -d $$ENV_DISCOURSE_HOSTNAME \
+          --fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME$1.cer \
+          --keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME$1.key \
+          --reloadcmd "sv reload nginx"
+
+        ########################################################
+        # ECDSA cert
+        ########################################################
+        issue_cert "ec-256"
+
+        if ! cert_exists "_ecc"; then
+          # Try to issue the cert again if something goes wrong
+          issue_cert "ec-256"
+        fi
+
+        LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
+          --installcert \
+          -d $$ENV_DISCOURSE_HOSTNAME \
+          --fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME$1.cer \
+          --keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME$1.key \
+          --reloadcmd "sv reload nginx"
+
+        if cert_exists "" || cert_exists "_ecc"; then
+          grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
+        fi
+
+        /usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
 
     - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_certificate.+/
        to: |
          ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer;
+         ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer;
 
     - replace:
        filename: /shared/letsencrypt/account.conf
@@ -86,6 +122,7 @@ hooks:
        from: /ssl_certificate_key.+/
        to: |
          ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key;
+         ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key;
 
     - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
diff --git a/templates/web.ssl.template.yml b/templates/web.ssl.template.yml
index 7bc4ef6..4b3a02d 100644
--- a/templates/web.ssl.template.yml
+++ b/templates/web.ssl.template.yml
@@ -1,7 +1,6 @@
 run:
   - exec:
      cmd:
-       # Generate strong Diffie-Hellman parameters
        - "mkdir -p /shared/ssl/"
   - replace:
      filename: "/etc/nginx/conf.d/discourse.conf"

GitHub sha: f6ec2185

Correctly install ECDSA certificate

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there:

Note that these changes break the current guidance on let’s encrypt and multisite given in this topic: