Securing Home Assistant

for example if I have certs in /volume1/fullchaim.pem I have to add at the docker run command this path -v /volume1:/volume1:ro?

This was the case for me i’m still fairly new to Docker but my understanding is this gives the container running HASS access to those files in this case certs outside of the container.

Hey,

so, this is how I have it here.

I have everything running in Docker with DuckDNS and LetsEncript. I think the trick is where you map the output of the certs and you connect on the HA side.

in my case, when I created the LetsEncript Docker Container running this:

sudo docker run -d --privileged --name=nginx -v /config/nginx:/config -e EMAIL=<emailaddress> -e URL=<domain> -p 443:443 -p 80:80 -e TZ=Europe/Madrid linuxserver/letsencrypt

NOTE: The image linuxserver/letsencrypt provides both Lets Encript and NGINX. That’s why I refer to it as NGINX in the Container name.

so in the Docker Host, in the path /config/nginx I have all the configuration and Cert keys.

then, when I create the docker container for HomeAssistant, I include the path from the LetsEncript Container as part of the HA one:

sudo docker run -d --name="home-assistant" -v /config/homeassistant/live:/config -v /etc/localtime:/etc/localtime:ro -v /config/nginx/etc/letsencrypt/:/etc/letsencrypt/ --net=host homeassistant/home-assistant

