wireguard: add Guest Party Mode - #148
Merged
Merged
Conversation
Lets a user host a temporary, isolated WireGuard network for guests (e.g. a LAN party): guests see each other and the router, never the real home LAN. Flips the server's existing lan_access/client-to-client settings for the duration and restores them exactly on End Guest Party Mode, since wireguard_gargoyle has exactly one hardcoded server instance and both settings are global to it. Warns and requires confirmation before starting if the server already has enabled clients, since starting a party also cuts off their LAN access for as long as it's on. Captures the pre-party lan_access/c2c into new wireguard_gargoyle.server options rather than /tmp, so ending the party still works after a reboot mid-party. Named "Guest Party Mode" rather than "Guest Network" to avoid colliding with the existing Wi-Fi guest network feature.
ispyisail
changed the base branch from
refactor/dedup-wg-client-config
to
master
July 30, 2026 08:17
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #145 (base branch is
refactor/dedup-wg-client-config), for the same shared config builder #146/#147 use. Sibling of both, not stacked on either. Opened against the same base to keep merge order simple.Sourced from a real forum thread (viewtopic.php?p=67974): a user wanted to host a temporary "LAN party" network for guests over WireGuard, isolated from the real home LAN.
The forum thread's own answer reached too far
The suggested fix was a second
wg1interface, "not in the GUI."wireguard_gargoylehas exactly one hardcoded server instance (config server 'server', not a list), so that's real backend/schema work.It's unnecessary for what was actually asked. Two settings the WireGuard page already exposes do the whole job:
wireguard_server_subnet_access(lan_access) gates thefirewall.lan_wg_forwardingsection entirely. Off, and there is no forwarding rule intolanat all, not a narrowed one, an absent one.wireguard_server_client_to_client(c2c) gatesforwardon thewgfirewall zone. On, and guests reach each other and the router (where a shared game server would live).So v1 here is a mode, not a new network: flip those two settings for the party, flip them back after. No new isolation mechanism, no new firewall rules, no new interface.
Why this can't be pure orchestration, unlike #146/#147
Both settings are global to the single WireGuard instance. Starting a party also cuts off any existing road-warrior (a family member's phone) relying on
wg0for LAN access, for as long as the party is on. This PR's entire design is about making that safe and reversible, not hiding it:lan_access/c2cinto newwireguard_gargoyle.serveroptions (party_active,party_saved_lan_access,party_saved_c2c) before flipping, not into/tmp, so End Guest Party Mode still works after a reboot mid-party. Verified directly, not assumed: built a second, independent jsdom window seeded only from what the first window had actually persisted (simulating a real config reload), and confirmed both the active-party detection and the restore still work from that fresh state.lan_access/c2ccombinations, not just the shipped default.Naming
Checked first, per the RFC's own instruction:
basic.shalready hasbasicS.GNet="Guest Network"for the Wi-Fi guest network feature (grep-verified). "Guest Network" would collide with that in a user's mind. Named this "Guest Party Mode" instead.Two real bugs found via an end-to-end smoke run, before any formal test existed
have_privkeybug as wireguard: add a Remote Access Setup Wizard #146:addWgClientModal()'s own prefill sets that dropdown tofalse(correct, no key exists yet); generating a key afterward never flipped it back, so the just-generated private key was silently discarded on commit. Same fix as wireguard: add a Remote Access Setup Wizard #146.uciOriginalvsuci: unlike the Restrictions page,wireguard.js'ssaveChanges()does not updateuciOriginalinline, it relies on a full page reload in production, 5 seconds after the save completes.openGuestPartyWizard()'s active-party check andguestPartyEnd()'s read of the saved values were both checkinguciOriginal, which is stale mid-session (or in any flow, like this one, that reopens the wizard more than once without a reload in between). Fixed both to read the liveuci, which is correct both immediately after a local change and on a genuinely fresh page load.Reuse, same pattern as #146
generateKeyPair,addWgClientModal/addAc,saveChanges,wgBuildClientConfig/downloadAcare all called unchanged, not reimplemented. The config handoff (always-available.confdownload, QR mentioned only as informational text pointing at the separate QR Code page) is identical to #146's design, not the RFC's originaltypeof encWireGuardQrCodesketch (superseded during #146's build; see that PR for why).Testing
18 new tests:
party-isolation.test.js(5): asserted on the actual firewall sectionssaveChanges()emits, not just thelan_accessUCI value, since the real guarantee is "no forwarding rule exists" and a value-only check would still pass ifconfigureFirewall()regressed.party-restore.test.js(7): three distinct startinglan_access/c2ccombinations, the mid-party flip actually taking effect,party_active/party_saved_*correctly cleared afterward, and the reboot-survival simulation described above.party-existing-clients.test.js(6): no re-key, an existing client's section and its own downloadable config both untouched by a full start/end cycle, and a two-guests-in-one-party case.Full wireguard+qr-code suite: 86/86. This branch has neither #146's nor #147's code (sibling branches, not stacked), so their own
wizard-*.test.jsfiles fail here, confirmed as the same branch-topology artifact #147 already documented, not a regression, by excluding them and by stashing this entire diff and re-running.Full node lane, same exclusion applied: clean, only the same 2 pre-existing unrelated failures (
access-dropbear-preserve,vlan/switchinfo-emit), reconfirmed pre-existing on this branch by stashing.page_lint.test.shdoesn't cover plugin pages (documented limitation). Hand-verified instead: all 9 new haserl<%~ %>references and all 11 new JSwgStr.*references checked one-for-one against the i18n file, all present, no gaps.node --checkclean, tabs verified, no em dashes, i18n BOM intact.Not verified
Two real devices connecting to each other during an active party. Everything above is jsdom.
Out of scope (v2, explicitly not built here)
True simultaneous operation (party guests and family road-warriors isolated from each other at the same time) needs a genuinely second WireGuard instance, real schema and backend work across
wireguard.js,wireguard.sh, andwireguard.firewall. Not a "v1.1"; scope separately if anyone actually wants it once v1 ships. Also out of scope: the forum thread's literal10.50.0.xsubnet request, the shared10.64.0.xsubnet already satisfies the actual isolation requirement.