Home Assistant under double nat access from outside

At home I have a PC installed with Home Assistant OS. My intention was to install DuckDNS to have access from the outside with the application and to integrate it with Google Home.

The problem arises in that in my house I have the router of the company with DMZ to another router that is the one that acts as Firewall and has full control (it is a Mikrotik).

The flow would be as follows:

  1. Public IP
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. Company Router with address 192.168.BBB.2
    +DMZ to 192.168.BBB.1 (Mikrotik Router Address)
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3. Mikrotik Router
    +On the one hand address 192.168.BBB.1 (connect to Router Company)
    ++ Public IP address assigned by the Mikrotik cloud (xxxxxx.sn.mynetname.net)
    +On the other 192.168.AAA.1 (connect to Local Network)
    ++Open port 8123 to 192.168.AAA .10 (PC Home Assistant Address)
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. PC Home Assistant with address 192.168.AAA.10 on port 8123.

Right now I don’t have anything installed from DuckDNS. Mikrotik assigns me an address (xxxxx.sn.mynetname.net) assigned to the Public IP (it updates correctly) and I only have port forwarding active (DMZ on the first router towards the Mikrotik router and port 8123 towards the Home Assistant) and it should work (without https), but it doesn’t.

I have tried redirecting to another address (another PC that I have) and it works, so I think it must be something from the Home Assistant configuration although I am not sure.

I know that an ideal solution would be the purchase of Home Assistant Cloud but my economy does not allow it.

Can someone help me? Thank you

Did you set up reverse proxy on home assistant ?

Is the company router forwarding all ports or just configured ports to Mikrotik, and if it is the latter case, is 8123 configured for forwarding?

No, I don’t know that setting. I would appreciate knowing how to do it.

The company’s router forwards all ports to Mikrotik and, on the Mikrotik router, configured 8123 to redirect it to the Home Assistant server (192.168.AAA.10)

oke, I will post you my config. It should work for remote access but I use it for local ssl only.
configuration.yaml settings

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.30.33.0/24

I use NGINX Home Assistant SSL proxy. In addon config use

active: true
default: nginx_proxy_default*.conf
servers: nginx_proxy-my_host*.conf

You have to create ^^ server config file in /share directory for addon to use it.
My config file is

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    server_name YOUR_DOMAIN_NAME;
    ssl_certificate /ssl/fullchain.pem;
    ssl_certificate_key /ssl/privkey.pem;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    listen [::]:443 ssl http2 default_server ipv6only=on;
    ssl_protocols TLSv1.3;
    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_set_header   X-Real-IP $remote_addr;
        proxy_pass http://172.30.32.1:8123;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
#        proxy_set_header Connection $connection_upgrade;
    }
}

Thank you but I would like to use my domain and LetsEncrypt directly without using a reverse proxy (NGINX). The problem is that now neither the SSL certificate is configured, only port forwarding over http and it doesn’t work. I would like to go step by step and try this first and then DuckDNS+Lets Encrypt and finally try NGINX if necessary.

Still, thanks a lot for the help.

Does Home Assistant need some kind of configuration for access from the outside? Is https necessary?

As I known you need reverse proxy for remote access and ssl. Without it will not work regardless of your network config.
Https is not necessary, but you should use it as your ha is exposed to the net.

This isn’t an IP address, it’s a url. Are you actually given an IP address by Mikrotik cloud or are you only given a url?

If it’s the latter then I assume Mikrotik is using a tunneling system, like cloudflared or nabu casa cloud. If so then what’s likely happening is you’ve been using a proxy, you just didn’t know about it. That’s how those tunneling systems work.

Are you able to see the requests that come from the Mikrotik cloud url when you use it on your network? Do they have an x-forwarded-for header set by Mikrotik? If so that’s the issue. HA rejects requests that have been forwarded by a proxy unless the proxy is in the list of trusted_proxies. That would explain why it works with the other computer but not with HA. HA is receiving them, it’s just rejecting them for security reasons. There should also be errors in your HA logs if that’s what is happening. You’ll need to add the ips mikrotik is using as a trusted proxy to use that.

