Reverse proxy error

Sorry if its wrong to post it in this thread

I have actually faced another problem after adding my nginx proxy ( my homeassistant is in a docker and running stable tag ).
I were able to fix the 404, “Received X-Forwarded-For header from an untrusted proxy”
by adding the proxy’s ip to the configuration.yaml

But the next issue is then that as soon I then log in and it accept my credentials its then saying “Unable to connect to Home Assistant.” on the webpage.

is there some other settings that I don’t know of?
it does works fine when I call it on the home assistants mapped ip and port directly ( so starting to think its actually after i entered the server_name in nginx there is giving me the issue )

Is there somewhere else we also need to remember to set the server name within homeassistant?

Hey, my docker swag works fine with home assistant, I just had to set the trusted_proxies with appropriate netmask

# swag reverse proxy
http:
  use_x_forwarded_for: true
  trusted_proxies:
   - '10.10.0.0/16'

In this case the networks are on 10.10.x.x classes just because I’ve set

  "default-address-pools":
  [
    {"base":"10.10.0.0/16","size":24}
  ],

within /etc/docker/daemon.json, but it should even work for networks from other address pools, i.e. 172.17.0.0/12 and so on… provided that the trusted_proxies netmask includes the network of your actual reverse proxy.

Nevermind. Looks good now. Was pointing at the wrong config file. :slight_smile:

thanks for your comment, it was very useful!

1 Like

I believe I’m having the same problem.

With docker-compose service name and network name are synonymous. So if I use the network name of a service, it should be the same as using the IP of the service. This is the case for the mqtt integration and the mosquitto service I have running, but does not seem to be the case for my ipv4_address when it comes to the caddy service I have running.

Here’s my docker-compose: tbro-server/docker-compose.yml at 4725320f1224dc73032b0507fa944f4893821fca · TonyBrobston/tbro-server · GitHub

For now I’ve hardcoded the IP of my caddy service, however for whatever reason that IP changed today, so I had to update it; this is the whole point of the network name.

Any advice? Is this a bug?

This will only work for docker services running in bridge network mode. Home assistant runs in “host” network mode, so you will not be able to reference it from another docker container by container name as it is running outside of the docker network. You will have to spell out the host IP address and add :8123. This would be the same for any of your other containers running in host network mode.

I looked at your compose and do not see any network settings in the compose. Not sure how you hardcoded the IP of the caddy service, but I’m running the swag container and found the only way to keep the IP static and not move around on me is to add the IP into the docker compose.

This is my compose for the swag container defining a static IP

version: "2.1"
services:
  swag:
    image: linuxserver/swag
    container_name: swag
    restart: unless-stopped
    cap_add:
    - NET_ADMIN
    volumes:
    - /home/tim/docker/swag/config:/config
    - /etc/localtime:/etc/localtime:ro
    environment:
    - PGID=1000
    - PUID=1000
    - [email protected]
    - URL=yourdomain.duckdns.org
    - SUBDOMAINS=wildcard
    - VALIDATION=duckdns
    - TZ=yourtimezone
    - DUCKDNSTOKEN=yourtoken
    - MAXMINDDB_LICENSE_KEY=yourkey #this is optional for location based IP banning
    ports:
    - "80:80"
    - "443:443"
    networks:
      default:
        ipv4_address: 172.21.0.2

More discussion about this as well on this thread - Nginx Reverse Proxy Set Up Guide – Docker - #285 by mwav3

@mwav3
Home Assistant only runs in “host” network mode if you add network_mode: host to that service in your docker-compose, Home Assistant doesn’t have to run in host network mode. When running containerized services I prefer to expose only exactly what needs exposed.

According to the docker-compose docs (Networking in Compose | Docker Docs):

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

So in this situation, caddy is the container name and therefore the hostname; because I’m not running network_mode host, this should just work; and it does work for many other things like my mqtt setup.

The docs also say:

If you make a configuration change to a service and run docker-compose up to update it, the old container is removed and the new one joins the network under a different IP address but the same name. Running containers can look up that name and connect to the new address, but the old address stops working.

So, if the IP changes and you’re referencing the hostname in Home Assistant’s configuration, then things should be fine.

For now I’ve grabbed the IP out of Home Assistant’s logs and hardcoded it here (I also verified that this IP is the IP of my caddy service):

http:
  use_x_forwarded_for: true
  trusted_proxies: [hardcoded IP here]

I was thinking the configuration should just be (however this doesn’t work, here is the conatiner/network name: tbro-server/home-automation/docker-compose.yml at 4725320f1224dc73032b0507fa944f4893821fca · TonyBrobston/tbro-server · GitHub):

http:
  use_x_forwarded_for: true
  trusted_proxies: caddy

But I’m wondering if it should really be http://caddy or http://caddy:443 or something along those lines… it’s also possible that there is a bug and it doesn’t work by network name, though the docs say it should here: HTTP - Home Assistant

List of trusted proxies, consisting of IP addresses or networks, that are allowed to set the X-Forwarded-For header.

