I also overcame this, using LetsEncrypt. my biggest challenge was not wanting to open up ports on my edge firewall at home. You can use something like cloudflare (even if they are not the registrar you purchased the domain with) to automate offline domain validation and download new certs automatically every 3 months. This is free and is a one-time setup. (aside from the cost of the domain)
Below is what mine looked like... afterwards, boom green locks inside the house without needing external access, and all my app clients play nice. nginx reverse proxy for all my self-hosted apps. You can even just use DNS on pfsense (or whatever home router you use) to tell your devices where your server is.
#sudo ln -s /var/lib/snapd/snap /snap
sudo snap install certbot --classic
#sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
#sudo certbot certonly --manual --preferred-challenges dns
sudo certbot certonly --manual --preferred-challenges dns --force-renewal --register-unsafely-without-email --agree-tos --domains *.[YOUR_DOMAIN]
#restart nginx to load new certs
sudo nginx -t
sudo systemctl restart nginx.service
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/[YOUR_DOMAIN]/fullchain.pem
Key is saved at: /etc/letsencrypt/live/[YOUR_DOMAIN]/privkey.pem
This certificate expires on XXXXXXX.
These files will be updated when the certificate renews.
https://davidaugustat.com/web/set-up-lets-encrypt-on-intranet-website
Put in host override on pfsense:
Services -> DNS Resolver -> Host Overrides
Automating Let's Encrypt with DNS-01?
https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=wildcard
https://certbot-dns-cloudflare.readthedocs.io/en/stable/
https://bjornjohansen.com/wildcard-certificate-letsencrypt-cloudflare/
#assuming you have certbot installed already as above
sudo snap install certbot-dns-cloudflare
#get API key with DNS Zone edit rights from Cloudflare portal
sudo mkdir /root/.secrets/
sudo chmod 0700 /root/.secrets/
sudo chmod 0400 /root/.secrets/cloudflare.ini
sudo nano /root/.secrets/cloudflare.ini
Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123
sudo certbot certonly --dry-run --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/cloudflare.ini --domains *.[YOUR_DOMAIN]
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/cloudflare.ini --dns-cloudflare-propagation-seconds 15 --domains *[YOUR_DOMAIN]
#check if there is a crontab entry
systemctl list-timers