Getting 400 when accessing Home Assistant through a reverse proxy (dockerized nginx)

Hi,

I have a clean instance of HASS which I want to make available through the internet and an already running instance of NGINX with configured SSL via Let’s Encrypt.

When I try to access it via the subdomain, I am getting 400 Bad Request and the logs from the HASS Docker container prints:

2021-12-31 15:17:06 ERROR (MainThread) [homeassistant.components.http.forwarded] A request from a reverse proxy was received from 172.19.0.3, but your HTTP integration is not set-up for reverse proxies

Other subdomains from the same NGINX instance I can access without an issue.

I added the IP address and multiple other things (including 0.0.0.0/0) into the HASS configuration.yml as trusted_proxies, but it does not seem to change anything. I also verified that the IP adress is the correct one via docker network inspect and it seems to be the case (output below).

Also when I log into the bash of the HASS docker container, I can ping the nginx instance without a problem using its IP address or hostname.

I posted all the relevant configurations below.

Thanks in advance for any hints, since I’m fairly new to HASS.

BR,
Patrick

docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /home/pi/docker/nginx/etc/nginx/conf.d:/etc/nginx/conf.d
      - /home/pi/docker/nginx/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /home/pi/docker/nginx/www/data:/www/data
      - /home/pi/docker/certbot/conf:/etc/letsencrypt
      - /home/pi/docker/certbot/www:/var/www/certbot
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot:arm32v6-latest
    restart: unless-stopped
    volumes:
      - /home/pi/docker/certbot/conf:/etc/letsencrypt
      - /home/pi/docker/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
  homeassistant:
    image: "ghcr.io/home-assistant/home-assistant:stable"
    volumes:
      - /home/pi/docker/home-assistant:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8123:8123
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    restart: unless-stopped
    privileged: true

hass.conf (nginx config)

upstream homeassistant {
  server        nginx_homeassistant_1:8123;
}

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

server {
    # Update this line to be your domain
    server_name hass.my.domain;

    # These shouldn't need to be changed
    listen 80;
    
    location / {
        return 301 https://$host$request_uri;
    }
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    # Update this line to be your domain
    server_name hass.my.domain;

    # Ensure these lines point to your SSL certificate and key
    ssl_certificate /etc/letsencrypt/live/my.domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my.domain/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;

    # Ensure this line points to your dhparams file
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;


    # These shouldn't need to be changed
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    # ssl on; # Uncomment if you are using nginx < 1.15.0
    ssl_session_cache shared:SSL:10m;

    proxy_buffering off;

    location / {
        proxy_pass http://homeassistant;
        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 $connection_upgrade;
    }
}

configuration.yaml

# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:

# Nginx Proxy stuff
http:
  base_url: https://hass.my.domain
  server_port: 8123
  # For extra security set this to only accept connections on localhost if NGINX is on the same machine
  # Uncommenting this will mean that you can only reach Home Assistant using the proxy, not directly via IP from other clients.
  #server_host: 127.0.0.1
  use_x_forwarded_for: true
  # You must set the trusted proxy IP address so that Home Assistant will properly accept connections
  # Set this to your NGINX machine IP, or localhost if hosted on the same machine.
  trusted_proxies:
    - 0.0.0.0/0
    # Other things I tried
    # - 127.0.0.1
    # - 172.19.0.0/16
    # - 172.19.0.0/24
    # - 172.19.0.3/16
    # - 172.19.0.3/24
    # - 192.168.0.0/24
    # - 192.168.1.0/24
    # - nginx_nginx_1
  ip_ban_enabled: true
  login_attempts_threshold: 5

# Text to speech
tts:
  - platform: google_translate

group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

docker network inspect nginx_default

[
    {
        "Name": "nginx_default",
        "Id": "5b1ead5cbd4acce47b13e2a26ea4afa755754923d52a4c2ec836e9ca96672760",
        "Created": "2021-12-31T14:05:12.356005105+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "3e661d1ec5f5a9cae39bfad97ca0181a69702b5c61dc044598309582727c4aea": {
                "Name": "nginx_homeassistant_1",
                ...
                "IPv4Address": "172.19.0.4/16"
            },
            "ad70140d7b3c5d99503c1c2757f5e8a66cc6acc8dc87fa2681e8157031127f56": {
                "Name": "nginx_certbot_1",
                ...
                "IPv4Address": "172.19.0.2/16"
            },
            "c6f219b5437bcaa21ba06de2dca3f6d295ed5944a07e42184722e976566a6ed4": {
                "Name": "nginx_nginx_1",
                ...
                "IPv4Address": "172.19.0.3/16"
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "nginx",
            "com.docker.compose.version": "2.0.0"
        }
    }
]

Did you try searching the forum? you may find the solution in this thread. you probably need to list the actual ip address of your reverse proxy in the config.

Hi,

thanks for you answer. I tried multiple things from the forum, including adding 127.0.0.1 (which is suggested in your link). I also came across the 0.0.0.0/0 setting which - if I got this right - would be basically “allow any proxy”, which I tried but didn’t work for me too.

I actually tried so many things related to the trusted_proxies configuration that I’m wondering whether this is actually part of the problem or I am missing something different.

The HA error says the reverse proxy ip address is 172.19.0.3 Docker containers many times set up their own network for local communication.

Yes I’m aware of that.
When I enter docker network inspect <NETWORK_NAME>, I also get the IP address from my NGINX instance (which was 172.19.0.3 in my inital post). Even if I add exactly this IP address to my configuration.yaml, I still receive the same error.

http:
  trusted_proxies:
    - 172.19.0.3
            "c6f219b5437bcaa21ba06de2dca3f6d295ed5944a07e42184722e976566a6ed4": {
                "Name": "nginx_nginx_1",
                ...
                "IPv4Address": "172.19.0.3/16"
            }

Did you restart HA after making that change?

You might want to try adding a subnet mask like this 172.19.0.3/32 That specifies that particular address.

Yes I restarted via HASS panel and since that didn’t work also tried to restart the container. Same behavior when using 172.19.0.3/32.

Can I somehow verify that this configuration.yaml file is even used? All I know is that when a syntax error exists in the file HASS doesn’t boot up. Is that enough evidence?

Home Assistant does some configuration checks if you ask That option os on the Server Controls configuration page. I am using 2021.11.5 so the menu path may have changed in 2021.12.x.

Okay config file seems to be fine.

Anything different show up in the HA logs or just the same error?

I see a second error now, but it seems to happen much later. But nothing else.

(IP changed since I recreated the containers)

OK to help with the changing addresses try 172.16.0.0/16 as the proxy. That should include that whole subnet.

Okay, with that I can at least somewhat enter the HASS instance. Thank you very much :slight_smile:

1 Like

I am glad it worked out. I hope you have a less frustrating 2022.

This fix eventually stops working, but there’s still a way. Over time, my Docker install started to venture outside of the .16 subnet.

The secret? Run the following in Google Colab:

for i in range(256):
  print(f"    - 172.{i}.0.0/16")

Then paste the output into configuration.yaml under http → trusted_proxies. Simply typing 172.0.0.0/8 will not work.

If anyone here from HomeAssistant is watching, it would be so nice to have a proper fix for this.

Hi. You may need to specify a static ip address for nginx in your docker compose file so that it does not change every time you rebuild your containers. This would be an easier solution than guessing which ip it will rebuild. This appears to be the OP’s problem. I had to switch from nginx and certbot to swag to keep homeassistant on network_mode: host.