This way, I have mapped the Host path /config/nginx/etc/letsencrypt/ (output of the LetsEncript Container) in the Container path /etc/letsencrypt/ so it’s looking perfectly aligned with the instructions in the web (https://home-assistant.io/blog/2015/12/13/setup-encryption-using-lets-encrypt/)

Now, in the HomeAssistant Configuration file I have the following:

http:
  api_password: !secret http.api_password 
  ssl_certificate: /etc/letsencrypt/live/<domain>/fullchain.pem
  ssl_key: /etc/letsencrypt/live/<domain>/privkey.pem

hope this helps.

@jamieb

Recommend looking at nginx(running in docker) and reverse proxy.
In the long run it reduces required open ports in network

For me only nginx docker server has cert installed.
Nginx forwards from Synology (docker) to raspberry pi running HA along with several other docker apps all secured by Cert installed on nginx server

I’m been hearing more and more about nginx lately. I’m going to have a look at setting it up. Have you found any negatives to using nginx as apposed to a open port? Thanks for the suggestion @tmjpugh

No negatives. much simpler
I use certbot but could not get this and nginx to run together in single container. I created a separate Certbot docker and change nginx config when I manually update certificates. will deal with automating this later

Docker Create command for NGINX on synology

docker create -p exthttpportt:8080 -p exthttpsport:443 -v synologywebexposedfolder:/var/www -v /etc/localtime:/etc/localtime:ro -v synologynginxconfigfolder:/etc/nginx --name=nginx nginx:latest

drop the config file below into the nginx config folder specified above
point any port to the docker container and it will work.
Be aware that port in config is the container port not host port. So you can forward WAN port 8081 to Host port 8443 and have that point to container port 80. 80 would be used in NGINX config

NGINX CONFIG
just to give you a jumpstart if needed
I’m not a networking guru so verify below but it should work
I have subdomains but you could also use different domain name or other method. NGINX looks for requested server name and port in a specified order to determine request routing

user root; #probably don't want to run as root

#################################################
#                     EVENTS                    #
#################################################
events {
    worker_connections  4096;
}


#################################################
#                    HTTP                       #
#################################################
http {


    #############################################
    #             WWW @ lOCALHOST               #
    #############################################
    server {
        listen          8080 default_server;
        server_name     yoursite.com;
        #access_log      logs/big.server.access.log main;

        location / {
            root /var/www;
        }
    }

    #############################################
    #               HTTP HASS EXAMPLE           #
    #############################################
    server {
        listen          8080;
        server_name     subdomain.yoursite.com;
        #access_log      logs/big.server.access.log main;

        location / {
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass    http://192.168.0.1:8123; #http request to subdomain can forward to separate internal server 
        }
    }       

#############################################################################
#                             HTTPS SERVER                                  #
#############################################################################

    #############################################
    #                 @ WEBROOT                 #
    #############################################
    server {
        listen               443 ssl;
        server_name          yoursite.com;
        ssl                  on;
        ssl_certificate      /etc/locationofyourcert//fullchain.pem;
        ssl_certificate_key  /etc/locationofyourcert/privkey.pem;
        ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers          HIGH:!aNULL:!MD5;

        location / {
            root /var/www;
        }

    }


    #############################################
    #                 HTTPS HASS EXAMPLE        #
    #############################################
    server {
        listen               443 ssl;
        server_name          subdomain.yoursite.com;
        ssl                  on;
        ssl_certificate      /etc/locationofyourcert/fullchain.pem;
        ssl_certificate_key  /etc/locationofyourcert/privkey.pem;
        ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers          HIGH:!aNULL:!MD5;

        location / {
            proxy_set_header Host $host;
            proxy_redirect http:// https://;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass                    http://192.168.0.1:8123; 
            proxy_buffering               off;
            proxy_ssl_verify              off;
        }

    }

}
###############################################
#                 FILE END                    #
###############################################
1 Like

Hello Luis,
Sorry to bother you with this old post,
I am building my network in a new build and have came across pFSence firewall/Router.
Which router are you using? What you suggest for a normal size family network from their product range.

Anil

@tmjpugh thank you for sharing this. I was stuck and can now see HA. Could you advise how to add additional proxy_pass.
So for instance I want to add the configurator to the panel frame, so It needs a pass.
http://192.168.0.1:3218

thank you

I now drop all http requests and accept only https pretty much.

I will post updated example later tonight

@tmjpugh, thank you. Looking forward :grinning:

@tmjpugh wandering if you could share your conf. Thank you

not a complete config but I think it shows what you were looking for
I am NO nginx expert so Please Read NGINX docs and understand(maybe improve) the items below. I didnt just copy paste but I do know I should reread docs myself and look over my below config for security errors

http {

    server {
        return 404;
    }

    #################################################
    #           HTTP UPSTREAM SERVERS               #
    #################################################

    upstream homeassistant_backend {
        server 192.60.27.12:8123;
        server 192.60.27.13:8123;
    }

    upstream unifi_8443_backend {
        #ip_hash;
        #least_conn;
        server 192.60.27.12:8443;
        server 192.60.27.13:8443;
    }


    #############################################
    #                 HTTP HASS                 #
    #############################################
    server {
        listen          80;
        server_name     myserver.com;

        location / {
            return 444;
        }
    }


#############################################################################
#                                                                           #
#                                                                           #
#                             HTTPS SERVER                                  #
#                                                                           #
#                                                                           #
#############################################################################

    #############################################
    #                 HTTPS HASS                #
    #############################################
    server {
        listen               443 ssl;
        server_name         myserver.com;
        access_log           /var/log/nginx/access/hass.log;
        #error_log            /var/log/nginx/error/hass.log;
        ssl                  on;
        ssl_certificate      /etc/letsencrypt/live/myserver.com/fullchain.pem;
        ssl_certificate_key  /etc/letsencrypt/live/myserver.com/privkey.pem;
        ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers          "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        proxy_buffering      off;

        location / {
            proxy_pass       http://homeassistant_backend;
            proxy_set_header Host $host;
            #proxy_redirect   http:// https://;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection default_upgrade;
        }

    }

#############################################
#                HTTPS UNIFI                #
#############################################
server {
    listen               443 ssl;
    server_name          unifi.myserver.com;
    access_log           /var/log/nginx/access/unifi.log;
    #error_log            /var/log/nginx/error/unifi.log;
    ssl                  on;
    ssl_certificate      /etc/letsencrypt/live/myserver.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/myserver.com/privkey.pem;
    ssl_trusted_certificate     /etc/nginx/.ssl/unifi.pem;
    ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers          HIGH:!aNULL:!MD5;

    location / {
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    proxy_pass                    https://unifi_8443_backend; 
        proxy_buffering               off;
        proxy_ssl_verify              off;
        
    }

 }
###############################################
#                 FILE END                    #
###############################################

@tmjpugh thank you very much. I’ve copied it and I can see the HA instance, however, I cant access the second instance (unifi in your case). couple of questions. in your upstream section you pair 2 ips per server?

and in the unifi seciton you use ssl_trusted_certificate /etc/nginx/.ssl/unifi.pem;
is this to replace a wild card cert? thank you

upstream 2 IP point to server with dual nic. This is round robin load balance.
http://nginx.org/en/docs/http/ngx_http_upstream_module.html

ssl_trusted_certificate is for unifi server self-signed cert. if you point to ssl server you must trust the certificate it uses
http://nginx.org/en/docs/http/ngx_http_ssl_module.html