It’s also possible to hardcoded the IP of the container in the docker-compose, however this shouldn’t be necessary based on the rest of the info above. I try my best not to subscribe to “just getting it to work”, less code = less maintenance; I try my best to let the abstractions do their job.

Does anyone else have any ideas? I’m certainly opening to trying some suggestions.

I missed you weren’t running Home Assistant in host networking mode. Technically your supposed to for a “supported” install but if your fine without the autodiscovery and aren’t using any integrations that needs host networking mode it will work and then they’ll be on the same docker network.

I know in an nginx config to reference other containers by name you would need to spell out the http - http://container for port 80 or https://container for port 443, but I have no idea if that would work in a Home Assistant config.yaml. You can try it but if not hopefully someone else can chime in.

Just keep in mind that if you’re not running HA in host mode, broadcasts will work neither from nor to HA.

That means no discovery, wol, upnp, …

If you want to default back to the old Home Assistant behavior (e.g. all IP’s are whitelisted), here is the config:

http:
    use_x_forwarded_for: true
    trusted_proxies:
      - 0.0.0.0/0 

This will allow all incoming traffic.

1 Like

I have discovery working through an mDNS Repeater. This container is ran in host mode, the thought is that it’s only doing mDNS Repeating and nothing else; so I can justify running it in host mode. This might seem a little backwards, however I think it complies closer to the, “How much security is the right amount? As much as possible.” philosophy. Opening everything up in Home Assistant to the host seems like opening the fire hose when you only want a sprinkle.

I guess it depends how you see containers.
I see them as a convenience, not really as a security mechanism, and definitely not for HA.

From a KISS perspective, adding components to workaround security settings that you decided to implement yourself seem dubious :wink:

1 Like

Worked for me aswell - I am using Traefik as proxy

After my last message I had to edit my configuration to include all addons IPs because when I upgraded and restarted Home Assistant OS the IP of Nginx changed and it broke again.

This is my working configuration:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 127.0.0.1
    - 172.16.0.0/12
    - ::1

1 Like

I am running HA inside a docker container on my Raspberry Pi 3 with nginx as a reverse proxy running on a Raspberry Pi Zero and had the same issue and removing proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; also solved it for me. Thank you for sharing @dvoijen .

@frenck Can you maybe explain the security risk here? I am not to deep into that topic and don’t get it.

this worked for me as well. Thank you

At this point does anyone have a working config for a reverse proxy with apache? I’ve seen configs for ngnix and traefik, but not Apache since about July. There’s a few threads on it:

In that thread, people are adding their reverse proxy based on an IP being blocked from the logs, I don’t have any log entries about a proxy being blocked.

I have exactly the same issue with the wss to /api/websocket being blocked, however proxy_wstunnel is already enabled.

This whole /api/api thing didn’t change anything.

I documented my Apache config here back in April, and since then I’ve updated my config to allow both my proxy host IP AND the entire /24 subnet of the proxy, no good:

I’m using this and it works for me anyway. Home Assistant is running on host 192.168.1.1 at default port 8123. One of the problems why it didn’t work at first was the end slashes. For some reason they’re pretty mandatory(?) Also modules like these are required:

  • mod_proxy
  • mod_rewrite
  • mod_http
  • mod_headers
<VirtualHost *:443>
    ServerName ha.domain.co
    SSLEngine on
    SSLCertificateFile	/etc/letsencrypt/live/domain.co/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/domain.co/privkey.pem
			
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass /api/websocket ws://192.168.1.1:8123/api/websocket
    ProxyPassReverse /api/websocket wss://192.168.1.1:8123/api/websocket
    ProxyPass / http://192.168.1.1:8123/
    ProxyPassReverse / http://192.168.1.1:8123/
    
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteRule ^/?(.*) "ws://192.168.1.1:8123/$1" [P,L] 
</VirtualHost>

I was led to this thread, but i’m just feeling more confused now. My setup was working just fine (HassOS, NGINX Proxy Manager) until a few days ago when i got a new phone. I got to the login screen, but my login attempt was refused. Also upgraded my PC to Win11, and it also got rejected. I found a “hack” that works, but not for long i suppose, as i added the remote IP range (Cloudflare: 162.158.222.0) to the thrusted proxies. I think my problem is that i have ip_ban_enabled: true also. As I read the documentation, the use_x_forwarded_for: true will forward the remote device/service IP to HA, instead of the reverse proxy’s IP. But in that case, I would have to enable all possible IP ranges that Cloudflare might use in my case, and that seems counter-intuitive. If I understand this correctly, I don’t see any practical way of combining ip_ban_enabled and a reverse proxy. Or am I misunderstanding this?

I am relatively new to Home Assistant and have installed Nginx for a separate requirement on a separate Raspberry Pi 4 in a docker container. I am having the same issues as discussed above and attempted different trusted IP addresses with no luck at all.

I can get to the login page but after login I get a message “Unable to connect to Home Assistant”

The log indicates: 2022-01-16 15:11:16 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from 110.xxx.xxx.xxx (110.xxx.xxx.xxx). (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55)

Seems like the Nginx is not allowing the authentication to pass through to HA?

I would appreciate any ideas or pointers.