-
-
Save Greelan/28a46a33140b65c9a045573ca460f044 to your computer and use it in GitHub Desktop.
| # How to use acme.sh to set up Let's Encrypt, with the script being run | |
| # mostly without root permissions | |
| # See https://github.com/Neilpang/acme.sh for more | |
| # These instructions use the domain "EXAMPLE.COM" as an example | |
| # These instructions: | |
| # - work on Ubuntu 18.04 and 20.04 with nginx | |
| # - use CloudFlare DNS validation | |
| # - set up a wildcard certificate for the "EXAMPLE.COM" domain | |
| # - use a systemd service, rather than cron job, to renew the certificate | |
| # When this is done, there will be an "acme" user that handles issuing, | |
| # updating, and installing certificates. This user will have the following | |
| # (fairly minimal) permissions: | |
| # - Copy certificates and key to /etc/letsencrypt/EXAMPLE.COM | |
| # - Reload your nginx server | |
| # First things first - create a system user account and group for acme | |
| sudo useradd -m -d /var/lib/acme -s /usr/sbin/nologin -r -U acme | |
| sudo chmod 700 /var/lib/acme | |
| # Create a directory for the acme account to save certs in | |
| MYDOMAIN="EXAMPLE.COM" | |
| sudo mkdir -m 710 /etc/letsencrypt/"$MYDOMAIN" | |
| sudo chown acme.www-data /etc/letsencrypt/"$MYDOMAIN" | |
| # Edit your sudoers file to allow the acme user to reload (not restart) nginx | |
| sudo visudo | |
| # Add the following line at the end: | |
| acme ALL=(ALL) NOPASSWD: /bin/systemctl reload nginx.service | |
| # Now change to the "acme" user - you'll do most of the rest of this guide as them | |
| sudo MYDOMAIN="$MYDOMAIN" -s -u acme bash | |
| export HOME=/var/lib/acme | |
| cd ~ | |
| # Install acme.sh | |
| git clone https://github.com/Neilpang/acme.sh.git | |
| cd acme.sh | |
| ./acme.sh --install | |
| # Export your CloudFlare API token and account ID so that acme.sh can use them | |
| # See https://github.com/Neilpang/acme.sh/wiki/dnsapi for more about API tokens | |
| # You can find your account ID in the URL of any page within the Cloudflare Dashboard | |
| # after selecting the appropriate account | |
| export CF_Token="[insert]" | |
| export CF_Account_ID="[insert]" | |
| # Create your certificate | |
| # Note that the "force" flag is needed for the below commands as otherwise | |
| # the acme.sh script complains about being run as sudo | |
| cd ~ | |
| .acme.sh/acme.sh --issue -d "$MYDOMAIN" -d *."$MYDOMAIN" --dns dns_cf --force | |
| # If everything went well, install your certificate | |
| .acme.sh/acme.sh --install-cert --domain "$MYDOMAIN" \ | |
| --ca-file /etc/letsencrypt/"$MYDOMAIN"/chain.pem \ | |
| --key-file /etc/letsencrypt/"$MYDOMAIN"/key.pem \ | |
| --fullchain-file /etc/letsencrypt/"$MYDOMAIN"/fullchain.pem \ | |
| --reloadcmd "sudo systemctl reload nginx.service" --force | |
| # Disable default cron job as a systemd service will be created instead for renewal | |
| .acme.sh/acme.sh --uninstall-cronjob --force | |
| # Drop back to your own user | |
| exit | |
| # Now modify your nginx config to work with the new certs | |
| sudo nano /etc/nginx/sites-enabled/"$MYDOMAIN" | |
| # Example SSL config section | |
| #server { | |
| # ... | |
| # ssl_certificate /etc/letsencrypt/EXAMPLE.COM/fullchain.pem; | |
| # ssl_certificate_key /etc/letsencrypt/EXAMPLE.COM/key.pem; | |
| # ssl_trusted_certificate /etc/letsencrypt/EXAMPLE.COM/chain.pem; | |
| # include /etc/nginx/ssl/ssl_params; # Change to whatever SSL settings you use - see further below | |
| # ... | |
| #} | |
| # acme.sh does not create its own suggested SSL settings for you to use with nginx, | |
| # so you will need to create your own (if you haven't already) | |
| # The following commands set up SSL parameters of a reasonable level of security - | |
| # relax or harden as you see fit (eg to include OCSP stapling), or skip if you | |
| # already have your own. See https://ssl-config.mozilla.org/ for suggestions | |
| sudo mkdir /etc/nginx/ssl | |
| sudo tee /etc/nginx/ssl/ssl_params >/dev/null <<EOF | |
| ssl_session_cache shared:SSL:10m; | |
| ssl_session_timeout 1d; | |
| ssl_protocols TLSv1.2 TLSv1.3; | |
| ssl_prefer_server_ciphers off; | |
| ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ | |
| ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\ | |
| ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\ | |
| DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; | |
| ssl_ecdh_curve X25519:secp384r1; | |
| ssl_session_tickets off; | |
| ssl_dhparam /etc/nginx/ssl/dhparam.pem; | |
| EOF | |
| sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 | |
| # Now test nginx to see if everything is working | |
| sudo nginx -t | |
| # And reload if it worked | |
| sudo systemctl reload nginx.service | |
| # Create a systemd service and timer to renew the certificate and reload nginx | |
| sudo tee /etc/systemd/system/acme_letsencrypt.service >/dev/null <<EOF | |
| [Unit] | |
| Description=Renew Let's Encrypt certificates using acme.sh | |
| After=network-online.target | |
| [Service] | |
| Type=oneshot | |
| User=acme | |
| Group=acme | |
| Environment="HOME=/var/lib/acme" | |
| ExecStart=/var/lib/acme/.acme.sh/acme.sh --cron | |
| SuccessExitStatus=0 2 | |
| EOF | |
| sudo tee /etc/systemd/system/acme_letsencrypt.timer >/dev/null <<EOF | |
| [Unit] | |
| Description=Daily renewal of Let's Encrypt's certificates | |
| [Timer] | |
| OnCalendar=daily | |
| RandomizedDelaySec=1h | |
| Persistent=true | |
| [Install] | |
| WantedBy=timers.target | |
| EOF | |
| # Now start and enable | |
| sudo systemctl start acme_letsencrypt.timer | |
| sudo systemctl enable acme_letsencrypt.timer | |
| # Congrats, you have a Let's Encrypt wildcard certificate set up on your box | |
| # and it is configured to automatically renew, all by running the acme.sh script mostly | |
| # without root permissions (other than to reload nginx on renewal). |
Back after over 2 years because of a fresh install that I have done.
I see that things have changed because of the underlying changes that have happened in acme.sh
Couple of extra steps that I had to do as a result.
acme.sh now using ZeroSSL by default (rather than LetsEncrypt) ... so a step is needed to set-up the ZeroSSL environment.
The approach taken depends on whether or not the user has a ZeroSSL account.
See https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA
Also - now using CloudFlare but probably worth mentioning that if using something else (I use Dynu) then the opening steps are different and user should follow the appropriate sequence from https://github.com/acmesh-official/acme.sh/wiki/dnsapi
remembering to also change the "--issue" command to use the correct "--dns" setting.
Thanks for this!
Thank you! <3