docs(arch): fish-safe repo setup, firewalld services, fix client label
apple / screenshots (push) Successful in 5m25s
android / android (push) Has been cancelled
apple / swift (push) Successful in 1m13s
ci / rust (push) Successful in 5m26s
arch / build-publish (push) Successful in 6m6s
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 59s
deb / build-publish (push) Successful in 2m58s
decky / build-publish (push) Successful in 25s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 16s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
ci / bench (push) Successful in 4m45s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 44s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m13s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m5s
docker / deploy-docs (push) Successful in 20s
apple / screenshots (push) Successful in 5m25s
android / android (push) Has been cancelled
apple / swift (push) Successful in 1m13s
ci / rust (push) Successful in 5m26s
arch / build-publish (push) Successful in 6m6s
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 59s
deb / build-publish (push) Successful in 2m58s
decky / build-publish (push) Successful in 25s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 16s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
ci / bench (push) Successful in 4m45s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 44s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m13s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m5s
docker / deploy-docs (push) Successful in 20s
The pacman-repo setup step used a bash heredoc (`<<'EOF'`), which fish — the
default shell on CachyOS — cannot parse ("expected a string, but found a
redirection"). Replace it with a cross-shell `printf | sudo tee -a` form in both
the Arch guide and packaging/arch/README.md; `$repo`/`$arch` stay literal for
pacman and the output is byte-identical to the old heredoc.
Firewall: stock Arch ships none (ports already open), but CachyOS enables
firewalld by default and an Arch package must never touch the running firewall.
Ship firewalld service definitions the host package installs to
/usr/lib/firewalld/services/ (punktfunk-gamestream, punktfunk-native), not
auto-enabled; the install scriptlet prints the enable command only when
firewall-cmd is present. Document it in the Arch guide (new section) and README.
The mgmt API (loopback) and web console ports are deliberately not opened.
Also fix the "GTK4 couch/Deck client" mislabel — it's the native
GTK4/libadwaita Linux client (desktop/laptop/Deck are targets; the
controller-optimized launcher is one view, not its identity) — across the Arch
PKGBUILD/README, Arch guide, and the Debian README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,12 +34,10 @@ curl -fsS https://git.unom.io/api/packages/unom/arch/repository.key \
|
||||
sudo pacman-key --lsign-key E0CA04465C99C936E0B0C6510A317015A34DDD69
|
||||
|
||||
# Add the repo (append to /etc/pacman.conf). No SigLevel line needed — pacman's default
|
||||
# verifies signed packages against the key you just trusted.
|
||||
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
|
||||
|
||||
[punktfunk]
|
||||
Server = https://git.unom.io/api/packages/unom/arch/$repo/$arch
|
||||
EOF
|
||||
# verifies signed packages against the key you just trusted. (printf, not a heredoc, so this
|
||||
# works in fish too — CachyOS's default shell has no `<<EOF` support.)
|
||||
printf '\n[punktfunk]\nServer = https://git.unom.io/api/packages/unom/arch/$repo/$arch\n' \
|
||||
| sudo tee -a /etc/pacman.conf >/dev/null
|
||||
```
|
||||
|
||||
> **Stable vs canary.** `[punktfunk]` is the **stable** channel — it moves only when a `vX.Y.Z`
|
||||
@@ -54,7 +52,7 @@ sudo pacman -S punktfunk-web # optional: the browser management console (
|
||||
sudo usermod -aG input "$USER" # /dev/uinput access for virtual gamepads (re-login to apply)
|
||||
```
|
||||
|
||||
`punktfunk-client` (the GTK4 couch/Deck client) is in the same repo if this box is also a client.
|
||||
`punktfunk-client` (the native GTK4 Linux client) is in the same repo if this box is also a client.
|
||||
The host package ships the systemd **user** units, the udev rule, the UDP socket-buffer sysctl
|
||||
tuning, and example configs. Updates later are just `sudo pacman -Syu`.
|
||||
|
||||
@@ -108,7 +106,33 @@ sed -n 's/^PUNKTFUNK_UI_PASSWORD=//p' ~/.config/punktfunk/web-password
|
||||
To set your own, edit that file and `systemctl --user restart punktfunk-web`. Forgot it? See
|
||||
[Forgot your Password?](/docs/forgot-password).
|
||||
|
||||
## 5. Connect a client
|
||||
## 5. Open the firewall (if you have one)
|
||||
|
||||
**Stock Arch ships no firewall** — every port is already open, so you can skip this. But **CachyOS
|
||||
enables `firewalld` by default**, and an Arch package never opens ports for you (it won't touch your
|
||||
running firewall), so on CachyOS the host is unreachable until you allow it.
|
||||
|
||||
The `punktfunk-host` package installs **firewalld service definitions** for exactly this, so
|
||||
enabling is one command. Reload once so firewalld sees the just-installed definition, add the
|
||||
service, then reload to apply:
|
||||
|
||||
```sh
|
||||
sudo firewall-cmd --reload
|
||||
sudo firewall-cmd --permanent --add-service=punktfunk-native # the default native host
|
||||
# --add-service=punktfunk-gamestream # …or add this for Moonlight compat
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
`punktfunk-native` opens the QUIC control port (UDP 9777) + mDNS discovery; add
|
||||
`punktfunk-gamestream` as well if you run `serve --gamestream` (the fixed Moonlight ports + mDNS).
|
||||
The media **data plane** uses an *ephemeral* UDP port per session (nothing fixed to open); a
|
||||
restrictive firewall must also allow a UDP range. The web console (47992) and mgmt API (47990,
|
||||
loopback-only) are **not** opened by these — reach the console from the host box, or open 47992
|
||||
yourself if you want it on the LAN. Not on firewalld? See
|
||||
[`packaging/arch/README.md`](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/arch/README.md#firewall)
|
||||
for the `ufw`/`nftables` port lists.
|
||||
|
||||
## 6. Connect a client
|
||||
|
||||
From any [client](/docs/clients), `--discover` finds the host on the LAN. On first connect, complete
|
||||
the **PIN pairing** — arm it from the host's web console, which displays a 4-digit PIN to type into
|
||||
|
||||
+10
-2
@@ -1,7 +1,7 @@
|
||||
# Maintainer: unom <noreply@anthropic.com>
|
||||
#
|
||||
# Arch Linux / SteamOS split package: punktfunk-host (the gaming-rig HOST, NVENC) and
|
||||
# punktfunk-client (the GTK4 couch/Deck CLIENT). Mirrors the rpm subpackages
|
||||
# punktfunk-client (the native GTK4/libadwaita Linux CLIENT). Mirrors the rpm subpackages
|
||||
# (packaging/rpm/punktfunk.spec) and the two deb build scripts. On a Steam Deck you want
|
||||
# `punktfunk-client` (it's what the Decky plugin launches); on a gaming rig, `punktfunk-host`.
|
||||
#
|
||||
@@ -134,13 +134,21 @@ package_punktfunk-host() {
|
||||
install -Dm0644 "$R/packaging/bazzite/gamescope-headless-session" \
|
||||
"$pkgdir/etc/gamescope-session-plus/sessions.d/steam"
|
||||
install -Dm0644 "$R/api/openapi.json" "$pkgdir/usr/share/punktfunk/openapi.json"
|
||||
# firewalld service definitions — NOT auto-enabled (Arch packages never touch the admin's
|
||||
# firewall). Stock Arch ships none, so they're a no-op there; CachyOS et al. ship firewalld, so
|
||||
# sudo firewall-cmd --reload && sudo firewall-cmd --permanent --add-service=punktfunk-gamestream && sudo firewall-cmd --reload
|
||||
# (or =punktfunk-native). See README.md → Firewall.
|
||||
install -Dm0644 "$R/packaging/arch/punktfunk-gamestream.xml" \
|
||||
"$pkgdir/usr/lib/firewalld/services/punktfunk-gamestream.xml"
|
||||
install -Dm0644 "$R/packaging/arch/punktfunk-native.xml" \
|
||||
"$pkgdir/usr/lib/firewalld/services/punktfunk-native.xml"
|
||||
install -Dm0644 "$R/LICENSE-MIT" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-MIT"
|
||||
install -Dm0644 "$R/LICENSE-APACHE" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-APACHE"
|
||||
install -Dm0644 "$R/README.md" "$pkgdir/usr/share/doc/punktfunk-host/README.md"
|
||||
}
|
||||
|
||||
package_punktfunk-client() {
|
||||
pkgdesc="Low-latency desktop/game streaming CLIENT (GTK4) — the couch/Deck side"
|
||||
pkgdesc="Low-latency desktop/game streaming CLIENT — native GTK4/libadwaita Linux app"
|
||||
# The GTK4/libadwaita client: SDL3 gamepads, FFmpeg (VAAPI) decode, PipeWire audio/mic.
|
||||
depends=('gtk4' 'libadwaita' 'sdl3' 'ffmpeg' 'pipewire' 'wireplumber' 'pipewire-pulse'
|
||||
'opus' 'libglvnd')
|
||||
|
||||
+36
-11
@@ -1,9 +1,9 @@
|
||||
# punktfunk on Arch Linux / SteamOS
|
||||
|
||||
Packaging for punktfunk on Arch and Arch-derived immutable distros. The `PKGBUILD` is a **split
|
||||
package** producing **`punktfunk-host`** (the gaming-rig host) and **`punktfunk-client`** (the GTK4
|
||||
couch/Deck client) — mirrors the rpm subpackages (`packaging/rpm/punktfunk.spec`) and the deb build
|
||||
scripts. On a **Steam Deck used as a client you want `punktfunk-client`** (it's what the
|
||||
package** producing **`punktfunk-host`** (the gaming-rig host) and **`punktfunk-client`** (the native
|
||||
GTK4/libadwaita Linux client) — mirrors the rpm subpackages (`packaging/rpm/punktfunk.spec`) and the
|
||||
deb build scripts. On a **Steam Deck used as a client you want `punktfunk-client`** (it's what the
|
||||
[Decky plugin](../../clients/decky/) launches); on a gaming rig, `punktfunk-host`.
|
||||
|
||||
> **Steam Deck as a HOST:** don't use this PKGBUILD — SteamOS's read-only root makes `makepkg`/sysext
|
||||
@@ -42,15 +42,13 @@ curl -fsS https://git.unom.io/api/packages/unom/arch/repository.key \
|
||||
sudo pacman-key --lsign-key E0CA04465C99C936E0B0C6510A317015A34DDD69
|
||||
|
||||
# 2. Add the repo (pick ONE channel — punktfunk for releases, punktfunk-canary for main builds).
|
||||
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
|
||||
|
||||
[punktfunk]
|
||||
Server = https://git.unom.io/api/packages/unom/arch/$repo/$arch
|
||||
EOF
|
||||
# printf, not a heredoc, so this works in fish too (CachyOS's default shell has no `<<EOF`).
|
||||
printf '\n[punktfunk]\nServer = https://git.unom.io/api/packages/unom/arch/$repo/$arch\n' \
|
||||
| sudo tee -a /etc/pacman.conf >/dev/null
|
||||
|
||||
# 3. Sync + install.
|
||||
sudo pacman -Sy punktfunk-host # gaming rig
|
||||
sudo pacman -Sy punktfunk-client # couch/Deck side
|
||||
sudo pacman -Sy punktfunk-client # the native GTK4 Linux client
|
||||
sudo pacman -Sy punktfunk-web # optional browser management console
|
||||
```
|
||||
|
||||
@@ -139,7 +137,31 @@ so it's a much lighter sysext than the host.
|
||||
|
||||
## Firewall
|
||||
|
||||
If the host box runs a firewall, open the ports it listens on. The **native `punktfunk/1`** plane:
|
||||
**Stock Arch ships no firewall** — every port is open by default, so there is nothing to do.
|
||||
Spins that enable one **do not** get their ports opened for you: an Arch package never touches the
|
||||
admin's running firewall. **CachyOS is the common case** — its installer turns on `firewalld` by
|
||||
default, so out of the box the host is unreachable until you allow it.
|
||||
|
||||
The `punktfunk-host` package ships **firewalld service definitions** (installed to
|
||||
`/usr/lib/firewalld/services/`) so enabling is one command — pick the plane your host serves:
|
||||
|
||||
```sh
|
||||
# Reload once so firewalld picks up the just-installed service definition, add it, reload to apply.
|
||||
sudo firewall-cmd --reload
|
||||
sudo firewall-cmd --permanent --add-service=punktfunk-gamestream # Moonlight/GameStream host
|
||||
# --add-service=punktfunk-native # …or the native-only host
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
`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
|
||||
both planes). The **data plane is an *ephemeral* UDP port** negotiated per session, so there is no
|
||||
fixed data port in either service; a restrictive firewall must additionally allow a UDP range (the
|
||||
project does not pin one). The mgmt REST API (TCP 47990) binds to loopback by default — leave it
|
||||
closed unless you move it off loopback with `--mgmt-bind IP:PORT` (which then requires
|
||||
`--mgmt-token`).
|
||||
|
||||
For a non-firewalld setup, open the ports directly. The **native `punktfunk/1`** plane:
|
||||
|
||||
- **QUIC control plane: UDP 9777** (`serve --native-port N` to change).
|
||||
- **Data plane: an *ephemeral* UDP port** — negotiated per session, so there is no fixed port to
|
||||
@@ -182,6 +204,9 @@ udp dport { 47998-48010, 5353 } accept
|
||||
- `PKGBUILD` — split package: `punktfunk-host` + `punktfunk-client` (builds the working tree via
|
||||
`PF_SRCDIR`, or a git tag for AUR).
|
||||
- `punktfunk-host.install` / `punktfunk-client.install` — pacman scriptlets (udev reload + sysctl +
|
||||
first-run hint), mirror the RPM `%post` / deb postinst.
|
||||
first-run hint, incl. the firewalld enable command when firewalld is present), mirror the RPM
|
||||
`%post` / deb postinst.
|
||||
- `punktfunk-gamestream.xml` / `punktfunk-native.xml` — firewalld service definitions the host
|
||||
package installs to `/usr/lib/firewalld/services/` (not auto-enabled; see Firewall above).
|
||||
- `build-sysext.sh` — wraps either built `.pkg.tar.zst` into a `systemd-sysext` `.raw` for SteamOS
|
||||
(derives the name from the package, so it works for host or client).
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
firewalld service definition for the punktfunk GameStream (Moonlight-compatible) host.
|
||||
|
||||
Installed to /usr/lib/firewalld/services/ by the punktfunk-host package. It is NOT enabled
|
||||
automatically: an Arch package never touches the admin's running firewall. Stock Arch ships no
|
||||
firewall (these ports are already open); on a firewalld spin such as CachyOS, enable it once with
|
||||
firewall-cmd (add-service=punktfunk-gamestream, then reload). Exact commands: the packaging/arch
|
||||
README, Firewall section.
|
||||
|
||||
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.
|
||||
Port map: design/gamestream-host-plan.md.
|
||||
-->
|
||||
<service>
|
||||
<short>Punktfunk (GameStream / Moonlight)</short>
|
||||
<description>Low-latency game-streaming host over the Moonlight-compatible GameStream protocol. Opens the fixed nvhttp (HTTPS/HTTP), RTSP, video RTP, ENet control/input and Opus audio ports, plus mDNS for auto-discovery.</description>
|
||||
<port protocol="tcp" port="47984"/> <!-- HTTPS nvhttp (paired, mutual TLS) -->
|
||||
<port protocol="tcp" port="47989"/> <!-- HTTP nvhttp (/serverinfo, /pair PIN flow) -->
|
||||
<port protocol="tcp" port="48010"/> <!-- RTSP handshake -->
|
||||
<port protocol="udp" port="47998"/> <!-- Video RTP (+ FEC) -->
|
||||
<port protocol="udp" port="47999"/> <!-- ENet control stream + remote input -->
|
||||
<port protocol="udp" port="48000"/> <!-- Audio (Opus) -->
|
||||
<port protocol="udp" port="5353"/> <!-- mDNS auto-discovery (_nvstream._tcp.local) -->
|
||||
</service>
|
||||
@@ -17,6 +17,18 @@ punktfunk-host installed.
|
||||
NOTE: encode is NVENC-only. Install 'nvidia-utils' on an NVIDIA host. An AMD Steam Deck is NOT
|
||||
yet supported — it needs a VAAPI (hevc_vaapi) encoder backend (see packaging/arch/README.md).
|
||||
MSG
|
||||
# Firewall: stock Arch ships none (ports already open), but CachyOS et al. enable firewalld. We
|
||||
# install firewalld service definitions but never touch the running firewall — just point the way.
|
||||
if command -v firewall-cmd >/dev/null 2>&1; then
|
||||
cat <<'MSG'
|
||||
|
||||
4. firewalld is active — open the streaming ports once (GameStream/Moonlight shown; use
|
||||
'punktfunk-native' instead for the native-only host):
|
||||
sudo firewall-cmd --reload # load the new service def
|
||||
sudo firewall-cmd --permanent --add-service=punktfunk-gamestream
|
||||
sudo firewall-cmd --reload
|
||||
MSG
|
||||
fi
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
firewalld service definition for the native punktfunk/1 host (the secure default 'serve', or the
|
||||
punktfunk1-host subcommand).
|
||||
|
||||
Installed to /usr/lib/firewalld/services/ by the punktfunk-host package. NOT enabled automatically
|
||||
(an Arch package never touches the admin's firewall). Stock Arch has no firewall; on a firewalld
|
||||
spin such as CachyOS, enable it once with firewall-cmd (add-service=punktfunk-native, then reload).
|
||||
Exact commands: the packaging/arch README, Firewall section.
|
||||
|
||||
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).
|
||||
-->
|
||||
<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>
|
||||
<port protocol="udp" port="9777"/> <!-- QUIC control plane (default 9777) -->
|
||||
<port protocol="udp" port="5353"/> <!-- mDNS auto-discovery (_punktfunk._udp.local) -->
|
||||
</service>
|
||||
@@ -9,7 +9,7 @@ to a canary build — see [Release Channels](https://punktfunk.unom.io/docs/chan
|
||||
below subscribes to `stable`; swap `stable` → `canary` for the latest main builds.
|
||||
|
||||
The same workflow also publishes **`punktfunk-web`** (the browser management console — pairing +
|
||||
status) and **`punktfunk-client`** (the GTK4 couch/Deck client). `punktfunk-host` **Recommends**
|
||||
status) and **`punktfunk-client`** (the native GTK4/libadwaita Linux client). `punktfunk-host` **Recommends**
|
||||
`punktfunk-web`, so a default `apt install punktfunk-host` pulls the console too (alongside the
|
||||
udev/sysctl bits) unless you've disabled weak deps; `punktfunk-client` is independent — install it
|
||||
on the box you stream *to*. (`punktfunk-probe` is the headless reference/test tool, not packaged
|
||||
|
||||
Reference in New Issue
Block a user