Help understanding how to host this with SSL?

I have a public domain, let’s call it “domain dot com” and it has an SSL certificate. I am installing HassOs on a raspberry pi 4.

I have a subdomain for that domain pointed to all my self-hosted things, let’s call it “home dot domain dot com” and I have a paid for SSL certificate for that domain.

I have a BUNCH of services hosted there, with reverse proxies in subdirectories to various ports. For example, “home dot domain dot com/airsonic/” or “home dot domain dot com/shinobi/” or “home dot domain dot com/bitwarden/”. This works across the board, and I have an existing dynamic dns solution that keeps this up to date, I think at present I have 18 services this is successfully working for.

Now that I’m integrating Home Assistant, I’m learning that because the decision has been made to keep the base url absolute and not relative, it’s not possible to proxy this to a subdirectory and requires its own subdomain. (If this is incorrect please let me know, I’m taking my understanding from here https://github.com/home-assistant/architecture/issues/156#issuecomment-478183627 ) Fine, not ideal but I can work with that. I can create “hass dot domain dot com” and keep my dynamic dns system pointed to that as well.

That works today, as long as I’m using port 8123 which is forwarded. 80 and 443 are spoken for by apache and my reverse proxy.

I’m trying to then set up Let’s Encrypt as I do not want to pay for another proper SSL certificate. I am finding this impossible to set up; I’ve never used let’s encrypt before since I’ve always had paid for certificates, but if I’m understanding this, it’s not gonna work because Let’s Encrypt only supports 80 and 443?

I’ve never worked with a self hosted service with requirements like this before; is SSL out of the question for me unless I dedicate 80 and 443 to this device? Usually I would get a bit linux-ey and delve into the command line, but it seems with the RPi image you can’t even get sudo so you’ve got to work within the confines of the UI?

If you are using either Apache or Nginx as your reverse proxy, you could create a virtual host on port 443 and base it on hass.domain.com (virtual hosts under both Apache and Nginx allow for port sharing). That should satisfy the LE requirement.

I’ve not tried it, so I’m not 100% certain that it will work, but in theory it should.

You could also use the Let’s Encrypt addon which should allow for adding a SSL cert pretty easily. (https://www.home-assistant.io/integrations/http/#configuration-variables) & (https://github.com/home-assistant/hassio-addons/tree/master/letsencrypt)

Another thing would be to ditch HA Supervised and go with HA Core as that runs in a simple docker container. You could then alter the inbound/outbound ports as part of the docker config and/or terminate your SSL at the docker container (on port 443 pointed to 8123 internally).

Lastly, you could go with Nabu Casa. While this is a paid route ($5/monthly), it provides out of the box SSL and remote access which you could simply redirect with your reverse proxy.

LetsEncrypt supports a DNS challenge so you don’t need any open ports for the SSL. You will need to forward a port for Home Assistant - whichever port you choose but not for SSL.
You could also use Caddy as a reverse proxy and let it handle the ssl as well if you wanted to.

1 Like

I am not familiar with DNS challenge but I’ll take a look at that.

This was more complex than I thought, so I want to document what I did here. Much was taken from here: https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-dns-validation-with-acme-dns-certbot-on-ubuntu-18-04

First, I had a single virtualhost in apache before for *:80, I made another virtualhost for “hass.domain.com” with the following config:

<VirtualHost *:80> 
  ServerName hass.example.com

  Redirect permanent / https://hass.example.com/
</VirtualHost>

On Ubuntu, I had to install the following:

sudo apt install certbot
wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py
chmod +x acme-dns-auth.py
sudo mv acme-dns-auth.py /etc/letsencrypt/

Edit that script and change the first line from “python” to “python3” for compatibility. Then, run this:

certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges --agree-tos --email [email protected] -w /var/lib/letsencryp
t/ -d hass.domain.com

This will pause in the middle, telling you to add a cname record to your dns name for validation, which you do however you want (I did it in cpanel). Then you get the cert and it’s good to go.

I then added the following to the hass.conf file, so it looks like this:

<VirtualHost *:80> 
  ServerName hass.domain.com

  Redirect permanent / https://hass.domain.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName hass.domain.com

  ErrorLog ${APACHE_LOG_DIR}/hass.domain.com-error.log
  CustomLog ${APACHE_LOG_DIR}/hass.domain.com-access.log combined

  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/hass.domain.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/hass.domain.com/privkey.pem

# Other Apache Configuration

  ProxyPreserveHost On

  ProxyPass / http://IPADDRESS:8123/
  ProxyPassReverse / http://IPADDRESS:8123/

  ProxyPass /api/websocket ws://IPADDRESS:8123/api/websocket
  ProxyPassReverse /api/websocket ws://IPADDRESS:8123/api/websocket

  RewriteEngine on
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)  ws://IPADDRESS:8123/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule /(.*)  http://IPADDRESS:8123/$1 [P,L]

</VirtualHost>

Reload apache, and I can now get to my Home Assistant login page at “https://hass.domain.com” with a valid SSL lock. I’ve never used home-assistant before, but if I understand it, renewals won’t happen automatically like with a more default certbot install,