Skip to content

fix(wireguard): remove the peer when a user loses WireGuard access - #99

Merged
ImMohammad20000 merged 2 commits into
PasarGuard:devfrom
T3ST3ST3R0N:fix/wg-remove-peer-on-empty-peer-ips
Oct 9, 2026
Merged

ImMohammad20000 merged 2 commits into
PasarGuard:devfrom
T3ST3ST3R0N:fix/wg-remove-peer-on-empty-peer-ips

Conversation

@T3ST3ST3R0N

@T3ST3ST3R0N T3ST3ST3R0N commented Oct 8, 2026 •

Copy link
Copy Markdown

Problem

When a user loses WireGuard access but stays active (e.g. their groups no longer include any WireGuard inbound), the panel does two things:

  1. It releases the user's IPs back to its pool and stores peer_ips = [], keeping the public key.
  2. It pushes the user to the nodes with that empty peer_ips.

In a partial sync (SyncUser, UpdateUsers, chunked updates), syncUsersPartialReconcile built the set of touched emails only from the users that survived normalizeUsers. normalizeUsers drops users with empty peer_ips or no WireGuard credentials. So this user was never touched, and their existing peer was never removed. As a result:

  • the user kept working WireGuard access until the next Start or full sync;
  • the IP the panel had freed could be handed to another user while the old peer still held it in the PeerStore.

Disable and delete were not affected, because the panel still sends the stored peer_ips (without inbounds) in those cases.

Change

  • Every user in the request that has an email now counts as touched. Only the normalized users become desired peers, so a stale peer is diffed out and removed from the device and the PeerStore, and its stats entry is marked deleted.
  • A side effect is correct now: a key can move from a user sent with empty peer_ips to another user in the same batch. Previously that was rejected with "already assigned to user ...".
  • syncUsersFull is unchanged.

Tests

backend/wireguard/user_sync_test.go, each test failing without the change:

  • TestUpdateUsersRemovesPeerWhenUserLosesWireguardAccess: two cases (empty peer_ips, and no wireguard proxy at all). Exactly one Remove is applied, the peer leaves the PeerStore, and the stats entry is marked deleted.
  • TestUpdateUsersAllowsKeyHandoverFromUserWhoLostAccess: the key handover in one batch.

go test ./backend/wireguard/ ./config/ ./controller/ -p 1 passes, and go vet / gofmt -l are clean.

Summary by CodeRabbit

  • Bug Fixes
    • WireGuard peers are now removed when a user is submitted without peer IPs or WireGuard credentials, ensuring removed access is reflected in device configuration and stored peer records.
    • When a WireGuard key is reassigned in the same update, the former owner’s peer is removed even if their submission has no peer IPs.

A partial sync (SyncUser / UpdateUsers / chunked updates) only marked as
"touched" the users that survived normalizeUsers, which drops users with
empty peer_ips or no WireGuard credentials. The panel sends exactly that
shape when it releases a user's WireGuard IPs (for example after the user
left every WireGuard group), so the user's existing peer was never removed
and kept working until the next Start or full sync. The freed IP could
also be handed to another user while the old peer still held it in the
peer store.

Every user with an email in the request now counts as touched; only the
normalized users become desired peers, so the stale peer is diffed out
and removed from the device and the peer store.
…es access

The stale peer's stats entry must be marked deleted, and a key can move from a user sent with empty peer_ips to another user in the same batch. The handover test fails without the previous commit ("already assigned to user").
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ef0a5dc5-9e58-49ac-a6e9-51ddf43db480

📥 Commits

Reviewing files that changed from the base of the PR and between 7be885f and fb0e71a.


📒 Files selected for processing (2)
  • backend/wireguard/user_partial_sync.go
  • backend/wireguard/user_sync_test.go

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.



Walkthrough

Partial user reconciliation now tracks nonempty emails from every requested user before normalization. Tests cover removal of stale peers when users lack peer IPs or WireGuard credentials, and transfer of a key to another user in the same batch.

Changes

Partial User Sync

Layer / File(s) Summary
Track requested users during reconciliation
backend/wireguard/user_partial_sync.go, backend/wireguard/user_sync_test.go
Partial sync now includes nonempty emails from the original request in touchedEmails. Tests check stale peer removal for users without peer IPs or WireGuard credentials, and key transfer to another user in the same batch.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to fb0e7

No actionable merge-blocking issue remains; the change is mergeable after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: removing a stale WireGuard peer when a user loses WireGuard access.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.


  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the users in a row,
And notes each name before the peers can go.
Stale keys hop off the device with care,
A new owner takes the key from there,
Then all the garden’s sync paths flow.

Comment @coderabbitai help to get the list of available commands.

@ImMohammad20000
ImMohammad20000 merged commit f72ac0e into PasarGuard:dev Oct 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants