Require a password on go2rtc's API

The API listener is what serves WebRTC, and it defaults to :1984 on every
interface, so anyone who could reach the gateway could watch any printer
with a camera. The RTSP server was closed on 2026-10-18; this was the
other half and the one that actually carries video.

Measured against go2rtc 1.9.14, feeding it this module's own rendered
config: from a non-loopback address /api/webrtc, /api/ws, /api/streams
and the web UI all answer 401 without credentials and 200 with them,
while :8554 stays closed. go2rtc exempts loopback, which is worth
knowing twice - it is why a probe from the gateway still works without
credentials, and why such a probe cannot be used to confirm auth is on.

The password is generated once per run from /dev/urandom, or taken from
CONTINUUM_GO2RTC_PASSWORD. Once per run matters: the config is
re-rendered every 30s and compared byte-for-byte to decide whether to
restart go2rtc, so a per-render credential would restart it and drop
every viewer every half minute, with no symptom but dying video. A test
pins that.

It is never logged - it goes into the config file, which already holds
every printer's access code and is already documented as a secret, so
there is one place to protect rather than two. An operator-supplied
password is escaped for YAML, because a config go2rtc cannot parse means
a camera that silently never appears.

No opt-out flag. The alternative is an unauthenticated video feed of
someone's workshop, which is not a thing to leave behind a setting, and
nothing in this crate calls go2rtc's API so nothing internal breaks.

Note this does NOT let a browser play a stream directly - see the next
commit's notes and PLAN.md. go2rtc sends no CORS headers and 401s the
unauthenticated preflight, so the relay is required, not optional.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 22:00:51 +00:00
co-authored by Claude Opus 5
parent 0f57717378
commit 005b8a3337
3 changed files with 176 additions and 7 deletions
+10
View File
@@ -16,6 +16,16 @@ CONTINUUM_GO2RTC_BIN=/usr/local/bin/go2rtc
CONTINUUM_GO2RTC_CONFIG=./go2rtc.yaml
CONTINUUM_GO2RTC_API_LISTEN=:1984
# The go2rtc API serves WebRTC, and the listen address above is every
# interface, so it is always password-protected: leave this unset and the
# daemon generates a random password each run and writes it into the config
# file above, which is already a secret. Set it only if you need a stable one
# (to open go2rtc's own web UI, say). The username is always "continuum".
#
# go2rtc exempts loopback from this, so a check from the gateway itself always
# succeeds - test from another machine if you want to confirm it is on.
# CONTINUUM_GO2RTC_PASSWORD=
# What a browser can reach the streams at, reported to the cloud. A bind
# address is not one, which is why this is separate from the listen address
# above; only you know this gateway's reachable name. Note this is a LAN