Both :8001 (FastAPI control API) and :8081 (OP25's HTTP terminal) listened on 0.0.0.0 with no authentication, on a container that is privileged with /dev mounted and network_mode: host. Nodes get deployed to third-party sites, so that exposed start/stop/retune to anyone on the host's LAN. All three containers share the host network namespace, so edge-node still reaches both over 127.0.0.1 unchanged. OP25_DEBUG_EXPOSE=true restores the old 0.0.0.0 binding and logs a loud warning; it is off by default. Confirmed against boatbod/op25 gr310 that the terminal's http:<host>:<port> string is honoured as a real bind address (http_server.py splits it and hands the host to create_server), so no flag was invented. Also reorder models.py so IcecastConfig precedes ConfigGenerator, which annotates a field with it. That only worked because python:slim-trixie is currently Python 3.14, where PEP 649 defers annotation evaluation; on 3.13 or earlier the same file is a hard NameError at import. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
34 lines
1.3 KiB
Python
34 lines
1.3 KiB
Python
from pydantic_settings import BaseSettings
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# ------------------------------------------------------------------
|
|
# OP25_DEBUG_EXPOSE — debugging aid, NOT a deployment mode.
|
|
#
|
|
# False (default): the op25 FastAPI control API (:8001, start/stop/
|
|
# generate-config) and OP25's own HTTP terminal (:8081, live talkgroup
|
|
# metadata) both bind 127.0.0.1. All three Client containers share the
|
|
# host network namespace (network_mode: host), so edge-node still reaches
|
|
# both over localhost with no functional change — nothing off-box can.
|
|
# Neither surface has authentication, so this is the only thing closing
|
|
# that hole.
|
|
#
|
|
# True: both bind 0.0.0.0 — reachable by anything on the node's LAN with
|
|
# NO authentication (start/stop OP25, rewrite its config, raw terminal
|
|
# access). Only ever set this for local development off a real deployed
|
|
# node. A loud warning naming both ports is logged at startup whenever
|
|
# this is true.
|
|
# ------------------------------------------------------------------
|
|
op25_debug_expose: bool = False
|
|
|
|
class Config:
|
|
env_file = ".env"
|
|
|
|
|
|
settings = Settings()
|
|
|
|
|
|
def bind_host() -> str:
|
|
"""Resolve the single bind address for both :8001 and :8081 from the flag."""
|
|
return "0.0.0.0" if settings.op25_debug_expose else "127.0.0.1"
|