mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-09-01 17:53:32 +02:00
feat(sabnzbd): enable Home Assistant ingress (#3019)
* feat(sabnzbd): enable Home Assistant ingress
The add-on already carried a complete but disabled nginx ingress scaffold:
`etc/nginx/` with its includes and a `servers/ingress.conf`, a
`cont-init.d/32-nginx_ingress.sh` short-circuited by `exit 0`, and
`ENV PACKAGES="nginx"` in a Dockerfile byte-identical to nzbget's. Only
`ingress: true` and the s6 service that starts nginx were missing.
What SABnzbd 5.1.1 actually needs from the proxy, measured against the
running add-on rather than assumed:
- Its interface emits only relative links (`href="../../config/general/"`,
`href="../../staticcfg/css/Auto.css"`, `action="./one"`), and grepping the
5.1.1 source for `(href|src|action)="/` across `interfaces/{Glitter,Config,
wizard}` and for absolute `url:` literals in the Glitter JavaScript returns
nothing. A plain pass-through proxy preserves path depth, so no `sub_filter`
is warranted. The previous config's `sub_filter /sabnzbd ...` would also have
mangled the `https://sabnzbd.org/wiki/...` help links present on every
config page.
- Redirects are the one exception: `Raiser()` prefixes `cfg.url_base()`, so
`GET /` answers `303 Location: /sabnzbd/wizard/`. One `proxy_redirect`
handles every observed case; all of them were path-absolute, never a full
URL. Login redirects and logout go through the same `Raiser()`, and the
session cookie's path is hardcoded to `/` (`interface.py:316`), so it is
still sent under the ingress path.
- SABnzbd rejects a Host header that is not an IP literal:
`Host: homeassistant` answers 403 "Hostname verification failed", while
`Host: 192.168.1.5:8123` answers 200. nginx therefore sends `$proxy_host`
instead of including the shared `proxy_params.conf`, which forwards
`$http_host`.
`ingress_entry: sabnzbd` is dropped rather than kept: Supervisor appends it to
the ingress URL, which only resolves while the user's `url_base` is literally
`/sabnzbd`, and that is a setting they can change. SABnzbd serves the same
interface at `/` as under its `url_base` (verified for `/config/general/`,
`/static/`, `/staticcfg/` and `/wizard/`), so entering at the ingress root
works for any value, including the empty code default.
Ingress traffic reaches SABnzbd as `127.0.0.1:8080` and so is not filtered by
a user's host whitelist; direct ip:port access is unchanged and still is.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(sabnzbd): keep the ingress Location relative and scope the login cookie
Exercising the shipped config against the running add-on caught a bug that
reading it did not. With nginx's default `absolute_redirect on`, rewriting
`Location: /sabnzbd/wizard/` produced
`http://homeassistant.local:18099/api/hassio_ingress/<token>/sabnzbd/wizard/`
— nginx expands a scheme-less replacement using the browser's Host and its own
listen port, which is the add-on's internal ingress port and is not reachable
from the browser. `absolute_redirect off` keeps it a path, which the browser
resolves against the Home Assistant origin.
`proxy_cookie_path` comes from Codex's review of the diff. SABnzbd hardcodes
the login cookie to `Path=/` (`interface.py:316`), so on the shared ingress
origin the browser would send it to every other add-on's ingress path as well.
Verified end to end by running the shipped nginx.conf and ingress.conf against
the live add-on, with the browser Host set to a non-IP hostname throughout:
all five redirect cases return a path under the ingress entry, the config
pages, wizard, API and both static roots return 200, and a stub upstream
emitting `Path=/` comes back rewritten to the ingress path.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(sabnzbd): drop webui, which the add-on linter forbids alongside ingress
frenck/action-addon-linter fails the PR with "'webui' should be removed,
Ingress is enabled." No other ingress add-on in this repo keeps the key. The
"Open Web UI" button now opens ingress; the ports mapping is untouched, so
direct ip:port still works, it just has to be typed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(sabnzbd): make the nginx finish script actually work on s6-overlay v3
CodeRabbit is right that the execline finish script copied from nzbget is
inert on this image. s6-portable-utils dropped `s6-test` in favour of
execline's `eltest` — s6-overlay 3.2.1.0 ships no `s6-test` at all — so
execlineb cannot run the first `if` block and never reaches s6-svscanctl.
`/var/run/s6/services` is also the v2 scandir path; v3's legacy services.d
compatibility layer uses /run/service.
Rather than port it to eltest, use the shell form the scrutiny add-on already
ships: `kill -15 1` signals s6-overlay's init directly, so it depends on
neither the s6 tool set nor the scandir path, and it is three lines shorter.
The 0 and 256 exclusions are kept, so a normal shutdown does not trigger it.
Also fix the CHANGELOG date to YYYY-MM-DD per Copilot: that is what this file
and 7705 of the repo's 8068 dated headings use.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
|
||||
## 5.1.1.2 (2026-08-25)
|
||||
- Ingress is now enabled: the WebUI opens directly in the Home Assistant sidebar, and the "Open Web UI" button now goes there. Access by ip:port is unchanged, but has to be typed rather than clicked, as Home Assistant does not allow an add-on to offer both.
|
||||
- Note for users who set a "Host verification" whitelist in SABnzbd: ingress sends `Host: 127.0.0.1:8080` upstream, because SABnzbd rejects any Host that is not an IP literal. That whitelist therefore no longer filters the ingress route, which is gated by Home Assistant authentication instead. Direct ip:port access is unchanged and still filtered.
|
||||
|
||||
## 5.1.1 (2026-08-22)
|
||||
- Update to latest version from linuxserver/docker-sabnzbd (changelog : https://github.com/linuxserver/docker-sabnzbd/releases)
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ environment:
|
||||
PGID: "0"
|
||||
PUID: "0"
|
||||
image: ghcr.io/alexbelgium/sabnzbd-{arch}
|
||||
ingress_entry: sabnzbd
|
||||
ingress: true
|
||||
init: false
|
||||
map:
|
||||
- addon_config:rw
|
||||
@@ -106,5 +106,4 @@ schema:
|
||||
slug: sabnzbd
|
||||
udev: true
|
||||
url: https://github.com/alexbelgium/hassio-addons
|
||||
version: "5.1.1"
|
||||
webui: http://[HOST]:[PORT:8080]
|
||||
version: "5.1.1.2"
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# shellcheck shell=bash
|
||||
# shellcheck disable=SC2317
|
||||
set -e
|
||||
|
||||
#################
|
||||
# NGINX SETTING #
|
||||
#################
|
||||
|
||||
exit 0
|
||||
|
||||
ingress_port=$(bashio::addon.ingress_port)
|
||||
ingress_interface=$(bashio::addon.ip_address)
|
||||
ingress_entry=$(bashio::addon.ingress_entry)
|
||||
sed -i "s/%%port%%/${ingress_port}/g" /etc/nginx/servers/ingress.conf
|
||||
sed -i "s/%%interface%%/${ingress_interface}/g" /etc/nginx/servers/ingress.conf
|
||||
|
||||
# Allows serving js
|
||||
sed -i 's/<!-- %if-not-debug% -->/<!-- %if-not-debug% /g' /app/sabnzbd/webui/index.html
|
||||
sed -i 's/<!-- %end% -->/ %end% -->/g' /app/sabnzbd/webui/index.html
|
||||
sed -i 's/<!-- %if-debug%/<!-- %if-debug% -->/g' /app/sabnzbd/webui/index.html
|
||||
sed -i 's/ %end% -->/<!-- %end% -->/g' /app/sabnzbd/webui/index.html
|
||||
sed -i "s|%%ingress_entry%%|${ingress_entry}|g" /etc/nginx/servers/ingress.conf
|
||||
|
||||
@@ -2,22 +2,34 @@ server {
|
||||
listen %%interface%%:%%port%% default_server;
|
||||
|
||||
include /etc/nginx/includes/server_params.conf;
|
||||
include /etc/nginx/includes/proxy_params.conf;
|
||||
|
||||
client_max_body_size 0;
|
||||
|
||||
location / {
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
proxy_connect_timeout 30m;
|
||||
proxy_send_timeout 30m;
|
||||
proxy_read_timeout 30m;
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
# Correct url without port when using https
|
||||
sub_filter_once off;
|
||||
sub_filter_types *;
|
||||
sub_filter /sabnzbd %%ingress_entry%%/sabnzbd;
|
||||
}
|
||||
# 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. X-Forwarded-For is
|
||||
# the only other header it reads (for its verify_xff_header option).
|
||||
proxy_set_header Host $proxy_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_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;
|
||||
}
|
||||
}
|
||||
|
||||
9
sabnzbd/rootfs/etc/services.d/nginx/finish
Executable file
9
sabnzbd/rootfs/etc/services.d/nginx/finish
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# shellcheck shell=bash
|
||||
# ==============================================================================
|
||||
# Stop the container when Nginx fails, so ingress does not silently go dead
|
||||
# ==============================================================================
|
||||
if [[ "$1" -ne 0 && "$1" -ne 256 ]]; then
|
||||
bashio::log.error "Nginx exited with code $1"
|
||||
kill -15 1
|
||||
fi
|
||||
11
sabnzbd/rootfs/etc/services.d/nginx/run
Executable file
11
sabnzbd/rootfs/etc/services.d/nginx/run
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# shellcheck shell=bash
|
||||
set -e
|
||||
# ==============================================================================
|
||||
|
||||
# Wait for sabnzbd to become available
|
||||
bashio::net.wait_for 8080 localhost 900
|
||||
|
||||
bashio::log.info "Starting NGinx..."
|
||||
|
||||
exec nginx
|
||||
Reference in New Issue
Block a user