{"id":19688,"date":"2024-01-08T15:58:49","date_gmt":"2024-01-08T20:58:49","guid":{"rendered":"https:\/\/nuxx.net\/blog\/?p=19688"},"modified":"2025-05-30T12:52:21","modified_gmt":"2025-05-30T16:52:21","slug":"nginx-on-opnsense-for-home-assistant","status":"publish","type":"post","link":"https:\/\/nuxx.net\/blog\/2024\/01\/08\/nginx-on-opnsense-for-home-assistant\/","title":{"rendered":"NGINX on OPNsense for Home Assistant"},"content":{"rendered":"\n<p>I&#8217;ve been experimenting with <a href=\"https:\/\/www.home-assistant.io\/\">Home Assistant<\/a> (HA) for some temperature monitoring around the house. It has a great mobile client that&#8217;ll work across the public internet, but HA itself unfortunately it only does HTTP by default. It has some minor built in support for HTTPS by using the <a href=\"https:\/\/github.com\/home-assistant\/addons\/tree\/master\/nginx_proxy\">NGINX<\/a> proxy and <a href=\"https:\/\/github.com\/home-assistant\/addons\/tree\/master\/letsencrypt\">Let&#8217;s Encrypt (LE)<\/a> <a href=\"https:\/\/github.com\/home-assistant\/addons\/\">Add-ons<\/a>, but for a couple of reasons<a href=\"#f1\">[1]<\/a> I didn&#8217;t like this solution. I&#8217;m not about to expose something with credentials across the public internet via plain HTTP, so I wanted to do this proxying on my firewall instead of on the device itself.<\/p>\n\n\n\n<p>My firewall at home runs <a href=\"https:\/\/opnsense.org\/\">OPNsense<\/a> which has an <a href=\"https:\/\/docs.opnsense.org\/manual\/how-tos\/nginx.html\">NGINX Plugin<\/a>, along with a full featured <a href=\"https:\/\/en.wikipedia.org\/wiki\/Automatic_Certificate_Management_Environment\">ACME<\/a> client that I&#8217;m already using for other certificates, so it was perfect for doing this forwarding. After a bit of frustration, fooling around, and unexpected errors I got things working, so I wanted to share a simple summary of what it took to make it work. I&#8217;m leaving the DNS, certificate, and firewall sides of this out, as they&#8217;ll vary and are well documented elsewhere.<\/p>\n\n\n\n<p>Here&#8217;s the steps I used:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set up DNS so the hostname you wish to use is accessible internally and externally. In this example <code>homeass.site.nuxx.net<\/code> will resolve to <code>24.25.26.13<\/code> on the public internet, and <code>192.168.2.1<\/code> at home, which are the WAN and LAN interfaces on the OPNsense box.<\/li>\n\n\n\n<li>Set up the ACME plugin to get a certificate for the hostname you will be using for, in this case <code>homeass.site.nuxx.net<\/code>. Also set up an automation to restart NGINX, and have it do this when the cert is issued.<\/li>\n\n\n\n<li>On your Home Assistant instance, add the following to the <code>configuration.yaml<\/code>. This tells HA to accept proxied connections from the gateway. If you don&#8217;t do this, or specify the wrong <code>trusted_proxy<\/code>, you will receive a <code>400: Bad Request<\/code> error when trying to access the site via the proxy:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>http:\n  use_x_forwarded_for: true\n  trusted_proxies:\n    - 192.168.2.1\/32<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In OPNsense, install NGINX.<\/li>\n\n\n\n<li>In <em>Configuration<\/em> \u2192 <em>Upstream<\/em> \u2192 <em>Upstream Server<\/em> define your HA instance as a server:\n<ul class=\"wp-block-list\">\n<li><em>Description<\/em>: HA Server<\/li>\n\n\n\n<li><em>Server<\/em>: 192.168.2.23 (your Home Assistant device)<\/li>\n\n\n\n<li><em>Port<\/em>: 8123 (the port you have Home Assistant running on, 8123 is the default)<\/li>\n\n\n\n<li><em>Server Priority<\/em>: 1<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In <em>Configuration<\/em> \u2192 <em>Upstream<\/em> \u2192 <em>Upstream<\/em> define a grouping of upstream servers, in this case the one you defined in the previous step:\n<ul class=\"wp-block-list\">\n<li><em>Description<\/em>: Home Assistant<\/li>\n\n\n\n<li><em>Server Entries<\/em>: HA Server<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In <em>Configuration<\/em> \u2192 <em>HTTP(S)<\/em> \u2192 <em>Location<\/em> define what will get redirected to the Upstream:\n<ul class=\"wp-block-list\">\n<li>Toggle <em>Advanced Mode<\/em><\/li>\n\n\n\n<li><em>Description<\/em>: Home Assistant<\/li>\n\n\n\n<li><em>URL Pattern<\/em>: \/<\/li>\n\n\n\n<li><em>Upstream Servers<\/em>: Home Assistant<\/li>\n\n\n\n<li><em>Advanced Proxy Options<\/em> \u2192 <em>WebSocket Support<\/em>: \u2713<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In <em>Configuration<\/em> \u2192 <em>HTTP(S)<\/em> \u2192 <em>HTTP Server<\/em> define the actual server to listen for HTTP connections:\n<ul class=\"wp-block-list\">\n<li><em>HTTP Listen Address<\/em>: Clear this out unless you want to proxy HTTP for some reason.<\/li>\n\n\n\n<li><em>HTTPS Listen Address<\/em>: 8123 and [::]:8123. Leave out the latter if you don&#8217;t wish to respond on IPv6.<\/li>\n\n\n\n<li><em>Default Server<\/em>: \u2713<\/li>\n\n\n\n<li><em>Server Name<\/em>: homeass.site.nuxx.net<\/li>\n\n\n\n<li><em>Locations<\/em>: Home Assistant<\/li>\n\n\n\n<li><em>TLS Certificate<\/em>: Pick the certificate that you created early on with the ACME plugin.<\/li>\n\n\n\n<li><em>HTTPS Only<\/em>: \u2713 (Unless for some reason you wish to support cleartext HTTP.)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Then under <em>General Settings<\/em> check <em>Enable nginx<\/em> and click <em>Apply<\/em>.<\/li>\n\n\n\n<li>Finally, if needed, be sure to create the firewall rule(s) needed to allow traffic to connect to the TCP port you designated in the <em>HTTP Server<\/em> portion of the <em>NGINX<\/em> configuration.<\/li>\n<\/ul>\n\n\n\n<p id=\"f1\">[1] Reasons for doing the proxying on the firewall include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Let&#8217;s Encrypt Add-on won&#8217;t restart NGINX automatically on cert renewal as OPNsense can. This means I&#8217;d have to either write something to do it, or manually restart the add-on to avoid periodic certificate errors.<\/li>\n\n\n\n<li>If NGINX is running on the same device as Home Assistant, then it needs to be on a different port. I prefer using the default port.<\/li>\n\n\n\n<li>I&#8217;d prefer to run just one copy of NGINX on my network for reverse proxying.<\/li>\n\n\n\n<li>While experimenting with NGINX and LE on HA I kept running into weird problems where something would start logging errors or just not work until I restarted the box. With everything running as containers, troubleshooting intermittent issues like these is painful enough that I preferred to avoid it.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been experimenting with Home Assistant (HA) for some temperature monitoring around the house. It has a great mobile client that&#8217;ll work across the public&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/nuxx.net\/blog\/2024\/01\/08\/nginx-on-opnsense-for-home-assistant\/\">Continue reading<span class=\"screen-reader-text\">NGINX on OPNsense for Home Assistant<\/span><\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,13],"tags":[],"class_list":["post-19688","post","type-post","status-publish","format-standard","hentry","category-around-the-house","category-computers","entry"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/comments?post=19688"}],"version-history":[{"count":11,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19688\/revisions"}],"predecessor-version":[{"id":19943,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19688\/revisions\/19943"}],"wp:attachment":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/media?parent=19688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/categories?post=19688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/tags?post=19688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}