mirror of
https://github.com/h44z/wg-portal.git
synced 2026-02-23 10:56:22 +00:00
Compare commits
5 Commits
multi_auth
...
improve_ip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11794fec61 | ||
|
|
df9fdd14fb | ||
|
|
e0f6c1d04b | ||
|
|
d2fe267be7 | ||
|
|
bb516e9115 |
6
go.mod
6
go.mod
@@ -21,9 +21,9 @@ require (
|
||||
github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.5
|
||||
github.com/yeqown/go-qrcode/writer/compressed v1.0.1
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/crypto v0.47.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/sys v0.39.0
|
||||
golang.org/x/sys v0.40.0
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.6.0
|
||||
@@ -96,7 +96,7 @@ require (
|
||||
golang.org/x/mod v0.31.0 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@@ -270,8 +270,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM=
|
||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -332,8 +332,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -362,8 +362,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
@@ -626,7 +626,7 @@ func (c LocalController) exec(command string, interfaceId domain.InterfaceIdenti
|
||||
if err != nil {
|
||||
slog.Warn("failed to executed shell command",
|
||||
"command", commandWithInterfaceName, "stdin", stdin, "output", string(out), "error", err)
|
||||
return fmt.Errorf("failed to exexute shell command %s: %w", commandWithInterfaceName, err)
|
||||
return fmt.Errorf("failed to execute shell command %s: %w", commandWithInterfaceName, err)
|
||||
}
|
||||
slog.Debug("executed shell command",
|
||||
"command", commandWithInterfaceName,
|
||||
|
||||
@@ -985,7 +985,26 @@ func (m Manager) importPeer(ctx context.Context, in *domain.Interface, p *domain
|
||||
peer.InterfaceIdentifier = in.Identifier
|
||||
peer.EndpointPublicKey = domain.NewConfigOption(in.PublicKey, true)
|
||||
peer.AllowedIPsStr = domain.NewConfigOption(in.PeerDefAllowedIPsStr, true)
|
||||
peer.Interface.Addresses = p.AllowedIPs // use allowed IP's as the peer IP's TODO: Should this also match server interface address' prefix length?
|
||||
|
||||
// split allowed IP's into interface addresses and extra allowed IP's
|
||||
var interfaceAddresses []domain.Cidr
|
||||
var extraAllowedIPs []domain.Cidr
|
||||
for _, allowedIP := range p.AllowedIPs {
|
||||
isHost := (allowedIP.IsV4() && allowedIP.NetLength == 32) || (!allowedIP.IsV4() && allowedIP.NetLength == 128)
|
||||
isNetworkAddr := allowedIP.Addr == allowedIP.NetworkAddr().Addr
|
||||
|
||||
// Network addresses (e.g. 10.0.0.0/24) will always be extra allowed IP's.
|
||||
// For IP addresses, such as 10.0.0.1/24, it is challenging to tell whether it is an interface address or
|
||||
// an extra allowed IP, therefore we treat such addresses as interface addresses.
|
||||
if !isHost && isNetworkAddr {
|
||||
extraAllowedIPs = append(extraAllowedIPs, allowedIP)
|
||||
} else {
|
||||
interfaceAddresses = append(interfaceAddresses, allowedIP)
|
||||
}
|
||||
}
|
||||
peer.Interface.Addresses = interfaceAddresses
|
||||
peer.ExtraAllowedIPsStr = domain.CidrsToString(extraAllowedIPs)
|
||||
|
||||
peer.Interface.DnsStr = domain.NewConfigOption(in.PeerDefDnsStr, true)
|
||||
peer.Interface.DnsSearchStr = domain.NewConfigOption(in.PeerDefDnsSearchStr, true)
|
||||
peer.Interface.Mtu = domain.NewConfigOption(in.PeerDefMtu, true)
|
||||
|
||||
94
internal/app/wireguard/wireguard_interfaces_test.go
Normal file
94
internal/app/wireguard/wireguard_interfaces_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/domain"
|
||||
)
|
||||
|
||||
func TestImportPeer_AddressMapping(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
allowedIPs []string
|
||||
expectedInterface []string
|
||||
expectedExtraAllowed string
|
||||
}{
|
||||
{
|
||||
name: "IPv4 host address",
|
||||
allowedIPs: []string{"10.0.0.1/32"},
|
||||
expectedInterface: []string{"10.0.0.1/32"},
|
||||
expectedExtraAllowed: "",
|
||||
},
|
||||
{
|
||||
name: "IPv6 host address",
|
||||
allowedIPs: []string{"fd00::1/128"},
|
||||
expectedInterface: []string{"fd00::1/128"},
|
||||
expectedExtraAllowed: "",
|
||||
},
|
||||
{
|
||||
name: "IPv4 network address",
|
||||
allowedIPs: []string{"10.0.1.0/24"},
|
||||
expectedInterface: []string{},
|
||||
expectedExtraAllowed: "10.0.1.0/24",
|
||||
},
|
||||
{
|
||||
name: "IPv4 normal address with mask",
|
||||
allowedIPs: []string{"10.0.1.5/24"},
|
||||
expectedInterface: []string{"10.0.1.5/24"},
|
||||
expectedExtraAllowed: "",
|
||||
},
|
||||
{
|
||||
name: "Mixed addresses",
|
||||
allowedIPs: []string{
|
||||
"10.0.0.1/32", "192.168.1.0/24", "172.16.0.5/24", "fd00::1/128", "fd00:1::/64",
|
||||
},
|
||||
expectedInterface: []string{"10.0.0.1/32", "172.16.0.5/24", "fd00::1/128"},
|
||||
expectedExtraAllowed: "192.168.1.0/24,fd00:1::/64",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
db := &mockDB{}
|
||||
m := Manager{
|
||||
db: db,
|
||||
}
|
||||
|
||||
iface := &domain.Interface{
|
||||
Identifier: "wg0",
|
||||
Type: domain.InterfaceTypeServer,
|
||||
}
|
||||
|
||||
allowedIPs := make([]domain.Cidr, len(tt.allowedIPs))
|
||||
for i, s := range tt.allowedIPs {
|
||||
cidr, _ := domain.CidrFromString(s)
|
||||
allowedIPs[i] = cidr
|
||||
}
|
||||
|
||||
p := &domain.PhysicalPeer{
|
||||
Identifier: "peer1",
|
||||
KeyPair: domain.KeyPair{PublicKey: "peer1-public-key-is-long-enough"},
|
||||
AllowedIPs: allowedIPs,
|
||||
}
|
||||
|
||||
err := m.importPeer(context.Background(), iface, p)
|
||||
assert.NoError(t, err)
|
||||
|
||||
savedPeer := db.savedPeers["peer1"]
|
||||
assert.NotNil(t, savedPeer)
|
||||
|
||||
// Check interface addresses
|
||||
actualInterface := make([]string, len(savedPeer.Interface.Addresses))
|
||||
for i, addr := range savedPeer.Interface.Addresses {
|
||||
actualInterface[i] = addr.String()
|
||||
}
|
||||
assert.ElementsMatch(t, tt.expectedInterface, actualInterface)
|
||||
|
||||
// Check extra allowed IPs
|
||||
assert.Equal(t, tt.expectedExtraAllowed, savedPeer.ExtraAllowedIPsStr)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user