fix(amneziawg): re-run the forward guard once a new row has its own ports

normalizeAmneziaWGSettings validates every client's ForwardedPorts before the row
is saved, and loadPortConflictContext then reads the database -- so the new
AmneziaWG row is never a candidate for itself. A client could forward exactly the
relay port the row's own id derives, or its own WireGuard listen port, and the
create was accepted: at runtime the panel's wildcard forward listener and Xray's
127.0.0.1 relay race for the same port, and a lost relay bind makes Xray refuse
the whole generated config (#6544 review, pre-existing).

The post-Save block is the only place the id is known, so it re-runs the guard
there. Both callers now share amneziaWGForwardedPortsConflict, so the collision
message lives in one place instead of two.

TestAddInbound_AmneziawgRefusesAClientForwardingItsOwnRelayPort fails without
this -- watched red first -- and passes with it.
This commit is contained in:
BlindMaster24
2026-09-15 12:55:08 +03:00
parent 35ffba1eea
commit 80eb5712b6
3 changed files with 69 additions and 2 deletions
+5
View File
@@ -1257,6 +1257,11 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, boo
if conflict != nil {
return common.NewError(conflict.String())
}
// The clients' forward specs were validated while this row had no id,
// so the ports it now derives were never in the guard's context.
if aErr := s.checkAmneziaWGForwardedPorts(tx, inbound.Settings); aErr != nil {
return aErr
}
}
// Emails seeded here (import's ClientStats, e.g. the controller's forced
// Enable=true on every imported stat row) are authoritative for this call