From c3318fb386096170282e831eb3b616a5a7e9dda8 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Wed, 3 Sep 2025 10:13:46 +0200 Subject: Revert "All: Remove ProxyGuard integration" This partially reverts commit 6b939462fb1064abd42e8cb8316700ec844172ea. It keeps the proxyguard functions but leaves GetConfig alone. E.g. no WireGuard config replacing and querying is happening for ProxyGuard. Needed for the Linux client as I have not found a good way to have a daemon with NetworkManager integration --- proxy/proxy.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 proxy/proxy.go (limited to 'proxy') diff --git a/proxy/proxy.go b/proxy/proxy.go new file mode 100644 index 0000000..af0cd89 --- /dev/null +++ b/proxy/proxy.go @@ -0,0 +1,84 @@ +// Package proxy is a wrapper around proxyguard that integrates it with eduvpn-common settings +// - leaves out some options not applicable to the common integration, e.g. fwmark +// - integrates with eduvpn-common's logger +// - integrates eduvpn-common's user agent +package proxy + +import ( + "context" + "fmt" + "log/slog" + + "codeberg.org/eduVPN/proxyguard" + + "codeberg.org/eduVPN/eduvpn-common/i18n/err" + httpw "codeberg.org/eduVPN/eduvpn-common/internal/http" +) + +// Logger is defined here such that we can update the proxyguard logger +type Logger struct{} + +// Logf logs a message with parameters +func (l *Logger) Logf(msg string, params ...any) { + slog.Info("Proxyguard log", "msg", fmt.Sprintf(msg, params...)) +} + +// Log logs a message +func (l *Logger) Log(msg string) { + slog.Info("Proxyguard log", "msg", msg) +} + +// Proxy is the ProxyGuard client with a channel used for restarting +type Proxy struct { + proxyguard.Client + resChan chan struct{} +} + +// NewProxyguard sets up proxyguard for proxied WireGuard connections +func NewProxyguard(ctx context.Context, lp int, tcpsp int, peer string, setupSocket func(fd int)) (*Proxy, error) { + proxyguard.UpdateLogger(&Logger{}) + proxy := Proxy{ + Client: proxyguard.Client{ + Peer: peer, + ListenPort: lp, + TCPSourcePort: tcpsp, + SetupSocket: setupSocket, + UserAgent: httpw.UserAgent, + }, + resChan: make(chan struct{}), + } + _, err := proxy.Setup(ctx) + if err != nil { + return nil, i18nerr.WrapInternal(err, "The ProxyGuard DNS could not be resolved") + } + + return &proxy, nil +} + +// Tunnel tunnels the ProxyGuard connection. `wglisten` is the WireGuard listen port +func (p *Proxy) Tunnel(ctx context.Context, wglisten int) error { + errChan := make(chan error, 1) + gctx, cancel := context.WithCancel(ctx) + go func() { + err := p.Client.Tunnel(gctx, wglisten) + if err != nil { + err = i18nerr.WrapInternal(err, "The VPN proxy exited") + } + errChan <- err + }() + + select { + case err := <-errChan: + cancel() + return err + case <-p.resChan: + cancel() + <-errChan + return p.Tunnel(ctx, wglisten) + } +} + +// Restart restarts the existing ProxyGuard process, for e.g. roaming +func (p *Proxy) Restart() { + p.resChan <- struct{}{} +} -- cgit v1.2.3