Feature #3355

Let's Encrypt (partial) support

Added by Giacomo Sanchietti over 3 years ago. Updated over 3 years ago.

Status:CLOSEDStart date:
Priority:NormalDue date:
Assignee:-% Done:

100%

Category:<multiple packages>
Target version:v6.7
Resolution: NEEDINFO:No

Description

Let's Encrypt (partial) support | Let's Encrypt automatically generates and renews SSL certificates (see: https://letsencrypt.org/).

Prerequisites:

  • the server must be reachable from outside at port 80
  • the server must have at least one public domain name associated to its own public IP (technically a DNS record A or a CNAME)

The system should support Let's Encrypt to generate certificates for the following domains:

  • server FQDN
  • custom domain names

This implementation will have no web interface.

Associated revisions

Revision 5efaabc0
Added by Giacomo Sanchietti over 3 years ago

Partial Let's Encrypt support. Refs #3355

Use letsencrypt.sh client.
No python dependency required.

Revision 3534a3d1
Added by Giacomo Sanchietti over 3 years ago

Partial Let's Encrypt support. Refs #3355

Revision 765bf3da
Added by Giacomo Sanchietti over 3 years ago

letsencrypt-certs: add command line options. Refs #3355

Revision d5d17d76
Added by Giacomo Sanchietti over 3 years ago

LetsEncrypt: add cron job renew script. Refs #3355

Revision 976c097f
Added by Giacomo Sanchietti over 3 years ago

letsencrypt-certs: support SAN for FQDN. Refs #3355

Revision 23a74363
Added by Giacomo Sanchietti over 3 years ago

letsencrypt-certs: add to SAN only enabled alias. Refs #3355

Revision 7efbc085
Added by Giacomo Sanchietti over 3 years ago

certificate-update: expand httpd ssl.conf Refs #3355

Revision b71df311
Added by Giacomo Sanchietti over 3 years ago

Move Let's Encrypt implementation to nethserver-letsencrypt package Refs #3355

This reverts commit 3534a3d11415be0b823e18b2fa3d8cfb9e95d4a9.

Revision 44a63f48
Added by Giacomo Sanchietti over 3 years ago

Move Let's Encrypt implementation to nethserver-letsencrypt package. Refs #3355

History

#1 Updated by Giacomo Sanchietti over 3 years ago

  • Description updated (diff)
  • Category set to <multiple packages>
  • Status changed from NEW to TRIAGED
  • Assignee set to Giacomo Sanchietti
  • Target version set to v6.7
  • % Done changed from 0 to 20

#2 Updated by Giacomo Sanchietti over 3 years ago

  • Description updated (diff)

#3 Updated by Giacomo Sanchietti over 3 years ago

  • Description updated (diff)

#4 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from TRIAGED to ON_DEV
  • % Done changed from 20 to 30

#5 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from ON_DEV to MODIFIED
  • % Done changed from 30 to 60

Current implementations uses letsencrypt.sh alternative client to avoid python dependencies.
See: https://github.com/NethServer/letsencrypt.sh

When Let's Encrypt is enabled, the system will create and automatically renew:
  • a certificate for server FQDN
  • a certificate for each domain enabled inside the certificates database

When a certificate has been generated or renewed, the certificate-update event will be fired.

To globally enable Let's Encrypt:

config setprop pki LetsEncrypt enabled
/usr/libexec/nethserver/letsencrypt-certs -v

Add a custom domain:

db certificates set neth.uk.to certificate status enabled
/usr/libexec/nethserver/letsencrypt-certs -v

Available extra options:
  • LetsEncryptMail: if set, Let's Encrypt server will send notification messages to this mail address
  • LetsEncryptRenewDays: minimum days before expiration to automatically renew certificate

NOTE: nethserver-httpd package is required, but could be not installed in all systems. Before trying Let's Encrypt, assure the package is installed: yum install nethserver-httpd

#6 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from MODIFIED to ON_QA
  • Assignee deleted (Giacomo Sanchietti)
  • % Done changed from 60 to 70
Packages in nethserver-testing:
  • nethserver-base-2.9.5-1.3.gd5d17d7.ns6.noarch.rpm
  • letsencrypt.sh-0.0.1-1.ns6.noarch.rpm
  • nethserver-httpd-2.5.1-1.1.g3534a3d.ns6.noarch.rpm

Before starting the QA, prepare the system:
1. Make sure your port 80 is open to the public Internet, you can check with sites like http://www.canyouseeme.org/
2. Make sure you have a public DNS name pointing to your server, you can check with sites like http://viewdns.info/ or dig and host commands
3. Make sure all packages are installed:

yum --enablerepo=nethserver-testing install nethserver-base nethserver-httpd

NOTE: Let’s Encrypt has stringent rate limits in place during the public beta period. If you start testing using the production endpoint (which is the default), you will quickly hit these limits and find yourself locked out. To avoid this, execute nethserver/letsencrypt-certs command with -t option. Generated certificate will NOT be valid, and released by "happy hacker fake CA" CA.

Test case 1
  • Enable Let's Encrypt: config setprop pki LetsEncrypt enabled
  • Execute the renew command /usr/libexec/nethserver/letsencrypt-certs -v -t and check for the output, should be something like:
    # INFO: Using main config file /tmp/3XhzEPg7Dt
    + Generating account key...
    + Registering account key with letsencrypt...
    Processing test1.neth.eu
     + Signing domains...
     + Creating new directory /etc/letsencrypt.sh/certs/test1.neth.eu ...
     + Generating private key...
     + Generating signing request...
     + Requesting challenge for test1.neth.eu...
     + Responding to challenge for test1.neth.eu...
     + Challenge is valid!
     + Requesting certificate...
     + Checking certificate...
     + Done!
     + Creating fullchain.pem...
     + Done!
    Executing certificate-update event...
    
  • Verify the presented certificate has been signed by Let's Encrypt CA on all SSL-enabled services like:
    • httpd on port 443
    • httpd-admin on port 980
    • etc
Test case 2
  • Create a custom certificate record: db certificates set mydomain certificate status enabled
  • Create all certificates: /usr/libexec/nethserver/letsencrypt-certs -v -t
  • Check new certificate files have been created under /etc/letsencrypt.sh directory
Test case 3
  • Move the date forward (at least 21 days)
  • Execute the script and check all certs are renewed: /usr/libexec/nethserver/letsencrypt-certs -v -t

#7 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from ON_QA to TRIAGED
  • Assignee set to Giacomo Sanchietti
  • % Done changed from 70 to 20

Since Let's Encrypt supports x509 SAN extension, change the implementation to add all server alias as alternatives names.

#8 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from TRIAGED to ON_DEV
  • % Done changed from 20 to 30

#9 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from ON_DEV to MODIFIED
  • % Done changed from 30 to 60

#10 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from MODIFIED to ON_QA
  • Assignee deleted (Giacomo Sanchietti)
  • % Done changed from 60 to 70
In nethserver-testing:
  • nethserver-base-2.9.5-1.5.g23a7436.ns6.noarch.rpm
  • nethserver-httpd-2.5.1-1.2.g7efbc08.ns6.noarch.rpm
  • letsencrypt.sh-0.0.1-1.ns6.noarch.rpm
Test case 4
  • Create a server alias inside the DNS page
  • Enable Let's Encrypt on server alias:
    db hosts setprop alias.mydomain.com LetsEncrypt enabled
    
  • Make sure the alias has a public DNS record
  • Regenerate all certificates:
    /usr/libexec/nethserver/letsencrypt-certs -v -t -f
    
  • Check the generated certificate for FQDN contains all enabled aliases as alternative names:
    openssl x509 -in  /etc/letsencrypt.sh/certs/fqdn/cert.pem -text -noout | grep "Subject Alternative Name" -A 1
    

#11 Updated by Giacomo Sanchietti over 3 years ago

In nethserver-testing:
  • nethserver-base-2.9.5-1.7.g44a63f4.ns6.noarch.rpm
  • nethserver-httpd-2.5.1-1.3.gb71df31.ns6.noarch.rpm
  • nethserver-letsencrypt-0.0.1-1.ns6.noarch.rpm
  • letsencrypt.sh-0.0.1-1.ns6.noarch.rpm
Modifications:
  • Implementation moved to nethserver-letsencrypt package
  • Testing mode doesn't apply any configuration to the system
  • Testing mode now exits with 0 status case in case of success, 1 otherwise
  • Support for custom certificates has been removed (was test case 2)

Before starting the QA, prepare the system:
1. Make sure your port 80 is open to the public Internet, you can check with sites like http://www.canyouseeme.org/
2. Make sure you have a public DNS name pointing to your server, you can check with sites like http://viewdns.info/ or dig and host commands
3. Make sure all packages are installed:

yum --enablerepo=nethserver-testing install nethserver-letsencrypt nethserver-httpd

NOTE: Let’s Encrypt has stringent rate limits in place during the public beta period. If you start testing using the production endpoint (which is the default), you will quickly hit these limits and find yourself locked out. To avoid this, execute nethserver/letsencrypt-certs command with -t option. Generated certificate will NOT be valid, and released by "happy hacker fake CA" CA. Also, testing certificates will NOT be applied to running services.

Test case 1
  • Enable Let's Encrypt: config setprop pki LetsEncrypt enabled
  • Execute the renew command /usr/libexec/nethserver/letsencrypt-certs -v -t and check for the output, should be something like:
    INFO: Using main config file /tmp/3XhzEPg7Dt
    + Generating account key...
    + Registering account key with letsencrypt...
    Processing test1.neth.eu
     + Signing domains...
     + Creating new directory /etc/letsencrypt.sh/certs/test1.neth.eu ...
     + Generating private key...
     + Generating signing request...
     + Requesting challenge for test1.neth.eu...
     + Responding to challenge for test1.neth.eu...
     + Challenge is valid!
     + Requesting certificate...
     + Checking certificate...
     + Done!
     + Creating fullchain.pem...
     + Done!
    
  • Check the certificate has been signed by "happy hacker fake CA"
Test case 2
  • Create a server alias inside the DNS page
  • Enable Let's Encrypt on server alias:
    db hosts setprop alias.mydomain.com LetsEncrypt enabled
    
  • Make sure the alias has a public DNS record
  • Regenerate all certificates:
    /usr/libexec/nethserver/letsencrypt-certs -v -t -f
    
  • Check the generated certificate for FQDN contains all enabled aliases as alternative names:
    openssl x509 -in  /etc/letsencrypt.sh/certs/fqdn/cert.pem -text -noout | grep "Subject Alternative Name" -A 1
    
Test case 3
WARNING: to test this case, you will need to generate a valid certificate!
  • Move the date forward (at least 21 days)
  • Execute the script and check all certs are renewed: /usr/libexec/nethserver/letsencrypt-certs -v -t
  • Check all services (port 443 and 980) are using the renewed certificate

#12 Updated by Giacomo Sanchietti over 3 years ago

Packages in nethserver-testing:
  • nethserver-base-2.9.5-1.7.g44a63f4.ns6.noarch.rpm
  • nethserver-httpd-2.5.1-1.3.gb71df31.ns6.noarch.rpm
  • nethserver-letsencrypt-0.0.1-1.1.g33d204d.ns6.noarch.rpm
  • letsencrypt.sh-0.0.1-1.ns6.noarch.rpm

#13 Updated by Filippo Carletti over 3 years ago

  • Status changed from ON_QA to VERIFIED
  • % Done changed from 70 to 90

I did tests on two different systems, one where I already used LE and one freshly installed.
Here's example output from a test (-t) run:

[root@server ~]# db hosts setprop mail.fanolug.org LetsEncrypt enabled
[root@server ~]# /usr/libexec/nethserver/letsencrypt-certs -t -v
/usr/sbin/letsencrypt.sh --cron  --config /tmp/X7nCS_uLlQ/config.sh  -d server.xxx.com  -d gateway.xxx.com  -d mail.fanolug.org 
# INFO: Using main config file /tmp/X7nCS_uLlQ/config.sh
+ Generating account key...
+ Registering account key with letsencrypt...
Processing server.xxx.com with alternative names: gateway.xxx.com mail.fanolug.org
 + Signing domains...
 + Creating new directory /tmp/X7nCS_uLlQ/certs/server.xxx.com ...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for server.xxx.com...
 + Requesting challenge for gateway.xxx.com...
 + Requesting challenge for mail.fanolug.org...
 + Responding to challenge for server.xxx.com...
 + Challenge is valid!
 + Responding to challenge for gateway.xxx.com...
 + Challenge is valid!
 + Responding to challenge for mail.fanolug.org...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!

Repeating the same test request command:
[root@server ~]# /usr/libexec/nethserver/letsencrypt-certs -v -t
/usr/sbin/letsencrypt.sh --cron  --config /tmp/GJbu2wRF8Q  -d server.xxx.com  -d gateway.xxx.com 
# INFO: Using main config file /tmp/GJbu2wRF8Q
Processing server.xxx.com with alternative names: gateway.xxx.com
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till May 18 12:14:00 2016 GMT (Longer than 30 days). Skipping!
[root@server ~]# echo $?
0

Date moved forward:
[root@nscom ~]# date 04252310
Mon Apr 25 23:10:00 CEST 2016
[root@nscom ~]# /usr/libexec/nethserver/letsencrypt-certs -v -t
/usr/sbin/letsencrypt.sh --cron  --config /tmp/jiitGmsQOf  -d fili.xxx.com 
# INFO: Using main config file /tmp/jiitGmsQOf
Processing fili.xxx.com
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till May 25 21:01:00 2016 GMT (Less than 30 days). Renewing!
 + Signing domains...
 + Generating signing request...
 + Requesting challenge for fili.xxx.com...
 + Responding to challenge for fili.xxx.com...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!
Executing certificate-update event...

While testing I received one error, I presume linked to the beta status of LE service:

[root@nscom ~]# /usr/libexec/nethserver/letsencrypt-certs -v -t
/usr/sbin/letsencrypt.sh --cron  --config /tmp/Z5PCsd4Bs3  -d fili.xxx.com 
# INFO: Using main config file /tmp/Z5PCsd4Bs3
ERROR: Problem connecting to server (curl returned with 6)

Note: moving the date forward is not a perfect way to test renewal, because the cert will always have the correct date, being created on LE servers.

#14 Updated by Giacomo Sanchietti over 3 years ago

  • Status changed from VERIFIED to CLOSED
  • % Done changed from 90 to 100
Releases in nethserver-updates:
  • nethserver-base-2.9.6-1.ns6.noarch.rpm
  • nethserver-httpd-2.5.2-1.ns6.noarch.rpm
  • nethserver-letsencrypt-1.0.0-1.ns6.noarch.rpm
  • letsencrypt.sh-0.0.1-1.ns6.noarch.rpm

Temporary documentation: http://wiki.nethserver.org/doku.php?id=developer:letsencrypt

Also available in: Atom PDF