No, a reverse proxy is not required. You can set SSL options in http config. But using a reverse proxy is recommended over putting the SSL info in HA. Since then you can still talk to HA internally on your LAN without SSL errors. Also you can renew the SSL certificate without restarting HA.

Let me get this straight. Ha is running in docker. Reverse proxy is used to enable access to your docker network from outside. This outside is usually some domain which might or might not have ssl.
I’m not that sure that you can access ha without reverse proxy regardless of ssl simply because reverse proxy will enable access from outside to the docker internal network.
Or I’m missing something?

You’re missing something. The homeassistant container runs on the host network. So whatever port specified here is bound on the host, not the container.

Even if HA wasn’t running on the host network, docker let’s you map ports on the host to ports on the container as part of creating a container. It’s no different then how your router works when you do port forwarding. There’s no proxying or reverse proxy involved.

I agree with you that port is bounded to host. That is why you can access internal docker network from homeassustant local.
But if you want to use a domain and access your host as domain than you will have to use reverse proxy.
It doesn’t matter does this domain resolve to your public ip or your host ip.
In my case my domain is resolved to my host ip. If I turn off reverse proxy I cant access my ha instance regardless that it is running on the same ip as my local host.

Right. Because you set it up that way. Which is great, nothing wrong with that, that’s how I did it too.

However lots of other people forward a port on their router to 8123 on their HA machine. And then they list their SSL certificate here. That also works just fine. In fact that’s exactly what the docs for the DuckDNS addon tell you to do. Notice this has no mention of a reverse proxy and just has you list the SSL certificate in HA.

I am 100% certain this works as I have done it before. If you don’t believe me, give it a try for yourself.

I believe you, I don’t have that setup but I think that you are right on this.
Let me ask you one thing.
You saw my setup in this thread. I have problem accessing uptime kuma using ssl on my local host. Everything else is working fine. I can’t access uptime kuma using nabu casa cloud. On my local ssl I get ssl error.
If I do in terminal

curl -i --verbose https://MY_DOMAIN:3001 "Authorization: Bearer TOKEN"

I get this

Trying 192.168.31.103:3001...
* Connected to MY_DOMAIN (192.168.31.103) port 3001 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
* Closing connection -1
curl: (3) URL using bad/illegal format or missing URL

Token is oke, I can access adguard on port 80 TLS handshake is oke, SSL cert oke, but I can’t access uptime kuma.
Did you set up uptime kuma to work with ssl and what do you think how can this be done?

Sorry not really sure. I’ve never used Uptime Kuma.

Also at this point this sounds like a different topic. I did the back and forth in here before because I didn’t want the OP to be under the impression that a reverse proxy was required if they didn’t want to use one. But Uptime Kuma is definitely a different topic. I would suggest starting a thread about that to see if other folks have encountered that issue and can help.

Why? I don’t have a reverse proxy…I use loopback NAT on my router…
But before that, I used just my plain own DNS…also worked fine, except I had to add :8123 for local IP’s :wink:

What Mikrotik provides me is simply a URL that always points to my IP and updates itself (it’s the Mikrotik Cloud). For us to have an example, it’s like DuckDNS.

Oh ok. Sorry I am not familiar with Mikrotik and seems I misunderstood what you said earlier.

In that case I guess a few things to try:

  1. Confirm that your mikrotik URL does point to the right IP address by doing dig xxxxxx.sn.mynetname.net and confirming the result matches your public IP address. Double NAT can create issues and sometimes you find that your URL is resolving to the router’s LAN IP and not your public one.
  2. Try changing the port mapping on your router. Instead of doing 8123 -> 8123 do like 80 -> 8123 (if using http) or 443 -> 8123 (if using https). Sometimes services controlling access only allow specific well-known ports and if so 8123 likely isn’t on the list.

If that doesn’t work and you can definitely confirm putting some other machine/software on the end works without issue then take a look at your Home Assistant logs. If the requests are getting all the way through and then failing at HA there must be errors in the logs that give some insight.

  1. This is not the problem, since I have tried and it gives me my public IP address and not that of the Mikrotik router.
  2. I have tried it with 80 and 443 and it doesn’t work.

Regarding what I said at the beginning, I’ve tried other devices (another server) and it doesn’t work for me either, so I think it’s a port problem and not Home Assistant