Obtain and configure ssl certificate on nginx with letsencrypt
The recommended method of using letsencrypt certificates with nginx is to obtain the certificate using the ‘certificate only’ method, authenticating via webroot. The webroot authentication uses a directory on the server that letsencrypt can view momentarily and issue the certificate.
This document contains instructions to do this using saltstack automation.
If you want to setup the server manually, then follow these instructions, Obtain and configure ssl certificate on nginx with letsencrypt - Manual Configuration.
Configure using Salt
The salt configuration installs letsencrypt and configures each site to use the
certificates supplied if both ssl and letsencrypt are configured in the site’s
pillar. A cron task is created per server to renew all certificates
periodically, this task logs output to /var/log/letsencrypt-renew.log
. The
server is also protected using a hardened Diffie Hellman dhparam certificate.
If you don’t have an existing certificate for your site, you need to configure
it to use the http
protocol to validate to letsencrypt that you are
authorised to use the domain and then alter the configuration later to enable
ssl and use the new certificate to sign the https
protocol connections to
your site. Follow the instructions in the section called Configuration
without an ssl certificate then skip to Obtain the letsencrypt certificate
If you already have a existing valid ssl certificate configured on your site,
you can use it to create an https connections to validate to letsencrypt that
you are authorised to use the domain and then alter the configuration later to
use the new certificate to sign the https
protocol connections to your
site. This is useful if you have an existing https site you wish to convert to
using letsencrypt. Follow the instructions in the section called
Configuration with an existing certificate then continue to
Obtain the letsencrypt certificate
Configuration without an ssl certificate
On the master server, configure the pillar for your site use standard http as follows:
<domain>:
package: <package>
profile: django
redirect: <redirect domain>
celery: False
db_pass: <password>
db_type: <database type e.g. psql or mysql>
norecaptcha_site_key: <norecaptcha site key>
norecaptcha_secret_key: <norecaptcha secret key>
opbeat: <opbeat id>
secret_key: <django secret key>
ssl: False
# letsencrypt: True
uwsgi_port: <uwsgi port>
mail:
mandrill_api_key: <mandrill key>
mandrill_user_name: <mandril user name>
For a devpi
server, edit the service.yb.devpi.sls
file setting ssl
to False
and commenting out letsencrypt
e.g:
devpi:
domain: devpi.yourbiz.co.uk
port: 4040
ssl: False
# letsencrypt: True
Note
The flag ssl
is set to False
(it must be present) and
letsencrypt
is commented out (disabled)
Having accepted your minion (if necessary), create or update your site using:
salt <minion name> state.apply --state-verbose=False
Check the output to ensure that the site has been created
Configuration with an existing certificate
On the master server, configure the pillar for your site to use https as follows:
<domain>:
package: <package>
profile: django
redirect: <redirect domain>
celery: False
db_pass: <password>
db_type: <database type e.g. psql or mysql>
norecaptcha_site_key: <norecaptcha site key>
norecaptcha_secret_key: <norecaptcha secret key>
opbeat: <opbeat id>
secret_key: <django secret key>
ssl: True
# letsencrypt: True
uwsgi_port: <uwsgi port>
mail:
mandrill_api_key: <mandrill key>
mandrill_user_name: <mandril user name>
Note
The flag ssl
is set to True
(enabled) but letsencrypt
is
commented out (disabled). This will use ssl certificates obtained
manually
Having accepted your minion (if necessary), create or update your site using:
salt <minion name> state.apply --state-verbose=False
Check the output to ensure that the site has been created
Obtain the letsencrypt certificate
Warning
Run the following command as a user that can sudo
(not the
web
user).
Log on to the minion and check and reload the nginx configuration:
sudo nginx -t
sudo service nginx reload
For a standard web site, run the command:
./bin/init-letsencrypt <server FQDN> [<redirect domain>]
For a devpi
server, see the instructions above, run:
./bin/init-letsencrypt devpi.yourbiz.co.uk - /usr/share/nginx/html
Note
/usr/share/nginx/html
is the root defined in
/etc/nginx/include/devpi.conf
.
init-letsencrypt
is a script installed by our salt configuration:
It calls
letsencrypt-auto
with thecertonly
andwebroot
options and sets the webroot path and specifies the domain and optionally a redirect domain.The
init-letsencrypt
script is installed into thebin
folder of all users other thanweb
. Theweb
user has anopt
directory - but the usual convention for a user directory that contains executable files is~/bin
. In order that there is only one copy of the script on the system, we installed the script into the/home/web/opt
directory. The script requiressudo
privilege (whichweb
does not have), so we created abin
directory for each user and linked to the/home/web/opt/
copy of the script.If this is the first time you have run letsencrypt on this server it will install a virtual environment and all the dependencies and then prompt for an email address and prompt to accept the terms and conditions
If successful you’ll receive the following message:
IMPORTANT NOTES:
- If you lose your account credentials, you can recover through
e-mails sent to sammy@digitalocean.com
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/<server FQDN>/fullchain.pem. Your
cert will expire on <Expiry Date>. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.
- If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Record the path and expiration date of your certificate so you can check at a later date.
This will create the following files in /etc/letsencrypt/live/<server FQDN>
cert.pem
: Your domain’s certificatechain.pem
: The Let’s Encrypt chain certificatefullchain.pem
: cert.pem and chain.pem combinedprivkey.pem
: Your certificate’s private key
Enable the letsencrypt certificate on your server
Having obtained the certificate using one of the methods above, log on to the master server and alter the pillar entry for the site to enable the flags for both ssl and letsencrypt - as shown in the following snippet (see above for the full pillar configuration):
secret_key: <django secret key>
ssl: True
letsencrypt: True
uwsgi_port: <uwsgi port>
For a devpi
server, edit the service.yb.devpi.sls
file setting ssl
and letsencrypt
to True
e.g:
ssl: True
# letsencrypt: True
Now run:
salt <minion name> state.apply --state-verbose=False
Then log on to the minion and type:
sudo service nginx reload
The system will now use the new letsencrypt certificate to provide https protocol connections.
Test
You can test your site using:
https://www.ssllabs.com/ssltest/analyze.html?d=<domain name>
Renew
For another time to renew - you can probably just type:
sudo certbot renew
… without setting it up again. For more information, see Chat with Malcolm ref renewal