Note: this post is amended because the updated port security/acme.sh is now using its own convention home directory /var/db/acme with dedicated user/group acme:acme
The idea is to limit the use of elevated privileges as much as possible.
================
- What is this about?
security/acme.sh is a shell script with minimal dependencies to generate SSL/TLS certificates from Let's Encrypt https://letsencrypt.org/
It's the same philosophy as portmaster for managing FreeBSD's ports.
security/acme.sh is a shell script to manage SSL/TLS certificates.
Those certificates are fully functional and will not give any security warning like the self-signed certificates.
Note that https://freebsd.org/ uses "Let's Encrypt" and apparently even uses the security/acme.sh shell script.
- Why use security/acme.sh?
There is a large choice of tools to request certificates from Let's Encrypt but they all require many dependencies and root access.
security/acme.sh is a very minimalistic implementation of the ACME protocol which is used to automate the request and renewal of those SSL/TLS certificates.
- Installation:
- Requesting a certificate:
If you already have a web server running i.e. using port 80:
security/acme.sh needs to create a temporary subfolder under your web-directory called: .well-known
For this, we need to temporarily change the ownership of web-directory so that security/acme.sh can proceed with the change without any root priviledge.
If you don't have any web server running on this host, you would need to run in standalone-mode:
make sure to pre-install net/socat since it is required for standalone mode.
Notice a few things:
the acme.sh script creates a set of certificates:
Your cert is in /var/db/acme/www.example.com/www.example.com.cer
Your cert key is in /var/db/acme/www.example.com/www.example.com.key
The intermediate CA cert is in /var/db/acme/www.example.com/ca.cer
And the full chain certs is there: /var/db/acme/www.example.com/fullchain.cer
The acme.sh author recommends to use the --install-cert target to copy the certificates to the web server's locations:
- Renewing the certificate:
The "Let's Encrypt" certificates have a short life span of 90 days and need to be renewed either manually or automatically and acme.sh script can take care of that:
Just create a cron job as the user running the script:
- This will attempt to renew the certificate every night. The script will check if the certificate is about to exipre and will renew it as necessary.
- It will restart the webserver (in this case nginx) if the certificate was renewed.
- security/sudo is used because we are running the cron job as a non root user and we need root priviledge to restart the webserver.
- Troubleshooting certificate creation:
The acme.sh has a few valuable knobs that you can add to it's invocation
--debug : displays detailed logs
--log : creates a log file with detailed logs normally found at /var/db/acme/.acme.sh/acme.sh.log
--staging: is a testing switch to dry-run certificate creation with LetsEncrypt
The idea is to limit the use of elevated privileges as much as possible.
================
- What is this about?
security/acme.sh is a shell script with minimal dependencies to generate SSL/TLS certificates from Let's Encrypt https://letsencrypt.org/
It's the same philosophy as portmaster for managing FreeBSD's ports.
security/acme.sh is a shell script to manage SSL/TLS certificates.
Those certificates are fully functional and will not give any security warning like the self-signed certificates.
Note that https://freebsd.org/ uses "Let's Encrypt" and apparently even uses the security/acme.sh shell script.
- Why use security/acme.sh?
There is a large choice of tools to request certificates from Let's Encrypt but they all require many dependencies and root access.
security/acme.sh is a very minimalistic implementation of the ACME protocol which is used to automate the request and renewal of those SSL/TLS certificates.
- Installation:
pkg install security/acme.sh
- Requesting a certificate:
If you already have a web server running i.e. using port 80:
security/acme.sh needs to create a temporary subfolder under your web-directory called: .well-known
For this, we need to temporarily change the ownership of web-directory so that security/acme.sh can proceed with the change without any root priviledge.
Code:
# change ownership temporarily to user:acme group:acme
chown acme:acme /usr/local/www/your-web-site-dir
su acme
acme.sh --issue -d www.example.com -w /usr/local/www/your-web-site-dir
# restore ownership back to whatever user it was.
chown www:www /usr/local/www/your-web-site-dir
If you don't have any web server running on this host, you would need to run in standalone-mode:
make sure to pre-install net/socat since it is required for standalone mode.
Code:
su
pkg install net/socat
# run acme.sh as root because it needs to listen on port 80
acme.sh --issue -d www.example.com --home /var/db/acme --standalone
Notice a few things:
- We are requesting a certificate for www.example.com. Obviously, you need to change this to your own FQDN. It needs to resolve to your host and must be reachable from the Internet.
- The "--standalone" invocation needs to temporarily bind port 80 and thus needs to be run as user root
- The user running acme.sh, as defined by the port maintainer is "acme". This user is created automatically by the port or pkg.
- The "--home /var/db/acme" is also created by the port/pkg and is defined by the port maintainer as the default home for storing the scripts files and certificates.
- the "-w /usr/local/www/your-web-site-dir" option is where the script needs to write temporary data to be read from the certificate authority. It must be writable by the user executing the script in this case user "acme".
the acme.sh script creates a set of certificates:
Your cert is in /var/db/acme/www.example.com/www.example.com.cer
Your cert key is in /var/db/acme/www.example.com/www.example.com.key
The intermediate CA cert is in /var/db/acme/www.example.com/ca.cer
And the full chain certs is there: /var/db/acme/www.example.com/fullchain.cer
The acme.sh author recommends to use the --install-cert target to copy the certificates to the web server's locations:
Code:
# Create a place to store the certificate so that nginx/apache car read them:
mkdir -p /usr/local/etc/nginx/ssl/www.example.com/
touch /usr/local/etc/nginx/ssl/www.example.com/fullchain.cer
touch /usr/local/etc/nginx/ssl/www.example.com/www.example.com.key
touch /usr/local/etc/nginx/ssl/www.example.com/www.example.com.cer
chown -R acme:acme /usr/local/etc/nginx/ssl/www.example.com
# run the script as user “acme”
su acme
acme.sh --install-cert -d www.example.com \
--cert-file /usr/local/etc/nginx/ssl/www.example.com/www.example.com.cer \
--key-file /usr/local/etc/nginx/ssl/www.example.com/www.example.com.key \
--fullchain-file /usr/local/etc/nginx/ssl/www.example.com/fullchain.cer \
--reloadcmd "sudo service nginx forcereload"
- Renewing the certificate:
The "Let's Encrypt" certificates have a short life span of 90 days and need to be renewed either manually or automatically and acme.sh script can take care of that:
Just create a cron job as the user running the script:
crontab -u acme -e
Code:
# Attempt to renew the certificates every once in a while:
45 1 * * * /usr/local/sbin/acme.sh --cron --home /var/db/acme/.acme.sh --reloadcmd "/usr/local/bin/sudo /usr/sbin/service nginx forcereload" > /dev/null
- This will attempt to renew the certificate every night. The script will check if the certificate is about to exipre and will renew it as necessary.
- It will restart the webserver (in this case nginx) if the certificate was renewed.
- security/sudo is used because we are running the cron job as a non root user and we need root priviledge to restart the webserver.
visudo
Code:
# add the following line to give access to user acme to restart a service
acme ALL=(root) NOPASSWD: /usr/sbin/service nginx forcereload
- Troubleshooting certificate creation:
The acme.sh has a few valuable knobs that you can add to it's invocation
--debug : displays detailed logs
--log : creates a log file with detailed logs normally found at /var/db/acme/.acme.sh/acme.sh.log
--staging: is a testing switch to dry-run certificate creation with LetsEncrypt
Last edited: