For people that are using their own internal certificate authority and want https for INTERNAL USE ONLY. This is not a primer on how to get your certificate authority setup with Acme.sh, just how to get acme.sh installed on your HomeAssistant system and the certificates installed into Nginx Proxy Manager (easiest one for me to use, traefik is complicated). I’m using the Advanced SSH & Web Terminal addon from Frenck to access the server through zhs. I also use Vim as my editor of choice; nano works as well.
Constructive comments are welcome. Again, I’m only using this for the internal network. I access HomeAssistant through a VPN when I want to check on the house remotely.
DNS Records
Make sure host records (A) are stated in the primary DNS zone with necessary reverse records set. I use Technitium DNS as my network DNS server that uses DNS Dynamic Updates through the dns-rfc2136 plugin. This is the dns_nsupdate plugin in acme.sh
Certificate Authority Setup
Copy the certificate authority root and intermediate certificates to /usr/local/share/ca-certificates/root_ca.crt and /usr/local/share/ca-certificates/intermediate_ca.crt, respectfully.
vim /usr/local/share/ca-certificates/root_ca.crt
vim /usr/local/share/ca-certificates/intermediate_ca.crt
update-ca-certificates
Copy your TSIG key into a file within the root directory. I used update as my key name. This key is setup within Technitium DNS to authenticate with the DNS server to enable dynamic DNS zone updates.
vim /root/update.key
Acme.sh Install
Curl is included by default with the Terminal addon but git needs to be installed to clone the acme.sh directory. Set “domain.tld” to whatever your internal domain address is.
apk add git
git clone https://github.com/acmesh-official/acme.sh.git
cd /root/acme.sh
./acme.sh --install -m [email protected]
cd ..
rm -rf /root/acme.sh
Restart the HomeAssistant server.
Acme.sh Account Setup
You need to register the server that is requesting certificates with the certificate authority server but some lines need to be added to the acme.sh configuration file.
vim /root/.acme.sh/account.conf
Add the following lines at the bottom of the file, changing the default values to fit your environment.
SAVED_NSUPDATE_SERVER='dns_server.domain.tld'
SAVED_NSUPDATE_KEY='/root/update.key'
SAVED_NSUPDATE_ZONE='domain.tld'
CA_BUNDLE='/usr/local/share/ca-certificates/root_ca.crt'
USER_PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin'
Acme.sh Account Registration on CA Server
Normally you don’t need bash at the beginning of the following commands, but acme.sh wouldn’t run without bash appended at the front.
bash acme.sh \
--register-account \
--server https://ca_server.domain.tld/acme/acme/directory \
--ca-bundle /usr/local/share/ca-certificates/root_ca.crt \
-m [[email protected]](mailto:[email protected])
Acme.sh Post Hook Script Initialization
touch /usr/local/bin/acme-post.sh
chmod +x /usr/local/bin/acme-post.sh
Acme.sh Certificate Issuance
bash acme.sh --issue --dns dns_nsupdate -d hostname.domain.tld --server https://ca_server.domain.tld/acme/acme/directory --valid-to "+365d" --ca-bundle /usr/local/share/ca-certificates/ --dnssleep 2 --post-hook /usr/local/bin/acme-post.sh
--dns dns_nsupdate
specifys the dns-rfc2136 plugin that interacts with the DNS server
--server
specifies the location of the certificate authority server on your internal network
--valid-to "+365d"
sets the expiration date of the certificate a full year from the issuance date. Default expiration is 60 days.
--dnssleep 2
sets a delay of 2 seconds to allow for dns record propagation on the dns server.
--post-hook
calls the post hook script that is initialized above. The script is edited after this command has run once.
To rerun this command to help propagate files called out in the post-hook script, append --force
at the end of the certificate issuance command to force a certificate renewal. I usually run the command above 3 times to get the files propagated to the correct places.
Acme.sh Output
The certificate,key, intermeidate CA, and full chain files are stored in: /root/.acme.sh/<hostname>.domain.tld_ecc/<hostname>.domain.tld.cer
/root/.acme.sh/<hostname>.domain.tld_ecc/<hostname>.domain.tld.key
/root/.acme.sh/<hostname>.domain.tld_ecc/ca.cer
/root/.acme.sh/<hostname>.domain.tld_ecc/fullchain.cer
Acme.sh Example Post File
Normally the certificate files don’t need to be moved out of the SSL private store, but in this case the files need to be in the /ssl
directory as referenced in the configuration.yaml
file.
#!/bin/bash
chmod +w /etc/ssl/private/hostname_cert.*
mv /etc/ssl/private/hostname_cert.pem /etc/ssl/private/hostname_cert.oldpem
mv /etc/ssl/private/hostname_cert.key /etc/ssl/private/hostname_cert.oldkey
cp /root/.acme.sh/hostname.domain.tld_ecc/hostname.domain.tld.cer /etc/ssl/private/hostname_cert.pem
cp /root/.acme.sh/hostname.domain.tld_ecc/hostname.domain.tld.key /etc/ssl/private/hostname_cert.key
mv /ssl/hostname_cert.pem /ssl/hostname_cert.oldpem
mv /ssl/hostname_cert.key /ssl/hostname_cert.oldkey
cp /etc/ssl/private/hostname_cert.pem /ssl/hostname_cert.pem
cp /etc/ssl/private/hostname_cert.key /ssl/hostname_cert.key
chmod 400 /etc/ssl/private/hostname_cert.*
Configuration.yaml
Add the following lines to your configuration.yaml
file. I use the Studio Code Server addon to edit the yaml file.
http:
ssl_certificate: /ssl/hostname_cert.pem
ssl_key: /ssl/hostname_cert.key
Nginx Proxy Manager
Copy the contents of the hostname_cert.pem
and hostname_cert.key
files to discreet files on your desktop to upload to NPM. I use MacOS terminal to copy the contents to .pem
and .key
files for upload.
cat /ssl/hostname_cert.pem
cat /ssl/hostname_cert.key
Go to “SSL Certificates” witin the NPM interface and choose “Add SSL Certificate” → “Custom” on the right hand side. Type in the name of your server, e.g., “hostname.domain.tld” into the first field. Browse to the location of .key
file on your desktop for the second field and the .pem
file for the third field. Click “Save” and verify that the expiration date of the certificate is a little more than a year from now.
Click on “Hosts” → “Proxy Hosts” on the top tool bar. Click “Add Proxy Host” on the right hand side. Type the server address in the first field (hostname.domain.tld). There will be a small dropdown below the field that will fill in as you type; click on the dropdown text once you are finished typing to fill in the field. The field will not fill in when you hit enter, you have to click the dropdown text. Change the “Scheme” to “https:”. Type in the full address of the server in the “Forward Hostname/IP” field: https://hostname.domain.tld
. Type in the port number: 8123
.
Click on the “SSL” tab in this edit window and choose the hostname.domain.tld file from the dropdown menu. Toggle the “Force SSL” option and click “Save.”
You should be able to navigate to your hostname address now with https://hostname.domain.tld:8123
in your browser with a valid SSL certificate.
Edit: If anyone notices issues in this post, comment so I can update the post with correct information.