diff options
| author | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-05-06 10:31:57 +0200 |
|---|---|---|
| committer | Jeroen Wijenbergh <jeroen.wijenbergh@geant.org> | 2025-05-06 13:25:48 +0200 |
| commit | 6b939462fb1064abd42e8cb8316700ec844172ea (patch) | |
| tree | b572daecdf0f25e3beec9883a8b7bb2522628212 /internal | |
| parent | 347b20fc91505584bc9efbeca89590a411b95e79 (diff) | |
All: Remove ProxyGuard integration
This should be done in WireGuard-go or in case of a linux a small daemon
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/api/api.go | 5 | ||||
| -rw-r--r-- | internal/api/api_test.go | 20 | ||||
| -rw-r--r-- | internal/server/server.go | 9 | ||||
| -rw-r--r-- | internal/wireguard/ini/ini.go | 42 | ||||
| -rw-r--r-- | internal/wireguard/ini/ini_test.go | 67 | ||||
| -rw-r--r-- | internal/wireguard/wireguard.go | 97 | ||||
| -rw-r--r-- | internal/wireguard/wireguard_test.go | 25 |
7 files changed, 19 insertions, 246 deletions
diff --git a/internal/api/api.go b/internal/api/api.go index 7111c45..4ee82b0 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -233,8 +233,6 @@ type ConnectData struct { Protocol protocol.Protocol // Expires tells us when this configuration expires Expires time.Time - // Proxy is filled when WireGuard is proxied - Proxy *wireguard.Proxy } // see https://github.com/eduvpn/documentation/blob/v3/API.md#request-1 @@ -338,7 +336,7 @@ func (a *API) Connect(ctx context.Context, prof profiles.Profile, protos []proto }, nil } - vpnCfg, proxy, err := wireguard.Config(vpnCfg, wgKey, proto == protocol.WireGuardProxy) + vpnCfg, err = wireguard.Config(vpnCfg, wgKey) if err != nil { return nil, err } @@ -346,7 +344,6 @@ func (a *API) Connect(ctx context.Context, prof profiles.Profile, protos []proto Configuration: vpnCfg, Protocol: proto, Expires: expT, - Proxy: proxy, }, nil } diff --git a/internal/api/api_test.go b/internal/api/api_test.go index f611f07..6ad70f6 100644 --- a/internal/api/api_test.go +++ b/internal/api/api_test.go @@ -10,6 +10,7 @@ import ( "net/url" "reflect" "regexp" + "slices" "strings" "testing" "time" @@ -17,11 +18,9 @@ import ( "codeberg.org/eduVPN/eduvpn-common/internal/api/profiles" httpw "codeberg.org/eduVPN/eduvpn-common/internal/http" "codeberg.org/eduVPN/eduvpn-common/internal/test" - "codeberg.org/eduVPN/eduvpn-common/internal/wireguard" "codeberg.org/eduVPN/eduvpn-common/types/protocol" "codeberg.org/eduVPN/eduvpn-common/types/server" "github.com/jwijenbergh/eduoauth-go" - "slices" ) func tokenHandler(t *testing.T, gt []string) func(http.ResponseWriter, *http.Request) { @@ -421,7 +420,6 @@ func TestAPIConnect(t *testing.T) { Configuration: "openvpnconfig\nscript-security 0", Protocol: protocol.OpenVPN, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - Proxy: nil, }, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, err: nil, @@ -437,7 +435,6 @@ func TestAPIConnect(t *testing.T) { PrivateKey = .*`, Protocol: protocol.WireGuard, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - Proxy: nil, }, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, err: nil, @@ -453,8 +450,6 @@ PrivateKey = .*`, PrivateKey = .*`, Protocol: protocol.WireGuardProxy, Expires: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), - // proxy will be manually checked - Proxy: &wireguard.Proxy{}, }, ptcp: true, protos: []protocol.Protocol{protocol.OpenVPN, protocol.WireGuard}, @@ -490,19 +485,6 @@ PrivateKey = .*`, // we have already checked the config using a regex c.cd.Configuration = gcd.Configuration - // check proxy manually - if c.cd.Proxy != nil && gcd.Proxy != nil { - if gcd.Proxy.Peer != "https://proxyendpoint" { - t.Fatalf("config data proxy peer is no proxyendpoint with HTTPS scheme: %s", gcd.Proxy.Peer) - } - if gcd.Proxy.SourcePort <= 0 { - t.Fatalf("got proxy source port is smaller or equal to 0: %v", gcd.Proxy.SourcePort) - } - if gcd.Proxy.ListenPort <= 0 { - t.Fatalf("proxy listen port is smaller or equal to 0: %v", gcd.Proxy.ListenPort) - } - c.cd.Proxy = gcd.Proxy - } } if !reflect.DeepEqual(gcd, c.cd) { t.Fatalf("got connect data: %v, not equal to want: %v", gcd, c.cd) diff --git a/internal/server/server.go b/internal/server/server.go index e27b38e..2372494 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -138,21 +138,12 @@ func (s *Server) connect(ctx context.Context, pTCP bool) (*srvtypes.Configuratio if err != nil { return nil, err } - var proxy *srvtypes.Proxy - if apicfg.Proxy != nil { - proxy = &srvtypes.Proxy{ - SourcePort: apicfg.Proxy.SourcePort, - ListenPort: apicfg.Proxy.ListenPort, - Peer: apicfg.Proxy.Peer, - } - } return &srvtypes.Configuration{ VPNConfig: apicfg.Configuration, Protocol: apicfg.Protocol, DefaultGateway: chosenP.DefaultGateway, DNSSearchDomains: chosenP.DNSSearchDomains, ShouldFailover: chosenP.ShouldFailover() && !pTCP, - Proxy: proxy, }, nil } diff --git a/internal/wireguard/ini/ini.go b/internal/wireguard/ini/ini.go index 842928a..46c6f8b 100644 --- a/internal/wireguard/ini/ini.go +++ b/internal/wireguard/ini/ini.go @@ -7,7 +7,6 @@ package ini import ( "errors" "fmt" - "slices" "strings" ) @@ -47,28 +46,6 @@ func keyValue(f string) (string, string, error) { // OrderedKeys is a slice of strings that is used for an ordered map type OrderedKeys []string -func (ok *OrderedKeys) find(name string) int { - if ok == nil { - return -1 - } - for i, v := range *ok { - if v == name { - return i - } - } - return -1 -} - -// Remove removes a `name` from the OrderedKeys slice by finding the name -// It is a no-op if the key does not exist -func (ok *OrderedKeys) Remove(name string) { - idx := ok.find(name) - if idx == -1 { - return - } - *ok = slices.Delete((*ok), idx, idx+1) -} - // Section represents a single section within an ini file // It consists of multiple key and values type Section struct { @@ -78,7 +55,7 @@ type Section struct { // KeyValue gets a value for key `key` // It returns an error if the key does not exist -func (sec *Section) KeyValue(key string) (string, error) { +func (sec *Section) keyValue(key string) (string, error) { if v, ok := sec.keyValues[key]; ok { return v, nil } @@ -96,7 +73,7 @@ func (sec *Section) newKeyValue(key string, value string) { // AddOrReplaceKeyValue adds a key `key` with value `value` // If the key already exists it modifies the value func (sec *Section) AddOrReplaceKeyValue(key string, value string) { - _, err := sec.KeyValue(key) + _, err := sec.keyValue(key) if err == nil { sec.keyValues[key] = value return @@ -108,7 +85,7 @@ func (sec *Section) AddOrReplaceKeyValue(key string, value string) { // It returns an error if the key already exists func (sec *Section) AddKeyValue(key string, value string) error { // get an existing key - _, err := sec.KeyValue(key) + _, err := sec.keyValue(key) if err == nil { return fmt.Errorf("key: '%s' already exists", key) } @@ -116,17 +93,6 @@ func (sec *Section) AddKeyValue(key string, value string) error { return nil } -// RemoveKey removes a key `key` from the section -// It returns an error if the key cannot be found -func (sec *Section) RemoveKey(key string) (string, error) { - if v, ok := sec.keyValues[key]; ok { - sec.keys.Remove(key) - delete(sec.keyValues, key) - return v, nil - } - return "", fmt.Errorf("no key to remove with name: '%s'", key) -} - // INI is the struct for a ini file type INI struct { sections map[string]*Section @@ -172,7 +138,7 @@ func (i *INI) String() string { out.WriteString(fmt.Sprintf("[%s]\n", s)) for _, k := range sec.keys { - v, err := sec.KeyValue(k) + v, err := sec.keyValue(k) if err != nil { continue } diff --git a/internal/wireguard/ini/ini_test.go b/internal/wireguard/ini/ini_test.go index faa45f2..d28ad4d 100644 --- a/internal/wireguard/ini/ini_test.go +++ b/internal/wireguard/ini/ini_test.go @@ -160,73 +160,6 @@ func TestKeyValue(t *testing.T) { } } -func TestOrderedKeysFind(t *testing.T) { - cases := []struct { - v OrderedKeys - in string - w int - }{ - { - v: []string{""}, - in: "test", - w: -1, - }, - { - v: []string{"bla"}, - in: "bla", - w: 0, - }, - { - v: []string{"ha"}, - in: "bla", - w: -1, - }, - { - v: []string{"ha", "ga"}, - in: "ga", - w: 1, - }, - } - - for _, c := range cases { - g := c.v.find(c.in) - if g != c.w { - t.Fatalf("got: %v, want: %v", g, c.w) - } - } -} - -func TestOrderedKeysRemove(t *testing.T) { - cases := []struct { - v OrderedKeys - rem string - out OrderedKeys - }{ - { - v: []string{"bla"}, - rem: "test", - out: []string{"bla"}, - }, - { - v: []string{"bla"}, - rem: "bla", - out: []string{}, - }, - { - v: []string{"ha", "ga"}, - rem: "ga", - out: []string{"ha"}, - }, - } - - for _, c := range cases { - c.v.Remove(c.rem) - if !reflect.DeepEqual(c.v, c.out) { - t.Fatalf("got: %v, want: %v", c.v, c.out) - } - } -} - func TestParse(t *testing.T) { // parse correct file diff --git a/internal/wireguard/wireguard.go b/internal/wireguard/wireguard.go index b156430..d2a0ae0 100644 --- a/internal/wireguard/wireguard.go +++ b/internal/wireguard/wireguard.go @@ -3,115 +3,30 @@ package wireguard import ( "errors" - "fmt" - "net" "codeberg.org/eduVPN/eduvpn-common/internal/wireguard/ini" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -func availableTCPPort() (int, error) { - tcpaddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") - if err != nil { - return -1, err - } - ltcp, err := net.ListenTCP("tcp", tcpaddr) - if err != nil { - return -1, err - } - defer ltcp.Close() //nolint:errcheck - return ltcp.Addr().(*net.TCPAddr).Port, nil -} - -func availableUDPPort() (int, error) { - udpaddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") - if err != nil { - return -1, err - } - ludp, err := net.ListenUDP("udp", udpaddr) - if err != nil { - return -1, err - } - defer ludp.Close() //nolint:errcheck - return ludp.LocalAddr().(*net.UDPAddr).Port, nil -} - -// Proxy is the proxyguard information -type Proxy struct { - // SourcePort is the source port of the TCP socket - SourcePort int - // ListenPort is the PORT of the udp listener - ListenPort int - // Peer is the hostname/ip:port of the WireGuard peer - Peer string -} - -// Config gets a wireguard config with API config `cfg`, wg key `key` and whether to use proxyguard `proxy` -func Config(cfg string, key *wgtypes.Key, proxy bool) (string, *Proxy, error) { +// Config places a WireGuard key `key` inside of the WireGuard config `cfg` +func Config(cfg string, key *wgtypes.Key) (string, error) { // the key is nil if the client does not accept WireGuard if key == nil { - return "", nil, errors.New("the server sent us a WireGuard profile but the client does not accept WireGuard") - } - - var tcpp int - var udpp int - var err error - var udpl string - - if proxy { - tcpp, err = availableTCPPort() - if err != nil { - return "", nil, err - } - udpp, err = availableUDPPort() - if err != nil { - return "", nil, err - } - udpl = fmt.Sprintf("127.0.0.1:%d", udpp) - } - - rcfg, peer, err := configReplace(cfg, *key, udpl) - if err != nil { - return "", nil, err - } - var retP *Proxy - if proxy { - retP = &Proxy{ - SourcePort: tcpp, - ListenPort: udpp, - Peer: peer, - } + return "", errors.New("the server sent us a WireGuard profile but the client does not accept WireGuard") } - return rcfg, retP, nil -} -// ConfigReplace replaces the wireguard config with our private key and proxy in case of TCP -func configReplace(cfg string, key wgtypes.Key, proxy string) (string, string, error) { // first parse the config secs := ini.Parse(cfg) if secs.Empty() { - return "", "", errors.New("parsed ini is empty") + return "", errors.New("parsed ini is empty") } // find the interface section // and set the private key is, err := secs.Section("Interface") if err != nil { - return "", "", err + return "", err } is.AddOrReplaceKeyValue("PrivateKey", key.String()) - peer := "" - if proxy != "" { - ps, err := secs.Section("Peer") - if err != nil { - return "", "", err - } - peer, err = ps.RemoveKey("ProxyEndpoint") - if err != nil { - return "", "", err - } - ps.AddOrReplaceKeyValue("Endpoint", proxy) - } - - return secs.String(), peer, nil + return secs.String(), nil } diff --git a/internal/wireguard/wireguard_test.go b/internal/wireguard/wireguard_test.go index bd68afb..5092320 100644 --- a/internal/wireguard/wireguard_test.go +++ b/internal/wireguard/wireguard_test.go @@ -8,7 +8,7 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -func TestConfigReplace(t *testing.T) { +func TestConfig(t *testing.T) { k, err := wgtypes.GeneratePrivateKey() if err != nil { t.Fatalf("Failed to generate key for wg config replace: %v", err) @@ -16,7 +16,6 @@ func TestConfigReplace(t *testing.T) { cases := []struct { config string - proxy string want string wantep string werr string @@ -24,10 +23,8 @@ func TestConfigReplace(t *testing.T) { { config: ` `, - want: "", - wantep: "", - proxy: "", - werr: "parsed ini is empty", + want: "", + werr: "parsed ini is empty", }, { config: ` @@ -48,9 +45,7 @@ PrivateKey = %s [interface] [interface2] `, k.String()), - wantep: "", - proxy: "", - werr: "", + werr: "", }, { config: ` @@ -73,23 +68,17 @@ DNS = 9.9.9.9,2620:fe::fe [Peer] PublicKey = AllowedIPs = 0.0.0.0/0,::/0 -Endpoint = 127.0.0.1:1337 +ProxyEndpoint = https://vpn.example.org/example `, k.String()), - wantep: "https://vpn.example.org/example", - proxy: "127.0.0.1:1337", - werr: "", + werr: "", }, } for _, c := range cases { - gcfg, gep, err := configReplace(c.config, k, c.proxy) + gcfg, err := Config(c.config, &k) test.AssertError(t, err, c.werr) if gcfg != c.want { t.Fatalf("Got config: %s, not equal to config: %s", gcfg, c.want) } - - if gep != c.wantep { - t.Fatalf("Got endpoint: %s, not equal to endpoint: %s", gep, c.wantep) - } } } |
