Automatically update SSL certificates using acme.sh script.
See: acme.sh on GitHub
Note: As a precaution, do NOT run this script as root but create a (system-)user which has no access to secure resources.
useradd --system --create-home --home-dir /var/lib/acme --shell /bin/bash acme
Using the acme provided script directly.
wget -O - https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m my@example.com
Just clone it to check first what is executed.
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install
An alias acme.sh to /home/sites/.acme.sh/acme.sh is created when installed.
User where the script is installed here is sites.
Also, a cron entry is added to update all the certificates when expired.
39 0 * * * "/home/sites/.acme.sh"/acme.sh --cron --home "/home/sites/.acme.sh" > /dev/null
Note: The given webroot of the domain must be available from a webserver using
thehttp://protocol in order for ACME to validate the domain ownership.
acme.sh --issue \
--domain www.scanframe.com \
--webroot /home/sites/apps/websrv/www \
--server letsencrypt
Is already done automatically by the created cronjob. But it can be forced by adding --force.
acme.sh --renew \
--domain www.scanframe.com \
--webroot /home/sites/apps/websrv/www \
--server letsencrypt
Is already done automatically by the cronjob when it is to be expired.
acme.sh --renew-all
This should be done from a cron job to generate the needed.
DOMAIN="www.scanframe.com" \
acme.sh --install-cert \
--domain "${DOMAIN}" \
--cert-file "ssl-cert/${DOMAIN}-cert.pem" \
--key-file "ssl-cert/${DOMAIN}-key.pem" \
--fullchain-file "ssl-cert/${DOMAIN}-letsencrypt.pem"
Creating a .pfx file of the certificate having a password.
# Create PKCS single file of all parts with a password.
openssl pkcs12 -export \
-out "${SSL_DIR}/${DOMAIN}.pfx" \
-inkey "${SSL_DIR}/${DOMAIN}-key.pem" \
-in "${SSL_DIR}/${DOMAIN}-cert.pem" \
-certfile "${SSL_DIR}/${DOMAIN}-letsencrypt.pem" \
-password pass:your-password
acme System UserNever not run the self-updating script as root.
For this reason, create a dedicated user for running the script.
useradd --system --create-home --home-dir /var/lib/acme --shell /bin/bash acme
As the acme user and install the script.
sudo -iu acme
wget -O - https://get.acme.sh | sh -s email=my@example.com
Install nginx to be able to serve the required webroot.
apt install nginx
Create the Nginx configuration file .
server {
listen 80;
listen [::]:80;
server_name my.example.com;
root /var/www/html;
index index.html;
location /.well-known/acme-challenge/ {
alias /var/lib/acme/webroot/.well-known/acme-challenge/;
}
location / {
try_files $uri $uri/ =404;
}
}
# When the SSL certificate files are available enable this line.
#include conf.d/include/my.example.com-ssl.conf;
Create the SSL include file /etc/nginx/conf.d/include/my.example.com-ssl.conf.
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name my.example.com;
ssl_certificate /var/lib/acme/.acme.sh/my.example.com_ecc/fullchain.cer;
ssl_certificate_key /var/lib/acme/.acme.sh/my.example.com_ecc/my.example.com.key;
# Modern SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# HSTS (optional but recommended, 1 year)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Add the acme group to www-data user so nginx can read the certificate files and other
files needed for issuing certificates.
usermod -aG acme www-data
Test and reload nginx.
nginx -t && systemctl reload nginx
Acquire a letsencrypt certificate for domain my.example.com.
acme.sh --issue --webroot /var/lib/acme/webroot --domain my.example.com -m acme@example.com --server letsencrypt