Wireguard support for Mullvad and Windscribe (#565)
- `internal/wireguard` client package with unit tests - Implementation works with kernel space or user space if unavailable - `WIREGUARD_PRIVATE_KEY` - `WIREGUARD_ADDRESS` - `WIREGUARD_PRESHARED_KEY` - `WIREGUARD_PORT` - `internal/netlink` package used by `internal/wireguard`
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/firewall"
|
||||
"github.com/qdm12/gluetun/internal/loopstate"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
"github.com/qdm12/gluetun/internal/openvpn"
|
||||
"github.com/qdm12/gluetun/internal/portforward"
|
||||
"github.com/qdm12/gluetun/internal/publicip"
|
||||
@@ -37,6 +38,7 @@ type Loop struct {
|
||||
versionInfo bool
|
||||
// Configurators
|
||||
openvpnConf openvpn.Interface
|
||||
netLinker netlink.NetLinker
|
||||
fw firewallConfigurer
|
||||
routing routing.VPNGetter
|
||||
portForward portforward.StartStopper
|
||||
@@ -67,7 +69,7 @@ const (
|
||||
|
||||
func NewLoop(vpnSettings configuration.VPN,
|
||||
allServers models.AllServers, openvpnConf openvpn.Interface,
|
||||
fw firewallConfigurer, routing routing.VPNGetter,
|
||||
netLinker netlink.NetLinker, fw firewallConfigurer, routing routing.VPNGetter,
|
||||
portForward portforward.StartStopper, starter command.Starter,
|
||||
publicip publicip.Looper, dnsLooper dns.Looper,
|
||||
logger logging.Logger, client *http.Client,
|
||||
@@ -86,6 +88,7 @@ func NewLoop(vpnSettings configuration.VPN,
|
||||
buildInfo: buildInfo,
|
||||
versionInfo: versionInfo,
|
||||
openvpnConf: openvpnConf,
|
||||
netLinker: netLinker,
|
||||
fw: fw,
|
||||
routing: routing,
|
||||
portForward: portForward,
|
||||
|
||||
@@ -30,8 +30,17 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
|
||||
providerConf := provider.New(settings.Provider.Name, allServers, time.Now)
|
||||
|
||||
vpnRunner, serverName, err := setupOpenVPN(ctx, l.fw,
|
||||
l.openvpnConf, providerConf, settings, l.starter, l.logger)
|
||||
var vpnRunner vpnRunner
|
||||
var serverName, vpnInterface string
|
||||
var err error
|
||||
if settings.Type == constants.OpenVPN {
|
||||
vpnInterface = settings.OpenVPN.Interface
|
||||
vpnRunner, serverName, err = setupOpenVPN(ctx, l.fw,
|
||||
l.openvpnConf, providerConf, settings, l.starter, l.logger)
|
||||
} else { // Wireguard
|
||||
vpnInterface = settings.Wireguard.Interface
|
||||
vpnRunner, serverName, err = setupWireguard(ctx, l.netLinker, l.fw, providerConf, settings, l.logger)
|
||||
}
|
||||
if err != nil {
|
||||
l.crashed(ctx, err)
|
||||
continue
|
||||
@@ -40,7 +49,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
portForwarding: settings.Provider.PortForwarding.Enabled,
|
||||
serverName: serverName,
|
||||
portForwarder: providerConf,
|
||||
vpnIntf: settings.OpenVPN.Interface,
|
||||
vpnIntf: vpnInterface,
|
||||
}
|
||||
|
||||
openvpnCtx, openvpnCancel := context.WithCancel(context.Background())
|
||||
|
||||
@@ -17,13 +17,6 @@ type tunnelUpData struct {
|
||||
}
|
||||
|
||||
func (l *Loop) onTunnelUp(ctx context.Context, data tunnelUpData) {
|
||||
vpnDestination, err := l.routing.VPNDestinationIP()
|
||||
if err != nil {
|
||||
l.logger.Warn(err.Error())
|
||||
} else {
|
||||
l.logger.Info("VPN routing IP address: " + vpnDestination.String())
|
||||
}
|
||||
|
||||
if l.dnsLooper.GetSettings().Enabled {
|
||||
_, _ = l.dnsLooper.ApplyStatus(ctx, constants.Running)
|
||||
}
|
||||
@@ -40,7 +33,7 @@ func (l *Loop) onTunnelUp(ctx context.Context, data tunnelUpData) {
|
||||
}
|
||||
}
|
||||
|
||||
err = l.startPortForwarding(ctx, data)
|
||||
err := l.startPortForwarding(ctx, data)
|
||||
if err != nil {
|
||||
l.logger.Error(err.Error())
|
||||
}
|
||||
|
||||
45
internal/vpn/wireguard.go
Normal file
45
internal/vpn/wireguard.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/firewall"
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
"github.com/qdm12/gluetun/internal/provider"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
"github.com/qdm12/gluetun/internal/wireguard"
|
||||
)
|
||||
|
||||
var (
|
||||
errGetServer = errors.New("failed finding a VPN server")
|
||||
errCreateWireguard = errors.New("failed creating Wireguard")
|
||||
)
|
||||
|
||||
// setupWireguard sets Wireguard up using the configurators and settings given.
|
||||
// It returns a serverName for port forwarding (PIA) and an error if it fails.
|
||||
func setupWireguard(ctx context.Context, netlinker netlink.NetLinker,
|
||||
fw firewall.VPNConnectionSetter, providerConf provider.Provider,
|
||||
settings configuration.VPN, logger wireguard.Logger) (
|
||||
wireguarder wireguard.Wireguarder, serverName string, err error) {
|
||||
connection, err := providerConf.GetConnection(settings.Provider.ServerSelection)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%w: %s", errGetServer, err)
|
||||
}
|
||||
|
||||
wireguardSettings := utils.BuildWireguardSettings(connection, settings.Wireguard)
|
||||
|
||||
wireguarder, err = wireguard.New(wireguardSettings, netlinker, logger)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%w: %s", errCreateWireguard, err)
|
||||
}
|
||||
|
||||
err = fw.SetVPNConnection(ctx, connection, settings.Wireguard.Interface)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%w: %s", errFirewall, err)
|
||||
}
|
||||
|
||||
return wireguarder, connection.Hostname, nil
|
||||
}
|
||||
Reference in New Issue
Block a user