feat(wireguard): implement interface network validation and tests · PasarGuard/node@ab850c5 · GitHub
Skip to content

Commit ab850c5

Browse files
committed
feat(wireguard): implement interface network validation and tests
1 parent f90d520 commit ab850c5

4 files changed

Lines changed: 79 additions & 2 deletions

File tree

backend/wireguard/config.go

Lines changed: 22 additions & 0 deletions

backend/wireguard/config_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
package wireguard
22

33
import (
4+
"net"
45
"testing"
56
)
67

8+
func TestConfigInterfaceNetworks(t *testing.T) {
9+
cfg := &Config{Address: []string{" 10.8.0.1/24 ", ""}}
10+
nets := cfg.InterfaceNetworks()
11+
if len(nets) != 1 {
12+
t.Fatalf("expected 1 network, got %d", len(nets))
13+
}
14+
if nets[0].String() != "10.8.0.0/24" {
15+
t.Fatalf("unexpected network: %s", nets[0].String())
16+
}
17+
_, ipn, _ := net.ParseCIDR("10.8.0.5/32")
18+
if !peerIPAllowedOnInterface(ipn, nets) {
19+
t.Fatal("expected 10.8.0.5/32 to be allowed under 10.8.0.0/24")
20+
}
21+
_, wrong, _ := net.ParseCIDR("10.0.0.2/32")
22+
if peerIPAllowedOnInterface(wrong, nets) {
23+
t.Fatal("expected 10.0.0.2/32 to be rejected under 10.8.0.0/24")
24+
}
25+
}
26+
727
func TestNewWireGuardConfig(t *testing.T) {
828
configJSON := `{
929
"interface_name": "wg0",

backend/wireguard/user_common.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,29 @@ func buildAddConfigFromPeerInfo(peer *PeerInfo, presharedKey *wgtypes.Key) (wgty
187187
return buildAddConfig(peer.PublicKey, peer.AllowedIPs, presharedKey), nil
188188
}
189189

190+
func peerIPAllowedOnInterface(peerNet *net.IPNet, ifaceNets []*net.IPNet) bool {
191+
if len(ifaceNets) == 0 {
192+
return true
193+
}
194+
for _, pool := range ifaceNets {
195+
if pool == nil || peerNet == nil {
196+
continue
197+
}
198+
if len(peerNet.IP) != len(pool.IP) {
199+
continue
200+
}
201+
if !pool.Contains(peerNet.IP) {
202+
continue
203+
}
204+
pPeer, _ := peerNet.Mask.Size()
205+
pPool, _ := pool.Mask.Size()
206+
if pPeer >= pPool {
207+
return true
208+
}
209+
}
210+
return false
211+
}
212+
190213
func (wg *WireGuard) collectDesiredPeers(users []*common.User) (map[string]*DesiredPeer, error) {
191214
desiredPeers := make(map[string]*DesiredPeer)
192215
seenIPs := make(map[string]string)
@@ -206,6 +229,8 @@ func (wg *WireGuard) collectDesiredPeers(users []*common.User) (map[string]*Desi
206229
continue
207230
}
208231

232+
ifaceNets := wg.config.InterfaceNetworks()
233+
209234
var allowedIPNets []net.IPNet
210235
var hasInvalidIP bool
211236

@@ -217,6 +242,16 @@ func (wg *WireGuard) collectDesiredPeers(users []*common.User) (map[string]*Desi
217242
break
218243
}
219244

245+
if !peerIPAllowedOnInterface(ipNet, ifaceNets) {
246+
log.Printf(
247+
"skipping wireguard peer IP %s for user %s on interface %s (outside core address ranges)",
248+
peerIp,
249+
email,
250+
wg.config.InterfaceName,
251+
)
252+
continue
253+
}
254+
220255
canonicalIP := ipNet.String()
221256
if existingEmail, exists := seenIPs[canonicalIP]; exists && existingEmail != email {
222257
return nil, fmt.Errorf("duplicate wireguard allowed IP %s assigned to users %s and %s", canonicalIP, existingEmail, email)

backend/wireguard/user_sync_test.go

Lines changed: 2 additions & 2 deletions

0 commit comments

Comments
 (0)