fix(packaging): open mgmt/library port 47990 on the LAN firewall profiles
apple / swift (push) Successful in 1m11s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
decky / build-publish (push) Has been cancelled
deb / build-publish (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / web (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
android / android (push) Successful in 3m49s
apple / screenshots (push) Has been cancelled
arch / build-publish (push) Has been cancelled

The mgmt REST API has bound 0.0.0.0:47990 by default since ae51276 so paired
clients can browse the game library over mTLS, but every packaged firewall
opener still excluded 47990 and the docs still claimed it was loopback-only.
On any host with an active firewall (ufw/firewalld) the LAN game-library
feature was silently broken.

Add 47990/tcp to the native firewall profiles (punktfunk.ufw [punktfunk-native]
+ punktfunk-native.xml) and correct the stale "loopback-only by default" text
across the debian/arch/bazzite READMEs and the docs site (incl. the factually
wrong --mgmt-bind default in host-cli.md, 127.0.0.1 -> 0.0.0.0). Opening the
port adds no admin exposure: off-loopback mgmt::require_auth serves only the
read-only status/library allowlist to a paired client cert; the bearer-token
admin surface stays loopback-only regardless of the bind.

Windows was already sound (shared parse_serve binds 0.0.0.0; service.rs already
firewall-opens 47990) — add a clarifying comment so the rule isn't mistaken for
accidental over-exposure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 12:38:57 +00:00
parent 7effdb4030
commit 1dc8dc7f0d
12 changed files with 79 additions and 35 deletions
+2 -1
View File
@@ -10,7 +10,8 @@
(punktfunk.ufw). Exact commands: your distro's install guide, or the per-distro packaging README.
Needed only when the host runs GameStream/Moonlight compat (serve with the gamestream flag). The
mgmt REST API (TCP 47990) stays on loopback by default and is deliberately not opened here.
mgmt REST API (TCP 47990) is opened by the punktfunk-native profile (not here) so paired clients can
browse the game library over mTLS; off-loopback it exposes only read-only status/library endpoints.
Port map: design/gamestream-host-plan.md.
-->
<service>
+9 -1
View File
@@ -13,10 +13,18 @@
The media DATA plane binds an EPHEMERAL UDP port (0.0.0.0:0) chosen per session and reported to the
client, so there is no fixed data port to open. On a restrictive firewall you must also allow the
ephemeral UDP range (the project does not pin one).
The mgmt REST API (TCP 47990, HTTPS + mTLS) is opened here because `serve` binds it to all interfaces
by default so paired clients can browse the game library over the LAN. Off-loopback it exposes ONLY
the read-only status + library endpoints, and only to a paired client certificate; every admin /
state-changing action (arming pairing, removing devices, session control, library edits) is honored
over loopback only. To keep 47990 loopback-only, bind the mgmt API to 127.0.0.1:47990 (the host's
`mgmt-bind` option).
-->
<service>
<short>Punktfunk (native punktfunk/1)</short>
<description>Low-latency game-streaming host over the native punktfunk/1 protocol (QUIC control plane). Opens the default QUIC control port plus mDNS for auto-discovery. The media data plane uses an ephemeral UDP port negotiated per session, not opened here.</description>
<description>Low-latency game-streaming host over the native punktfunk/1 protocol (QUIC control plane). Opens the default QUIC control port plus mDNS for auto-discovery, and the mgmt/library REST API (HTTPS + mTLS; off-loopback it serves only read-only status/library to paired clients). The media data plane uses an ephemeral UDP port negotiated per session, not opened here.</description>
<port protocol="udp" port="9777"/> <!-- QUIC control plane (default 9777) -->
<port protocol="udp" port="5353"/> <!-- mDNS auto-discovery (_punktfunk._udp.local) -->
<port protocol="tcp" port="47990"/> <!-- mgmt/library REST API (HTTPS + mTLS; LAN = read-only, paired) -->
</service>
+3 -2
View File
@@ -10,8 +10,9 @@
firewall-cmd (add-service=punktfunk-web, then reload). CachyOS/Ubuntu: use the ufw punktfunk-web
profile instead.
The mgmt REST API (TCP 47990) is a different, loopback-only surface (the console proxies to it
locally) and is deliberately NOT opened here.
The mgmt REST API (TCP 47990) is a different surface the console proxies to it over loopback, and
it is opened for paired clients by the punktfunk-native profile (not here). Off-loopback the mgmt API
serves only read-only status/library to a paired client cert; its admin surface stays loopback-only.
-->
<service>
<short>Punktfunk web console</short>
+8 -3
View File
@@ -21,17 +21,22 @@
[punktfunk-native]
title=punktfunk host (native punktfunk/1)
description=punktfunk/1 native streaming: QUIC control plane + mDNS auto-discovery
ports=9777/udp|5353/udp
description=punktfunk/1 native streaming: QUIC control plane + mDNS auto-discovery + mgmt/library API (HTTPS + mTLS)
ports=9777/udp|5353/udp|47990/tcp
[punktfunk-gamestream]
title=punktfunk host (GameStream/Moonlight)
description=GameStream/Moonlight compatibility ports (opt-in, trusted LAN only)
ports=47984,47989,48010/tcp|47998:48010/udp|5353/udp
# The mgmt REST API (TCP 47990, in the punktfunk-native profile above) binds all interfaces by
# default so paired clients can browse the game library over mTLS. Off-loopback it exposes ONLY the
# read-only status + library endpoints, and only to a paired client certificate; every admin action
# (arming pairing, removing devices, session control, library edits) is honored over loopback only.
# Run the host with `--mgmt-bind 127.0.0.1:47990` to keep 47990 loopback-only (then don't open it).
#
# The optional web console (the separate punktfunk-web package). Open only if you installed it and
# want to reach it from another device — it binds all interfaces on TCP 47992 (HTTPS, login-gated).
# The mgmt API (47990) is loopback-only and is deliberately not covered here.
[punktfunk-web]
title=punktfunk web console
description=The optional punktfunk management web console (HTTPS, login-gated) reachable from the LAN