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
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:
@@ -890,11 +890,16 @@ pub(crate) fn allow_public_network(args: &[String]) -> bool {
|
|||||||
args.iter().any(|a| a == "--allow-public-network")
|
args.iter().any(|a| a == "--allow-public-network")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inbound firewall rules for the streaming ports (best-effort; logs but never fails the install).
|
/// Inbound firewall rules for the streaming + mgmt ports (best-effort; logs but never fails the
|
||||||
/// Scoped by [`firewall_profile_arg`]: Domain + Private by default, all profiles when `allow_public`.
|
/// install). Scoped by [`firewall_profile_arg`]: Domain + Private by default, all profiles when
|
||||||
|
/// `allow_public`. TCP 47990 is deliberate: `serve` binds the mgmt/library REST API to all interfaces
|
||||||
|
/// so paired clients can browse the game library over mTLS, and off-loopback `mgmt::require_auth`
|
||||||
|
/// exposes only the read-only status/library allowlist to a paired client cert — the bearer-token
|
||||||
|
/// admin surface stays loopback-only regardless of the bind — so opening it adds no admin exposure.
|
||||||
fn add_firewall_rules(allow_public: bool) {
|
fn add_firewall_rules(allow_public: bool) {
|
||||||
let profile = firewall_profile_arg(allow_public);
|
let profile = firewall_profile_arg(allow_public);
|
||||||
// (name suffix, protocol, ports)
|
// (name suffix, protocol, ports). 47990 = mgmt/library (LAN = read-only, paired-cert only); the
|
||||||
|
// rest are the GameStream (47984/47989/48010, 47998-48010) + native (9777) + mDNS (5353) ports.
|
||||||
let rules = [
|
let rules = [
|
||||||
("TCP", "TCP", "47984,47989,48010,47990"),
|
("TCP", "TCP", "47984,47989,48010,47990"),
|
||||||
("UDP", "UDP", "47998-48010,9777,5353"),
|
("UDP", "UDP", "47998-48010,9777,5353"),
|
||||||
|
|||||||
@@ -128,8 +128,9 @@ sudo ufw allow punktfunk-web
|
|||||||
sudo firewall-cmd --permanent --add-service=punktfunk-web && sudo firewall-cmd --reload # firewalld
|
sudo firewall-cmd --permanent --add-service=punktfunk-web && sudo firewall-cmd --reload # firewalld
|
||||||
```
|
```
|
||||||
|
|
||||||
That opens **TCP 47992** (HTTPS, login-gated). The mgmt API (47990) stays loopback-only and is never
|
That opens **TCP 47992** (HTTPS, login-gated). The mgmt API (47990) is opened for paired clients by the
|
||||||
opened. Full port lists (`nftables`, explicit ports) are in
|
`punktfunk-native` profile (game-library browsing over mTLS); off-loopback it serves only read-only
|
||||||
|
status/library, and every admin action stays loopback-only. Full port lists (`nftables`, explicit ports) are in
|
||||||
[`packaging/arch/README.md`](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/arch/README.md#firewall).
|
[`packaging/arch/README.md`](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/arch/README.md#firewall).
|
||||||
|
|
||||||
## 6. Connect a client
|
## 6. Connect a client
|
||||||
|
|||||||
@@ -32,15 +32,19 @@ punktfunk-host serve --gamestream
|
|||||||
| `--native` | No-op. The native `punktfunk/1` server always runs in `serve`; kept only for backward compatibility. |
|
| `--native` | No-op. The native `punktfunk/1` server always runs in `serve`; kept only for backward compatibility. |
|
||||||
| `--native-port <PORT>` | Native QUIC port (default `9777`). |
|
| `--native-port <PORT>` | Native QUIC port (default `9777`). |
|
||||||
| `--open` | Don't require pairing — serve any device on the network. Off by default; only for trusted single-user setups. |
|
| `--open` | Don't require pairing — serve any device on the network. Off by default; only for trusted single-user setups. |
|
||||||
| `--mgmt-bind <IP:PORT>` | Management API address (default loopback `127.0.0.1:47990`). |
|
| `--mgmt-bind <IP:PORT>` | Management API address (default `0.0.0.0:47990` — all interfaces, so paired clients can browse the game library over mTLS; pass `127.0.0.1:47990` to keep it loopback-only). |
|
||||||
| `--mgmt-token <TOKEN>` | Override the bearer token for the management API. |
|
| `--mgmt-token <TOKEN>` | Override the bearer token for the management API. |
|
||||||
|
|
||||||
These are the only flags `serve` accepts.
|
These are the only flags `serve` accepts.
|
||||||
|
|
||||||
The management API is **always HTTPS with bearer-token auth**. If you don't pass `--mgmt-token`, a token
|
The management API is **always HTTPS**. It binds all interfaces by default so a **paired client** can
|
||||||
is auto-generated and persisted to `~/.config/punktfunk/mgmt-token`; `--mgmt-token` only overrides it. A
|
fetch the game library over its mTLS certificate — but off loopback that certificate reaches only the
|
||||||
token is **required** when you bind the API off loopback with `--mgmt-bind`. Every endpoint is documented
|
read-only status + library endpoints. The **admin surface** (arming pairing, removing devices, session
|
||||||
in the interactive [**API Reference**](/api).
|
control, library edits) authenticates with a **bearer token** and is honored **from loopback only**, so
|
||||||
|
it is never LAN-exposed even under the default wide bind. If you don't pass `--mgmt-token`, a token is
|
||||||
|
auto-generated and persisted to `~/.config/punktfunk/mgmt-token` (the bundled web console reads the same
|
||||||
|
file); `--mgmt-token` only overrides it. Pass `--mgmt-bind 127.0.0.1:47990` to keep 47990 loopback-only.
|
||||||
|
Every endpoint is documented in the interactive [**API Reference**](/api).
|
||||||
|
|
||||||
By default the host **requires pairing** — see [Pairing & Trust](/docs/pairing). On `serve` you
|
By default the host **requires pairing** — see [Pairing & Trust](/docs/pairing). On `serve` you
|
||||||
**arm pairing from the web console** (or mgmt API); the host then displays a 4-digit PIN. Pass `--open` to
|
**arm pairing from the web console** (or mgmt API); the host then displays a 4-digit PIN. Pass `--open` to
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ description: Enable the punktfunk browser console, read or change its login pass
|
|||||||
|
|
||||||
The web console is the browser UI for a punktfunk host — live status, paired devices, and the PIN
|
The web console is the browser UI for a punktfunk host — live status, paired devices, and the PIN
|
||||||
pairing flow. It ships as the **`punktfunk-web`** systemd user unit on Linux and the **`PunktfunkWeb`**
|
pairing flow. It ships as the **`punktfunk-web`** systemd user unit on Linux and the **`PunktfunkWeb`**
|
||||||
task on Windows, and serves on **`http://<host-ip>:47992`**. The host's own management API stays
|
task on Windows, and serves on **`http://<host-ip>:47992`**. It's the surface you expose on the LAN to
|
||||||
loopback-only behind it, so the console is the one surface you expose on the LAN.
|
administer the host; the host's own management API (47990) keeps every admin action loopback-only and
|
||||||
|
off-loopback serves only read-only status + game-library browsing to paired clients.
|
||||||
|
|
||||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ only by Administrators and SYSTEM. To read or change it (with the `schtasks` res
|
|||||||
|
|
||||||
The host **requires PIN pairing** by default (secure on a LAN). To connect the first time, open the
|
The host **requires PIN pairing** by default (secure on a LAN). To connect the first time, open the
|
||||||
console from any browser on the LAN, log in, go to **Devices → [arm pairing](/docs/web-console#arm-pairing)**,
|
console from any browser on the LAN, log in, go to **Devices → [arm pairing](/docs/web-console#arm-pairing)**,
|
||||||
and enter the PIN on your [client](/docs/clients). The host's own management API stays loopback-only behind the console.
|
and enter the PIN on your [client](/docs/clients). The host's own management API keeps every admin action loopback-only; off-loopback it serves only read-only status and game-library browsing to paired clients.
|
||||||
|
|
||||||
### Configure
|
### Configure
|
||||||
|
|
||||||
|
|||||||
@@ -160,17 +160,20 @@ sudo firewall-cmd --reload
|
|||||||
```
|
```
|
||||||
|
|
||||||
`punktfunk-gamestream` opens the fixed Moonlight ports + mDNS; `punktfunk-native` opens the QUIC
|
`punktfunk-gamestream` opens the fixed Moonlight ports + mDNS; `punktfunk-native` opens the QUIC
|
||||||
control port (UDP 9777) + mDNS. Enable both if the host runs `serve --gamestream` (which serves
|
control port (UDP 9777) + mDNS + the mgmt/library API (TCP 47990, HTTPS + mTLS). Enable both if the
|
||||||
both planes). The **data plane is an *ephemeral* UDP port** the client opens with a hole-punch, so
|
host runs `serve --gamestream` (which serves both planes). The **data plane is an *ephemeral* UDP port** the client opens with a hole-punch, so
|
||||||
there is no fixed data port in either service — the host streams back out through the path the
|
there is no fixed data port in either service — the host streams back out through the path the
|
||||||
client opened, which any firewall that allows outbound UDP (the default) passes. The mgmt REST API
|
client opened, which any firewall that allows outbound UDP (the default) passes. The mgmt REST API
|
||||||
(TCP 47990) binds to loopback by default — leave it closed unless you move it off loopback with
|
(TCP 47990, HTTPS + mTLS) binds all interfaces by default so paired clients can browse the game library
|
||||||
`--mgmt-bind IP:PORT` (which then requires `--mgmt-token`).
|
— the `punktfunk-native` profile opens it. Off-loopback it serves only read-only status/library to a
|
||||||
|
paired client cert and keeps the admin surface loopback-only (`--mgmt-bind 127.0.0.1:47990` to opt out).
|
||||||
|
|
||||||
If you installed the **web console** (`punktfunk-web`) and want it reachable from another device,
|
If you installed the **web console** (`punktfunk-web`) and want it reachable from another device,
|
||||||
open its port with the matching one-liner — `sudo ufw allow punktfunk-web` or `sudo firewall-cmd
|
open its port with the matching one-liner — `sudo ufw allow punktfunk-web` or `sudo firewall-cmd
|
||||||
--permanent --add-service=punktfunk-web && sudo firewall-cmd --reload` — which opens **TCP 47992**
|
--permanent --add-service=punktfunk-web && sudo firewall-cmd --reload` — which opens **TCP 47992**
|
||||||
(HTTPS, login-gated). The mgmt API (47990) stays loopback-only.
|
(HTTPS, login-gated). The mgmt API (47990) is opened for paired clients by the `punktfunk-native`
|
||||||
|
profile (game-library browsing over mTLS); off-loopback it serves only read-only status/library and
|
||||||
|
keeps admin loopback-only.
|
||||||
|
|
||||||
Prefer explicit rules (or a firewall the shipped profiles don't cover)? Open the ports directly.
|
Prefer explicit rules (or a firewall the shipped profiles don't cover)? Open the ports directly.
|
||||||
The **native `punktfunk/1`** plane:
|
The **native `punktfunk/1`** plane:
|
||||||
@@ -198,13 +201,16 @@ And the **GameStream / Moonlight** ports (fixed) — only needed if you run the
|
|||||||
| 47998–48010 | UDP | Video RTP (+ FEC), ENet control (47999), audio (48000) |
|
| 47998–48010 | UDP | Video RTP (+ FEC), ENet control (47999), audio (48000) |
|
||||||
| 5353 | UDP | mDNS auto-discovery |
|
| 5353 | UDP | mDNS auto-discovery |
|
||||||
|
|
||||||
The mgmt API (TCP 47990) binds to loopback by default — leave it closed unless you move it off
|
The mgmt API (TCP 47990, HTTPS + mTLS) binds all interfaces by default so paired clients can browse the
|
||||||
loopback with `--mgmt-bind IP:PORT` (which then requires `--mgmt-token`).
|
game library — the `punktfunk-native` profile opens it. Off-loopback it serves only read-only
|
||||||
|
status/library to a paired client cert; the admin surface stays loopback-only. Pass
|
||||||
|
`--mgmt-bind 127.0.0.1:47990` to keep it loopback-only (then leave 47990 closed).
|
||||||
|
|
||||||
With `ufw` (explicit ports, instead of the shipped `punktfunk-native`/`punktfunk-gamestream` profile):
|
With `ufw` (explicit ports, instead of the shipped `punktfunk-native`/`punktfunk-gamestream` profile):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo ufw allow 9777/udp # punktfunk/1 control plane
|
sudo ufw allow 9777/udp # punktfunk/1 control plane
|
||||||
|
sudo ufw allow 47990/tcp # mgmt/library API (HTTPS + mTLS; LAN = read-only, paired)
|
||||||
sudo ufw allow 47984/tcp && sudo ufw allow 47989/tcp && sudo ufw allow 48010/tcp
|
sudo ufw allow 47984/tcp && sudo ufw allow 47989/tcp && sudo ufw allow 48010/tcp
|
||||||
sudo ufw allow 47998,47999,48000/udp # GameStream video/control/audio
|
sudo ufw allow 47998,47999,48000/udp # GameStream video/control/audio
|
||||||
sudo ufw allow 5353/udp # mDNS discovery
|
sudo ufw allow 5353/udp # mDNS discovery
|
||||||
@@ -217,6 +223,7 @@ With raw `nftables` (add to your `inet filter input` chain):
|
|||||||
|
|
||||||
```
|
```
|
||||||
udp dport 9777 accept # punktfunk/1 control plane
|
udp dport 9777 accept # punktfunk/1 control plane
|
||||||
|
tcp dport 47990 accept # mgmt/library API (HTTPS + mTLS; LAN = read-only, paired)
|
||||||
tcp dport { 47984, 47989, 48010 } accept
|
tcp dport { 47984, 47989, 48010 } accept
|
||||||
udp dport { 47998-48000, 5353 } accept # GameStream video/control/audio + mDNS
|
udp dport { 47998-48000, 5353 } accept # GameStream video/control/audio + mDNS
|
||||||
# The punktfunk/1 data plane is a random UDP port — normally left closed (hole-punch + ~2.5s
|
# The punktfunk/1 data plane is a random UDP port — normally left closed (hole-punch + ~2.5s
|
||||||
|
|||||||
@@ -335,7 +335,8 @@ sudo firewall-cmd --reload
|
|||||||
```
|
```
|
||||||
|
|
||||||
`punktfunk-gamestream` opens the fixed Moonlight ports + mDNS; `punktfunk-native` opens the QUIC
|
`punktfunk-gamestream` opens the fixed Moonlight ports + mDNS; `punktfunk-native` opens the QUIC
|
||||||
control port (UDP 9777) + mDNS. Enable both if the host runs `serve --gamestream` (both planes). The
|
control port (UDP 9777) + mDNS + the mgmt/library API (TCP 47990, HTTPS + mTLS). Enable both if the
|
||||||
|
host runs `serve --gamestream` (both planes). The
|
||||||
per-port breakdown below is for reference (or for opening ports by hand); the ports are the code
|
per-port breakdown below is for reference (or for opening ports by hand); the ports are the code
|
||||||
constants (`crates/punktfunk-host/src/gamestream/mod.rs`, `mgmt.rs`) and the GameStream-host port-map
|
constants (`crates/punktfunk-host/src/gamestream/mod.rs`, `mgmt.rs`) and the GameStream-host port-map
|
||||||
(`design/gamestream-host-plan.md`).
|
(`design/gamestream-host-plan.md`).
|
||||||
@@ -354,9 +355,11 @@ host you don't open them:
|
|||||||
| 48000 | UDP | Audio (Opus) |
|
| 48000 | UDP | Audio (Opus) |
|
||||||
| 5353 | UDP | mDNS — so Moonlight auto-discovers the host (`_nvstream._tcp.local.`) |
|
| 5353 | UDP | mDNS — so Moonlight auto-discovers the host (`_nvstream._tcp.local.`) |
|
||||||
|
|
||||||
**Management REST API:** **TCP 47990** — but `serve` **binds it to `127.0.0.1` (loopback) by
|
**Management REST API:** **TCP 47990** (HTTPS + mTLS) — `serve` **binds it to all interfaces by
|
||||||
default**, so you do **not** open it in the firewall unless you deliberately move it off loopback
|
default** so paired clients can browse the game library over the LAN; the `punktfunk-native` profile
|
||||||
with `--mgmt-bind IP:PORT` (which also requires `--mgmt-token`). Leave it closed for a normal setup.
|
(above) opens it, or open it by hand with `firewall-cmd --add-port=47990/tcp`. Off-loopback it serves
|
||||||
|
only read-only status/library to a paired client cert; every admin action stays loopback-only. Pass
|
||||||
|
`--mgmt-bind 127.0.0.1:47990` to keep it loopback-only instead.
|
||||||
|
|
||||||
To open the GameStream ports by hand instead of the service (equivalent):
|
To open the GameStream ports by hand instead of the service (equivalent):
|
||||||
|
|
||||||
@@ -508,4 +511,6 @@ matching your Bazzite Fedora base (`rpm -E %fedora`).
|
|||||||
3. The bundled systemd unit runs `serve --gamestream` — the native `punktfunk/1` QUIC plane (always
|
3. The bundled systemd unit runs `serve --gamestream` — the native `punktfunk/1` QUIC plane (always
|
||||||
on) **plus** the GameStream/Moonlight planes. Drop `--gamestream` for a secure native-only host;
|
on) **plus** the GameStream/Moonlight planes. Drop `--gamestream` for a secure native-only host;
|
||||||
`punktfunk1-host` is a separate standalone native host, unmanaged by the unit.
|
`punktfunk1-host` is a separate standalone native host, unmanaged by the unit.
|
||||||
4. The mgmt port (47990) is **loopback-only by default** — don't open it.
|
4. The mgmt port (47990) **binds all interfaces by default** and is opened for paired clients by the
|
||||||
|
`punktfunk-native` profile (game-library browsing over mTLS); off-loopback it serves only read-only
|
||||||
|
status/library and keeps admin loopback-only. `--mgmt-bind 127.0.0.1:47990` restores loopback-only.
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ sudo firewall-cmd --reload
|
|||||||
If you installed the **web console** (`punktfunk-web`) and want it reachable from another device,
|
If you installed the **web console** (`punktfunk-web`) and want it reachable from another device,
|
||||||
open its port with the matching one-liner — `sudo ufw allow punktfunk-web` or `sudo firewall-cmd
|
open its port with the matching one-liner — `sudo ufw allow punktfunk-web` or `sudo firewall-cmd
|
||||||
--permanent --add-service=punktfunk-web && sudo firewall-cmd --reload` — which opens **TCP 47992**
|
--permanent --add-service=punktfunk-web && sudo firewall-cmd --reload` — which opens **TCP 47992**
|
||||||
(HTTPS, login-gated). The mgmt API (47990) stays loopback-only.
|
(HTTPS, login-gated). The mgmt API (47990) is opened for paired clients by the `punktfunk-native`
|
||||||
|
profile (game-library browsing over mTLS); off-loopback it serves only read-only status/library and
|
||||||
|
keeps admin loopback-only.
|
||||||
|
|
||||||
Prefer explicit rules? Open the ports directly. The **native `punktfunk/1`** plane:
|
Prefer explicit rules? Open the ports directly. The **native `punktfunk/1`** plane:
|
||||||
|
|
||||||
@@ -98,13 +100,16 @@ And the **GameStream / Moonlight** ports (fixed) — only needed if you run the
|
|||||||
| 47998–48010 | UDP | Video RTP (+ FEC), ENet control (47999), audio (48000) |
|
| 47998–48010 | UDP | Video RTP (+ FEC), ENet control (47999), audio (48000) |
|
||||||
| 5353 | UDP | mDNS auto-discovery |
|
| 5353 | UDP | mDNS auto-discovery |
|
||||||
|
|
||||||
The mgmt API (TCP 47990) binds to loopback by default — leave it closed unless you move it off
|
The mgmt API (TCP 47990, HTTPS + mTLS) binds all interfaces by default so paired clients can browse the
|
||||||
loopback with `--mgmt-bind IP:PORT` (which then requires `--mgmt-token`).
|
game library — the `punktfunk-native` profile opens it. Off-loopback it serves only read-only
|
||||||
|
status/library to a paired client cert; the admin surface stays loopback-only. Pass
|
||||||
|
`--mgmt-bind 127.0.0.1:47990` to keep it loopback-only (then leave 47990 closed).
|
||||||
|
|
||||||
With `ufw` (explicit ports, instead of the shipped profile):
|
With `ufw` (explicit ports, instead of the shipped profile):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo ufw allow 9777/udp # punktfunk/1 control plane
|
sudo ufw allow 9777/udp # punktfunk/1 control plane
|
||||||
|
sudo ufw allow 47990/tcp # mgmt/library API (HTTPS + mTLS; LAN = read-only, paired)
|
||||||
sudo ufw allow 47984/tcp && sudo ufw allow 47989/tcp && sudo ufw allow 48010/tcp
|
sudo ufw allow 47984/tcp && sudo ufw allow 47989/tcp && sudo ufw allow 48010/tcp
|
||||||
sudo ufw allow 47998,47999,48000/udp # GameStream video/control/audio
|
sudo ufw allow 47998,47999,48000/udp # GameStream video/control/audio
|
||||||
sudo ufw allow 5353/udp # mDNS discovery
|
sudo ufw allow 5353/udp # mDNS discovery
|
||||||
@@ -117,6 +122,7 @@ With raw `nftables` (add to your `inet filter input` chain):
|
|||||||
|
|
||||||
```
|
```
|
||||||
udp dport 9777 accept # punktfunk/1 control plane
|
udp dport 9777 accept # punktfunk/1 control plane
|
||||||
|
tcp dport 47990 accept # mgmt/library API (HTTPS + mTLS; LAN = read-only, paired)
|
||||||
tcp dport { 47984, 47989, 48010 } accept
|
tcp dport { 47984, 47989, 48010 } accept
|
||||||
udp dport { 47998-48010, 5353 } accept
|
udp dport { 47998-48010, 5353 } accept
|
||||||
# The punktfunk/1 data plane is a random UDP port — normally left closed (hole-punch + ~2.5s
|
# The punktfunk/1 data plane is a random UDP port — normally left closed (hole-punch + ~2.5s
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
(punktfunk.ufw). Exact commands: your distro's install guide, or the per-distro packaging README.
|
(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
|
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.
|
Port map: design/gamestream-host-plan.md.
|
||||||
-->
|
-->
|
||||||
<service>
|
<service>
|
||||||
|
|||||||
@@ -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
|
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
|
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).
|
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>
|
<service>
|
||||||
<short>Punktfunk (native punktfunk/1)</short>
|
<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="9777"/> <!-- QUIC control plane (default 9777) -->
|
||||||
<port protocol="udp" port="5353"/> <!-- mDNS auto-discovery (_punktfunk._udp.local) -->
|
<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>
|
</service>
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
firewall-cmd (add-service=punktfunk-web, then reload). CachyOS/Ubuntu: use the ufw punktfunk-web
|
firewall-cmd (add-service=punktfunk-web, then reload). CachyOS/Ubuntu: use the ufw punktfunk-web
|
||||||
profile instead.
|
profile instead.
|
||||||
|
|
||||||
The mgmt REST API (TCP 47990) is a different, loopback-only surface (the console proxies to it
|
The mgmt REST API (TCP 47990) is a different surface — the console proxies to it over loopback, and
|
||||||
locally) and is deliberately NOT opened here.
|
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>
|
<service>
|
||||||
<short>Punktfunk web console</short>
|
<short>Punktfunk web console</short>
|
||||||
|
|||||||
@@ -21,17 +21,22 @@
|
|||||||
|
|
||||||
[punktfunk-native]
|
[punktfunk-native]
|
||||||
title=punktfunk host (native punktfunk/1)
|
title=punktfunk host (native punktfunk/1)
|
||||||
description=punktfunk/1 native streaming: QUIC control plane + mDNS auto-discovery
|
description=punktfunk/1 native streaming: QUIC control plane + mDNS auto-discovery + mgmt/library API (HTTPS + mTLS)
|
||||||
ports=9777/udp|5353/udp
|
ports=9777/udp|5353/udp|47990/tcp
|
||||||
|
|
||||||
[punktfunk-gamestream]
|
[punktfunk-gamestream]
|
||||||
title=punktfunk host (GameStream/Moonlight)
|
title=punktfunk host (GameStream/Moonlight)
|
||||||
description=GameStream/Moonlight compatibility ports (opt-in, trusted LAN only)
|
description=GameStream/Moonlight compatibility ports (opt-in, trusted LAN only)
|
||||||
ports=47984,47989,48010/tcp|47998:48010/udp|5353/udp
|
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
|
# 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).
|
# 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]
|
[punktfunk-web]
|
||||||
title=punktfunk web console
|
title=punktfunk web console
|
||||||
description=The optional punktfunk management web console (HTTPS, login-gated) reachable from the LAN
|
description=The optional punktfunk management web console (HTTPS, login-gated) reachable from the LAN
|
||||||
|
|||||||
Reference in New Issue
Block a user