Skip to content

Accessing LAN applications with HASSio Nginx Reverse Proxy Addon

 

DuckDNS subfolder reverse proxy configuration for SSL access to LAN resources

Have you ever needed to access LAN resources while you’re away?  Have all of the news of hacks leave you feeling queasy about exposing additional ports on your router?  Then this might be a solution that you can implement in a matter of minutes.

Initially, when I started using HASSio, I was happy to see that the addons included Nginx for reverse proxy.  Unfortunately, it was very limited with what it would let you configure.  Fast forward a handful of months and the devs have added the ability to customize the addon with custom server configurations.  For me, this is great, because I’ve installed HASSio Raspberry Pis at three family member’s houses.

At this point, I’m assuming you have your HASSio instance up and running.  If not, there are plenty of how to’s to walk you through this process just a Google away.  In order to expose your instance to the world, you should have SSL certificates on the site.  The best way to do this with HASSio is to use the DuckDNS addon and enable it to have Lets Encrypt handle automagically getting the certificates.   Once this is done, you should be able to access Home Assitant without trouble from the WAN at your DDNS url of yourcustomurl.duckdns.org.  If you own your own domain, it’s a bit different, but let me know if the comments and I will help where I can.

 

Follow these steps

Now add the addon via Hass.io panel > Addon Store > NGINX Home Assistant SSL proxy and click install.  After the install finishes, you will need to add your DuckDNS domain (yourcustomurl.duckdns.org) and set the customize > active to true.

If you look at the source for the nginx.conf file, you see the differences between how the default and servers options are utilized.  Since we want to have these sites be subfolders of the DDNS domain instead of subdomains, we need to add our configuration to the default file.

The next step is to create the nginx_proxy_default.conf file in your share folder in the root of your Raspberry Pi.  For me, this was easy to do via SSH and executing  nano /share/nginx_proxy_default.conf.  You can also install the terminal addon and perform it through the web terminal within HA.

For this example, I want to access my TOMATO router configuration.  So I used this configuration:

Here, I’ve set the subfolder as /router/, rewriting the URL to remove the router subfolder so when it hits the router it goes to the base URL, and am passing it to my router’s URL.  The rest of the configuration sets headers and a few other details.

 

To make this easily accessible from within the HA UI, I added an iframe:

You can do this by adding this to your configuration.yaml file:

 

I will mention that while this configuration works for basic resources, some others with more advanced UIs will require additional configuration to pass websockets or APIs.

 

 

Published inHome AssitsantHomeLAB

8 Comments

  1. Christian Christian

    Seems like you missed a “p” in the config above:
    shouldn’t “roxy_pass http://192.168.1.1:80;” be “proxy_pass http://192.168.1.1:80;”?

    But nice turorial – changed from another nginx-setup to this to get this functionality – and it works brilliantly!

    • DK DK

      Thanks for catching the typo, it’s fixed!

      Yea, I’ve tried to use traefik but gave up after spending much more time on it than I’d like to admit. Nginx on the other hand, while it was a steep learning curve to understand the basic premise of how it works, it’s been very easy to use once I got the hang of it. It seems like there wasn’t a whole of info that walked you through how it functions at a high level. Let me know if there’s interest in it, I can make a post about that in the future.

  2. Aaron Aaron

    so, unless i missed it, do I need to install both the DuckDNS Add-on AND the NGINX Add-on, or just the NGINX? I have been wanting something like this for a while

    thanks

    • DK DK

      Check out the last paragraph of the intro that outlines my assumptions for this example.

      In short, there are three components in play to make this work in addition to your served application:
      1. DuckDNS addon – Gives you a free (sudo) domain updated to the IP address of your server
      2. LetsEncrypt addon – Gives you SSL certs to keep your communications encrypted for safety
      3. Nginx addon – Routes requests to additional services on your domain via subdomains or subfolders

  3. ys ys

    I’ve followed your tutorial. Works great thanks. However be sure to have authentication on every iframe you’ll add. Because if you go directly to the url for example. yourhome.com/router you’ll get served the iframe without logging in to homeassistant.

    • DK DK

      That’s a good point!

      Make sure you only expose things that require logging in. This way you have still have some user authentication before exposing the device.

  4. Glen Glen

    Hi DK,

    I am having a lot of trouble getting this to work. I have a Raspberry Pi 3 with hass.io.

    I have successfully set up hass.io with duckdns.org to use SSL I have port forwarded through a static ip address. This has been working for months.

    I want to use NGINX to put mythweb into an iframe. I’ve also attempted to add my router, my isp’s web portal and a few Hassio services. None work. All say 404 error.

    Please help if you have time.

    Here is my /share/nginx_proxy_default.conf


    location /router {
    rewrite /router/(.*) /$1 break;
    proxy_pass http://192.168.1.1:80;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    location /mythweb {
    rewrite /mythweb/(.*) /$1 break;
    proxy_pass http://192.168.1.200:80/mythweb;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    location /zoneminder {
    rewrite /zoneminder/(.*) /$1 break;
    proxy_pass http://192.168.1.200:80/zm;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    location /isp {
    rewrite /isp/(.*) /$1 break;
    proxy_pass https://www.isp.com/myisp;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    location /terminal {
    rewrite /terminal/(.*) /$1 break;
    proxy_pass https://example.duckdns.org:7681;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    location /config_editor {
    rewrite /config_editor/(.*) /$1 break;
    proxy_pass https://example.duckdns.org:3218;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    location /ide {
    rewrite /ide/(.*) /$1 break;
    proxy_pass https://example.duckdns.org:8321;

    proxy_redirect http:// https://;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    }

    Here is my iframe config from /config/configuration.yaml

    panel_iframe:
    ide:
    title: 'IDE'
    url: https://example.duckdns.org/ide/
    icon: mdi:code-tags
    config_editor:
    title: 'Config Editior'
    url: https://example.duckdns.org/config_editor/
    icon: mdi:wrench
    terminal:
    title: 'Terminal'
    url: https://example.duckdns.org/terminal/
    icon: mdi:console
    router:
    title: 'Router'
    url: https://example.duckdns.org/router/
    icon: mdi:router-wireless
    mythweb:
    title: 'MythWeb'
    url: https://example.duckdns.org/mythweb/
    icon: mdi:television-guide
    zoneminder:
    title: 'ZoneMinder'
    url: https://example.duckdns.org/zoneminder/
    icon: mdi:cctv
    isp:
    title: 'isp'
    url: https://example.duckdns.org/isp/
    icon: mdi:web

    DK EDIT: I added code TAGs so it’s easier to read

    • DK DK

      Glen,

      I’d recommend trying to simplify the setup as much as possible and starting out with one forward. I would try it with mythweb as it’s an internally hosted resource. You can look around to try to find nginx configs for mythweb in case there are additional headers that you need to send.

      There should be some error logs generated too but I have not looked for these.

Leave a Reply

Your email address will not be published. Required fields are marked *