mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-10-25 08:20:10 +01:00
Reported from a remote session: ingress answered `403 External internet access denied - https://sabnzbd.org/access-denied`. Root cause is `check_access()` in `sabnzbd/interface.py`: # Never check the XFF header unless access would have been granted # based on the remote IP alone! if is_allowed and cfg.verify_xff_header() and (xff_ips := ...): is_allowed = all(is_local_addr(ip) or is_loopback_addr(ip) for ip in xff_ips) nginx's own address is loopback, so the first test passes, and then every address in X-Forwarded-For has to be local too. Supervisor puts the browser's address in that header, so anyone reaching Home Assistant from outside the LAN is refused. `verify_xff_header` defaults to on (`cfg.py:531`), so this is not a configuration a user opted into. Reproduced against the running add-on, `GET /config/general/`: no X-Forwarded-For 200 X-Forwarded-For: 81.164.12.7 403 External internet access denied X-Forwarded-For: 81.164.12.7, 172.30.32.2 403 X-Forwarded-For: 192.168.1.44 200 which is why it worked on the LAN and not from outside. Verified the fix the same way, running the shipped nginx.conf and ingress.conf in front of the live add-on with both variants side by side: the current config 403s on a public address, the fixed one answers 200 for all three chains, and redirects, static roots and the API are unaffected. That instance has an empty `url_base`, so the pass-through routing is now confirmed for both `url_base` values. The header was forwarded because SABnzbd reads it — the wrong test, since what it does with it is reject. Clearing it leaves SABnzbd looking at nginx's loopback address, which is what it saw before the header was added; ingress is gated by Home Assistant authentication before reaching this proxy either way. The evidence.md entry records the methodology error, per the skill's own feed-the-skill rule. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
43 lines
1.8 KiB
Plaintext
43 lines
1.8 KiB
Plaintext
server {
|
|
listen %%interface%%:%%port%% default_server;
|
|
|
|
include /etc/nginx/includes/server_params.conf;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:8080;
|
|
|
|
# SABnzbd refuses any request whose Host is not an IP literal
|
|
# ("Access denied - Hostname verification failed"), so send the
|
|
# upstream socket rather than the browser's host.
|
|
proxy_set_header Host $proxy_host;
|
|
|
|
# X-Forwarded-For must NOT be forwarded. verify_xff_header defaults to
|
|
# on, and check_access() then requires every address in the header to
|
|
# be local, so Supervisor's copy of the browser's public address makes
|
|
# SABnzbd answer 403 "External internet access denied" for anyone
|
|
# reaching Home Assistant from outside the LAN. Clearing it leaves
|
|
# SABnzbd looking at nginx's own loopback address. Access is gated by
|
|
# Home Assistant authentication before it ever reaches this proxy.
|
|
proxy_set_header X-Forwarded-For "";
|
|
|
|
# The interface itself only emits relative links, so no body
|
|
# rewriting is needed. Redirects are the exception: Raiser() emits
|
|
# a path under url_base, so prefix them with the ingress entry.
|
|
# absolute_redirect must stay off, or nginx expands the rewritten
|
|
# Location into http://<browser host>:<ingress port>/..., a port the
|
|
# browser cannot reach.
|
|
proxy_redirect / %%ingress_entry%%/;
|
|
absolute_redirect off;
|
|
|
|
# The login cookie is hardcoded to Path=/, which on the ingress
|
|
# origin would send it to every other add-on's ingress path too.
|
|
proxy_cookie_path / %%ingress_entry%%/;
|
|
|
|
proxy_http_version 1.1;
|
|
proxy_read_timeout 86400s;
|
|
proxy_send_timeout 86400s;
|
|
}
|
|
}
|