Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f04a05b45 |
1
.github/ISSUE_TEMPLATE/bug.yml
vendored
1
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -40,7 +40,6 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: VPN service provider
|
label: VPN service provider
|
||||||
options:
|
options:
|
||||||
- AirVPN
|
|
||||||
- Custom
|
- Custom
|
||||||
- Cyberghost
|
- Cyberghost
|
||||||
- ExpressVPN
|
- ExpressVPN
|
||||||
|
|||||||
3
.github/labels.yml
vendored
3
.github/labels.yml
vendored
@@ -23,9 +23,6 @@
|
|||||||
description: ""
|
description: ""
|
||||||
|
|
||||||
# VPN providers
|
# VPN providers
|
||||||
- name: ":cloud: AirVPN"
|
|
||||||
color: "cfe8d4"
|
|
||||||
description: ""
|
|
||||||
- name: ":cloud: Cyberghost"
|
- name: ":cloud: Cyberghost"
|
||||||
color: "cfe8d4"
|
color: "cfe8d4"
|
||||||
description: ""
|
description: ""
|
||||||
|
|||||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -45,8 +45,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
locale: "US"
|
locale: "US"
|
||||||
level: error
|
level: error
|
||||||
exclude: |
|
|
||||||
./internal/storage/servers.json
|
|
||||||
|
|
||||||
- name: Linting
|
- name: Linting
|
||||||
run: docker build --target lint .
|
run: docker build --target lint .
|
||||||
@@ -128,7 +126,7 @@ jobs:
|
|||||||
run: echo "::set-output name=value::$(git rev-parse --short HEAD)"
|
run: echo "::set-output name=value::$(git rev-parse --short HEAD)"
|
||||||
|
|
||||||
- name: Build and push final image
|
- name: Build and push final image
|
||||||
uses: docker/build-push-action@v3.2.0
|
uses: docker/build-push-action@v3.1.1
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/ppc64le
|
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v6,linux/arm/v7,linux/ppc64le
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|||||||
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@@ -5,11 +5,11 @@
|
|||||||
"name": "Update a VPN provider servers data",
|
"name": "Update a VPN provider servers data",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"cwd": "${workspaceFolder}",
|
"mode": "debug",
|
||||||
"program": "cmd/gluetun/main.go",
|
"program": "cmd/gluetun/main.go",
|
||||||
"args": [
|
"args": [
|
||||||
"update",
|
"update",
|
||||||
"${input:updateMode}",
|
"-enduser",
|
||||||
"-providers",
|
"-providers",
|
||||||
"${input:provider}"
|
"${input:provider}"
|
||||||
],
|
],
|
||||||
@@ -20,16 +20,6 @@
|
|||||||
"id": "provider",
|
"id": "provider",
|
||||||
"type": "promptString",
|
"type": "promptString",
|
||||||
"description": "Please enter a provider (or comma separated list of providers)",
|
"description": "Please enter a provider (or comma separated list of providers)",
|
||||||
},
|
}
|
||||||
{
|
|
||||||
"id": "updateMode",
|
|
||||||
"type": "pickString",
|
|
||||||
"description": "Update mode to use",
|
|
||||||
"options": [
|
|
||||||
"-maintainer",
|
|
||||||
"-enduser"
|
|
||||||
],
|
|
||||||
"default": "-maintainer"
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
ARG ALPINE_VERSION=3.16
|
ARG ALPINE_VERSION=3.16
|
||||||
ARG GO_ALPINE_VERSION=3.16
|
ARG GO_ALPINE_VERSION=3.16
|
||||||
ARG GO_VERSION=1.19
|
ARG GO_VERSION=1.17
|
||||||
ARG XCPUTRANSLATE_VERSION=v0.6.0
|
ARG XCPUTRANSLATE_VERSION=v0.6.0
|
||||||
ARG GOLANGCI_LINT_VERSION=v1.49.0
|
ARG GOLANGCI_LINT_VERSION=v1.49.0
|
||||||
ARG MOCKGEN_VERSION=v1.6.0
|
ARG MOCKGEN_VERSION=v1.6.0
|
||||||
@@ -91,6 +91,7 @@ ENV VPN_SERVICE_PROVIDER=pia \
|
|||||||
OPENVPN_CIPHERS= \
|
OPENVPN_CIPHERS= \
|
||||||
OPENVPN_AUTH= \
|
OPENVPN_AUTH= \
|
||||||
OPENVPN_PROCESS_USER= \
|
OPENVPN_PROCESS_USER= \
|
||||||
|
OPENVPN_IPV6=off \
|
||||||
OPENVPN_CUSTOM_CONFIG= \
|
OPENVPN_CUSTOM_CONFIG= \
|
||||||
# Wireguard
|
# Wireguard
|
||||||
WIREGUARD_PRIVATE_KEY= \
|
WIREGUARD_PRIVATE_KEY= \
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Based on Alpine 3.16 for a small Docker image of 29MB
|
- Based on Alpine 3.16 for a small Docker image of 29MB
|
||||||
- Supports: **AirVPN**, **Cyberghost**, **ExpressVPN**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Perfect Privacy**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **SlickVPN**, **Surfshark**, **TorGuard**, **VPNSecure.me**, **VPNUnlimited**, **Vyprvpn**, **WeVPN**, **Windscribe** servers
|
- Supports: **Cyberghost**, **ExpressVPN**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Perfect Privacy**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **SlickVPN**, **Surfshark**, **TorGuard**, **VPNSecure.me**, **VPNUnlimited**, **Vyprvpn**, **WeVPN**, **Windscribe** servers
|
||||||
- Supports OpenVPN for all providers listed
|
- Supports OpenVPN for all providers listed
|
||||||
- Supports Wireguard both kernelspace and userspace
|
- Supports Wireguard both kernelspace and userspace
|
||||||
- For **Mullvad**, **Ivpn**, **Surfshark** and **Windscribe**
|
- For **Mullvad**, **Ivpn** and **Windscribe**
|
||||||
- For **ProtonVPN**, **PureVPN**, **Torguard**, **VPN Unlimited** and **WeVPN** using [the custom provider](https://github.com/qdm12/gluetun/wiki/Custom-provider)
|
- For **Torguard**, **VPN Unlimited** and **WeVPN** using [the custom provider](https://github.com/qdm12/gluetun/wiki/Custom-provider)
|
||||||
- For custom Wireguard configurations using [the custom provider](https://github.com/qdm12/gluetun/wiki/Custom-provider)
|
- For custom Wireguard configurations using [the custom provider](https://github.com/qdm12/gluetun/wiki/Custom-provider)
|
||||||
- More in progress, see [#134](https://github.com/qdm12/gluetun/issues/134)
|
- More in progress, see [#134](https://github.com/qdm12/gluetun/issues/134)
|
||||||
- DNS over TLS baked in with service provider(s) of your choice
|
- DNS over TLS baked in with service provider(s) of your choice
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import (
|
|||||||
"github.com/qdm12/dns/pkg/unbound"
|
"github.com/qdm12/dns/pkg/unbound"
|
||||||
"github.com/qdm12/gluetun/internal/alpine"
|
"github.com/qdm12/gluetun/internal/alpine"
|
||||||
"github.com/qdm12/gluetun/internal/cli"
|
"github.com/qdm12/gluetun/internal/cli"
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
"github.com/qdm12/gluetun/internal/configuration/sources/env"
|
"github.com/qdm12/gluetun/internal/configuration/sources/env"
|
||||||
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
||||||
mux "github.com/qdm12/gluetun/internal/configuration/sources/merge"
|
"github.com/qdm12/gluetun/internal/configuration/sources/mux"
|
||||||
"github.com/qdm12/gluetun/internal/configuration/sources/secrets"
|
"github.com/qdm12/gluetun/internal/configuration/sources/secrets"
|
||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/dns"
|
"github.com/qdm12/gluetun/internal/dns"
|
||||||
@@ -108,15 +108,11 @@ func main() {
|
|||||||
const shutdownGracePeriod = 5 * time.Second
|
const shutdownGracePeriod = 5 * time.Second
|
||||||
timer := time.NewTimer(shutdownGracePeriod)
|
timer := time.NewTimer(shutdownGracePeriod)
|
||||||
select {
|
select {
|
||||||
case err := <-errorCh:
|
case <-errorCh:
|
||||||
if !timer.Stop() {
|
if !timer.Stop() {
|
||||||
<-timer.C
|
<-timer.C
|
||||||
}
|
}
|
||||||
if err == nil {
|
logger.Info("Shutdown successful")
|
||||||
logger.Info("Shutdown successful")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
logger.Warnf("Shutdown not completed gracefully: %s", err)
|
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
logger.Warn("Shutdown timed out")
|
logger.Warn("Shutdown timed out")
|
||||||
case signal := <-signalCh:
|
case signal := <-signalCh:
|
||||||
@@ -132,7 +128,7 @@ var (
|
|||||||
|
|
||||||
//nolint:gocognit,gocyclo,maintidx
|
//nolint:gocognit,gocyclo,maintidx
|
||||||
func _main(ctx context.Context, buildInfo models.BuildInformation,
|
func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||||
args []string, logger log.LoggerInterface, source Source,
|
args []string, logger log.LoggerInterface, source sources.Source,
|
||||||
tun Tun, netLinker netLinker, cmder command.RunStarter,
|
tun Tun, netLinker netLinker, cmder command.RunStarter,
|
||||||
cli clier) error {
|
cli clier) error {
|
||||||
if len(args) > 1 { // cli operation
|
if len(args) > 1 { // cli operation
|
||||||
@@ -142,7 +138,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
case "clientkey":
|
case "clientkey":
|
||||||
return cli.ClientKey(args[2:])
|
return cli.ClientKey(args[2:])
|
||||||
case "openvpnconfig":
|
case "openvpnconfig":
|
||||||
return cli.OpenvpnConfig(logger, source, netLinker)
|
return cli.OpenvpnConfig(logger, source)
|
||||||
case "update":
|
case "update":
|
||||||
return cli.Update(ctx, args[2:], logger)
|
return cli.Update(ctx, args[2:], logger)
|
||||||
case "format-servers":
|
case "format-servers":
|
||||||
@@ -288,17 +284,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Supported, err := netLinker.IsIPv6Supported()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("checking for IPv6 support: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ipv6Supported {
|
|
||||||
logger.Info("IPv6 is supported")
|
|
||||||
} else {
|
|
||||||
logger.Info("IPv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := routingConf.Setup(); err != nil {
|
if err := routingConf.Setup(); err != nil {
|
||||||
if strings.Contains(err.Error(), "operation not permitted") {
|
if strings.Contains(err.Error(), "operation not permitted") {
|
||||||
logger.Warn("💡 Tip: Are you passing NET_ADMIN capability to gluetun?")
|
logger.Warn("💡 Tip: Are you passing NET_ADMIN capability to gluetun?")
|
||||||
@@ -404,7 +389,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
httpClient, unzipper, parallelResolver, ipFetcher, openvpnFileExtractor)
|
httpClient, unzipper, parallelResolver, ipFetcher, openvpnFileExtractor)
|
||||||
|
|
||||||
vpnLogger := logger.New(log.SetComponent("vpn"))
|
vpnLogger := logger.New(log.SetComponent("vpn"))
|
||||||
vpnLooper := vpn.NewLoop(allSettings.VPN, ipv6Supported, allSettings.Firewall.VPNInputPorts,
|
vpnLooper := vpn.NewLoop(allSettings.VPN, allSettings.Firewall.VPNInputPorts,
|
||||||
providers, storage, ovpnConf, netLinker, firewallConf, routingConf, portForwardLooper,
|
providers, storage, ovpnConf, netLinker, firewallConf, routingConf, portForwardLooper,
|
||||||
cmder, publicIPLooper, unboundLooper, vpnLogger, httpClient,
|
cmder, publicIPLooper, unboundLooper, vpnLogger, httpClient,
|
||||||
buildInfo, *allSettings.Version.Enabled)
|
buildInfo, *allSettings.Version.Enabled)
|
||||||
@@ -509,7 +494,6 @@ type netLinker interface {
|
|||||||
Ruler
|
Ruler
|
||||||
Linker
|
Linker
|
||||||
IsWireguardSupported() (ok bool, err error)
|
IsWireguardSupported() (ok bool, err error)
|
||||||
IsIPv6Supported() (ok bool, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Addresser interface {
|
type Addresser interface {
|
||||||
@@ -545,8 +529,8 @@ type Linker interface {
|
|||||||
type clier interface {
|
type clier interface {
|
||||||
ClientKey(args []string) error
|
ClientKey(args []string) error
|
||||||
FormatServers(args []string) error
|
FormatServers(args []string) error
|
||||||
OpenvpnConfig(logger cli.OpenvpnConfigLogger, source cli.Source, ipv6Checker cli.IPv6Checker) error
|
OpenvpnConfig(logger cli.OpenvpnConfigLogger, source sources.Source) error
|
||||||
HealthCheck(ctx context.Context, source cli.Source, warner cli.Warner) error
|
HealthCheck(ctx context.Context, source sources.Source, warner cli.Warner) error
|
||||||
Update(ctx context.Context, args []string, logger cli.UpdaterLogger) error
|
Update(ctx context.Context, args []string, logger cli.UpdaterLogger) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,9 +538,3 @@ type Tun interface {
|
|||||||
Check(tunDevice string) error
|
Check(tunDevice string) error
|
||||||
Create(tunDevice string) error
|
Create(tunDevice string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Source interface {
|
|
||||||
Read() (settings settings.Settings, err error)
|
|
||||||
ReadHealth() (health settings.Health, err error)
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|||||||
29
go.mod
29
go.mod
@@ -1,9 +1,9 @@
|
|||||||
module github.com/qdm12/gluetun
|
module github.com/qdm12/gluetun
|
||||||
|
|
||||||
go 1.19
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/breml/rootcerts v0.2.8
|
github.com/breml/rootcerts v0.2.6
|
||||||
github.com/fatih/color v1.13.0
|
github.com/fatih/color v1.13.0
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/qdm12/dns v1.11.0
|
github.com/qdm12/dns v1.11.0
|
||||||
@@ -15,25 +15,24 @@ require (
|
|||||||
github.com/qdm12/log v0.1.0
|
github.com/qdm12/log v0.1.0
|
||||||
github.com/qdm12/ss-server v0.4.0
|
github.com/qdm12/ss-server v0.4.0
|
||||||
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e
|
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e
|
||||||
github.com/stretchr/testify v1.8.1
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5
|
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5
|
||||||
golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
|
||||||
golang.org/x/text v0.4.0
|
golang.org/x/text v0.3.7
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
|
golang.zx2c4.com/wireguard v0.0.0-20210805125648-3957e9b9dd19
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c
|
||||||
inet.af/netaddr v0.0.0-20210718074554-06ca8145d722
|
inet.af/netaddr v0.0.0-20210718074554-06ca8145d722
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/google/go-cmp v0.5.7 // indirect
|
github.com/google/go-cmp v0.5.5 // indirect
|
||||||
github.com/josharian/native v1.0.0 // indirect
|
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/mdlayher/genetlink v1.2.0 // indirect
|
github.com/mdlayher/genetlink v1.0.0 // indirect
|
||||||
github.com/mdlayher/netlink v1.6.0 // indirect
|
github.com/mdlayher/netlink v1.4.0 // indirect
|
||||||
github.com/mdlayher/socket v0.2.3 // indirect
|
|
||||||
github.com/miekg/dns v1.1.40 // indirect
|
github.com/miekg/dns v1.1.40 // indirect
|
||||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
@@ -41,8 +40,6 @@ require (
|
|||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
|
||||||
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 // indirect
|
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 // indirect
|
||||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
|
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
|
||||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
111
go.sum
111
go.sum
@@ -4,8 +4,8 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/g
|
|||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/breml/rootcerts v0.2.8 h1:hNPyNa+MghU9ZKqWy+MYxvouNqE70jvOBIa5v70z/P8=
|
github.com/breml/rootcerts v0.2.6 h1:CdPczjzItec+wopLoDsBAFcLEai2q7Yayfg/94/q/2E=
|
||||||
github.com/breml/rootcerts v0.2.8/go.mod h1:24FDtzYMpqIeYC7QzaE8VPRQaFZU5TIUDlyk8qwjD88=
|
github.com/breml/rootcerts v0.2.6/go.mod h1:24FDtzYMpqIeYC7QzaE8VPRQaFZU5TIUDlyk8qwjD88=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@@ -36,16 +36,28 @@ github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3K
|
|||||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gotify/go-api-client/v2 v2.0.4/go.mod h1:VKiah/UK20bXsr0JObE1eBVLW44zbBouzjuri9iwjFU=
|
github.com/gotify/go-api-client/v2 v2.0.4/go.mod h1:VKiah/UK20bXsr0JObE1eBVLW44zbBouzjuri9iwjFU=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
||||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b h1:c3NTyLNozICy8B4mlMXemD3z/gXgQzVXZS/HqT+i3do=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
@@ -61,16 +73,24 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
|
|||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mdlayher/genetlink v1.2.0 h1:4yrIkRV5Wfk1WfpWTcoOlGmsWgQj3OtQN9ZsbrE+XtU=
|
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY=
|
||||||
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
|
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
|
||||||
github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=
|
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||||
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
|
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||||
github.com/mdlayher/socket v0.2.3 h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM=
|
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||||
github.com/mdlayher/socket v0.2.3/go.mod h1:bz12/FozYNH/VbvC3q7TRIK/Y6dH1kCKsXaUeXi/FmY=
|
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||||
|
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||||
|
github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8=
|
||||||
|
github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||||
|
github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||||
|
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
|
||||||
|
github.com/mdlayher/netlink v1.4.0 h1:n3ARR+Fm0dDv37dj5wSWZXDKcy+U0zwcXS3zKMnSiT0=
|
||||||
|
github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8=
|
||||||
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
||||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
|
||||||
|
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
@@ -108,15 +128,13 @@ github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jW
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5 h1:b/k/BVWzWRS5v6AB0gf2ckFSbFsHN5jR0HoNso1pN+w=
|
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5 h1:b/k/BVWzWRS5v6AB0gf2ckFSbFsHN5jR0HoNso1pN+w=
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
github.com/vishvananda/netlink v1.1.1-0.20211129163951-9ada19101fc5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
||||||
@@ -136,60 +154,80 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210504132125-bbd867fde50d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||||
golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA=
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
@@ -201,12 +239,11 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
golang.zx2c4.com/wireguard v0.0.0-20210805125648-3957e9b9dd19 h1:ab2jcw2W91Rz07eHAb8Lic7sFQKO0NhBftjv6m/gL/0=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 h1:vDy//hdR+GnROE3OdYbQKt9rdtNdHkDtONvpRwmls/0=
|
golang.zx2c4.com/wireguard v0.0.0-20210805125648-3957e9b9dd19/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c h1:ADNrRDI5NR23/TUCnEmlLZLt4u9DnZ2nwRkPrAcFvto=
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b h1:9JncmKXcUwE918my+H6xmjBdhK2jM/UTUNXxhRG1BAk=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c/go.mod h1:+1XihzyZUBJcSc5WO9SwNA7v26puQwOEDwanaxfNXPQ=
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b/go.mod h1:yp4gl6zOlnDGOZeWeDfMwQcsdOIQnMdhuPx9mwwWBL4=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
"github.com/qdm12/gluetun/internal/healthcheck"
|
"github.com/qdm12/gluetun/internal/healthcheck"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *CLI) HealthCheck(ctx context.Context, source Source, warner Warner) error {
|
func (c *CLI) HealthCheck(ctx context.Context, source sources.Source, warner Warner) error {
|
||||||
// Extract the health server port from the configuration.
|
// Extract the health server port from the configuration.
|
||||||
config, err := source.ReadHealth()
|
config, err := source.ReadHealth()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
||||||
"github.com/qdm12/gluetun/internal/provider"
|
"github.com/qdm12/gluetun/internal/provider"
|
||||||
@@ -35,12 +36,7 @@ type IPFetcher interface {
|
|||||||
FetchMultiInfo(ctx context.Context, ips []net.IP) (data []ipinfo.Response, err error)
|
FetchMultiInfo(ctx context.Context, ips []net.IP) (data []ipinfo.Response, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPv6Checker interface {
|
func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) error {
|
||||||
IsIPv6Supported() (supported bool, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source Source,
|
|
||||||
ipv6Checker IPv6Checker) error {
|
|
||||||
storage, err := storage.New(logger, constants.ServersData)
|
storage, err := storage.New(logger, constants.ServersData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -55,11 +51,6 @@ func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source Source,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Supported, err := ipv6Checker.IsIPv6Supported()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("checking for IPv6 support: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unused by this CLI command
|
// Unused by this CLI command
|
||||||
unzipper := (Unzipper)(nil)
|
unzipper := (Unzipper)(nil)
|
||||||
client := (*http.Client)(nil)
|
client := (*http.Client)(nil)
|
||||||
@@ -71,14 +62,12 @@ func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source Source,
|
|||||||
providers := provider.NewProviders(storage, time.Now, warner, client,
|
providers := provider.NewProviders(storage, time.Now, warner, client,
|
||||||
unzipper, parallelResolver, ipFetcher, openvpnFileExtractor)
|
unzipper, parallelResolver, ipFetcher, openvpnFileExtractor)
|
||||||
providerConf := providers.Get(*allSettings.VPN.Provider.Name)
|
providerConf := providers.Get(*allSettings.VPN.Provider.Name)
|
||||||
connection, err := providerConf.GetConnection(
|
connection, err := providerConf.GetConnection(allSettings.VPN.Provider.ServerSelection)
|
||||||
allSettings.VPN.Provider.ServerSelection, ipv6Supported)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := providerConf.OpenVPNConfig(connection,
|
lines := providerConf.OpenVPNConfig(connection, allSettings.VPN.OpenVPN)
|
||||||
allSettings.VPN.OpenVPN, ipv6Supported)
|
|
||||||
|
|
||||||
fmt.Println(strings.Join(lines, "\n"))
|
fmt.Println(strings.Join(lines, "\n"))
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ var (
|
|||||||
ErrWireguardEndpointIPNotSet = errors.New("endpoint IP is not set")
|
ErrWireguardEndpointIPNotSet = errors.New("endpoint IP is not set")
|
||||||
ErrWireguardEndpointPortNotAllowed = errors.New("endpoint port is not allowed")
|
ErrWireguardEndpointPortNotAllowed = errors.New("endpoint port is not allowed")
|
||||||
ErrWireguardEndpointPortNotSet = errors.New("endpoint port is not set")
|
ErrWireguardEndpointPortNotSet = errors.New("endpoint port is not set")
|
||||||
ErrWireguardEndpointPortSet = errors.New("endpoint port is set")
|
|
||||||
ErrWireguardInterfaceAddressNotSet = errors.New("interface address is not set")
|
ErrWireguardInterfaceAddressNotSet = errors.New("interface address is not set")
|
||||||
ErrWireguardInterfaceNotValid = errors.New("interface name is not valid")
|
ErrWireguardInterfaceNotValid = errors.New("interface name is not valid")
|
||||||
ErrWireguardPreSharedKeyNotSet = errors.New("pre-shared key is not set")
|
ErrWireguardPreSharedKeyNotSet = errors.New("pre-shared key is not set")
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ type OpenVPN struct {
|
|||||||
// Private Internet Access. It can be set to an
|
// Private Internet Access. It can be set to an
|
||||||
// empty string for other providers.
|
// empty string for other providers.
|
||||||
PIAEncPreset *string
|
PIAEncPreset *string
|
||||||
|
// IPv6 is set to true if IPv6 routing should be
|
||||||
|
// set to be tunnel in OpenVPN, and false otherwise.
|
||||||
|
// It cannot be nil in the internal state.
|
||||||
|
IPv6 *bool // TODO automate like with Wireguard
|
||||||
// MSSFix is the value (1 to 10000) to set for the
|
// MSSFix is the value (1 to 10000) to set for the
|
||||||
// mssfix option for OpenVPN. It is ignored if set to 0.
|
// mssfix option for OpenVPN. It is ignored if set to 0.
|
||||||
// It cannot be nil in the internal state.
|
// It cannot be nil in the internal state.
|
||||||
@@ -95,9 +99,7 @@ func (o OpenVPN) validate(vpnProvider string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isCustom := vpnProvider == providers.Custom
|
isCustom := vpnProvider == providers.Custom
|
||||||
isUserRequired := !isCustom &&
|
isUserRequired := !isCustom && vpnProvider != providers.VPNSecure
|
||||||
vpnProvider != providers.Airvpn &&
|
|
||||||
vpnProvider != providers.VPNSecure
|
|
||||||
|
|
||||||
if isUserRequired && *o.User == "" {
|
if isUserRequired && *o.User == "" {
|
||||||
return ErrOpenVPNUserIsEmpty
|
return ErrOpenVPNUserIsEmpty
|
||||||
@@ -181,7 +183,6 @@ func validateOpenVPNClientCertificate(vpnProvider,
|
|||||||
clientCert string) (err error) {
|
clientCert string) (err error) {
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case
|
case
|
||||||
providers.Airvpn,
|
|
||||||
providers.Cyberghost,
|
providers.Cyberghost,
|
||||||
providers.VPNSecure,
|
providers.VPNSecure,
|
||||||
providers.VPNUnlimited:
|
providers.VPNUnlimited:
|
||||||
@@ -204,7 +205,6 @@ func validateOpenVPNClientCertificate(vpnProvider,
|
|||||||
func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) {
|
func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) {
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case
|
case
|
||||||
providers.Airvpn,
|
|
||||||
providers.Cyberghost,
|
providers.Cyberghost,
|
||||||
providers.VPNUnlimited,
|
providers.VPNUnlimited,
|
||||||
providers.Wevpn:
|
providers.Wevpn:
|
||||||
@@ -254,6 +254,7 @@ func (o *OpenVPN) copy() (copied OpenVPN) {
|
|||||||
EncryptedKey: helpers.CopyStringPtr(o.EncryptedKey),
|
EncryptedKey: helpers.CopyStringPtr(o.EncryptedKey),
|
||||||
KeyPassphrase: helpers.CopyStringPtr(o.KeyPassphrase),
|
KeyPassphrase: helpers.CopyStringPtr(o.KeyPassphrase),
|
||||||
PIAEncPreset: helpers.CopyStringPtr(o.PIAEncPreset),
|
PIAEncPreset: helpers.CopyStringPtr(o.PIAEncPreset),
|
||||||
|
IPv6: helpers.CopyBoolPtr(o.IPv6),
|
||||||
MSSFix: helpers.CopyUint16Ptr(o.MSSFix),
|
MSSFix: helpers.CopyUint16Ptr(o.MSSFix),
|
||||||
Interface: o.Interface,
|
Interface: o.Interface,
|
||||||
ProcessUser: o.ProcessUser,
|
ProcessUser: o.ProcessUser,
|
||||||
@@ -276,6 +277,7 @@ func (o *OpenVPN) mergeWith(other OpenVPN) {
|
|||||||
o.EncryptedKey = helpers.MergeWithStringPtr(o.EncryptedKey, other.EncryptedKey)
|
o.EncryptedKey = helpers.MergeWithStringPtr(o.EncryptedKey, other.EncryptedKey)
|
||||||
o.KeyPassphrase = helpers.MergeWithStringPtr(o.KeyPassphrase, other.KeyPassphrase)
|
o.KeyPassphrase = helpers.MergeWithStringPtr(o.KeyPassphrase, other.KeyPassphrase)
|
||||||
o.PIAEncPreset = helpers.MergeWithStringPtr(o.PIAEncPreset, other.PIAEncPreset)
|
o.PIAEncPreset = helpers.MergeWithStringPtr(o.PIAEncPreset, other.PIAEncPreset)
|
||||||
|
o.IPv6 = helpers.MergeWithBool(o.IPv6, other.IPv6)
|
||||||
o.MSSFix = helpers.MergeWithUint16(o.MSSFix, other.MSSFix)
|
o.MSSFix = helpers.MergeWithUint16(o.MSSFix, other.MSSFix)
|
||||||
o.Interface = helpers.MergeWithString(o.Interface, other.Interface)
|
o.Interface = helpers.MergeWithString(o.Interface, other.Interface)
|
||||||
o.ProcessUser = helpers.MergeWithString(o.ProcessUser, other.ProcessUser)
|
o.ProcessUser = helpers.MergeWithString(o.ProcessUser, other.ProcessUser)
|
||||||
@@ -298,6 +300,7 @@ func (o *OpenVPN) overrideWith(other OpenVPN) {
|
|||||||
o.EncryptedKey = helpers.OverrideWithStringPtr(o.EncryptedKey, other.EncryptedKey)
|
o.EncryptedKey = helpers.OverrideWithStringPtr(o.EncryptedKey, other.EncryptedKey)
|
||||||
o.KeyPassphrase = helpers.OverrideWithStringPtr(o.KeyPassphrase, other.KeyPassphrase)
|
o.KeyPassphrase = helpers.OverrideWithStringPtr(o.KeyPassphrase, other.KeyPassphrase)
|
||||||
o.PIAEncPreset = helpers.OverrideWithStringPtr(o.PIAEncPreset, other.PIAEncPreset)
|
o.PIAEncPreset = helpers.OverrideWithStringPtr(o.PIAEncPreset, other.PIAEncPreset)
|
||||||
|
o.IPv6 = helpers.OverrideWithBool(o.IPv6, other.IPv6)
|
||||||
o.MSSFix = helpers.OverrideWithUint16(o.MSSFix, other.MSSFix)
|
o.MSSFix = helpers.OverrideWithUint16(o.MSSFix, other.MSSFix)
|
||||||
o.Interface = helpers.OverrideWithString(o.Interface, other.Interface)
|
o.Interface = helpers.OverrideWithString(o.Interface, other.Interface)
|
||||||
o.ProcessUser = helpers.OverrideWithString(o.ProcessUser, other.ProcessUser)
|
o.ProcessUser = helpers.OverrideWithString(o.ProcessUser, other.ProcessUser)
|
||||||
@@ -326,6 +329,8 @@ func (o *OpenVPN) setDefaults(vpnProvider string) {
|
|||||||
defaultEncPreset = presets.Strong
|
defaultEncPreset = presets.Strong
|
||||||
}
|
}
|
||||||
o.PIAEncPreset = helpers.DefaultStringPtr(o.PIAEncPreset, defaultEncPreset)
|
o.PIAEncPreset = helpers.DefaultStringPtr(o.PIAEncPreset, defaultEncPreset)
|
||||||
|
|
||||||
|
o.IPv6 = helpers.DefaultBool(o.IPv6, false)
|
||||||
o.MSSFix = helpers.DefaultUint16(o.MSSFix, 0)
|
o.MSSFix = helpers.DefaultUint16(o.MSSFix, 0)
|
||||||
o.Interface = helpers.DefaultString(o.Interface, "tun0")
|
o.Interface = helpers.DefaultString(o.Interface, "tun0")
|
||||||
o.ProcessUser = helpers.DefaultString(o.ProcessUser, "root")
|
o.ProcessUser = helpers.DefaultString(o.ProcessUser, "root")
|
||||||
@@ -371,6 +376,8 @@ func (o OpenVPN) toLinesNode() (node *gotree.Node) {
|
|||||||
node.Appendf("Private Internet Access encryption preset: %s", *o.PIAEncPreset)
|
node.Appendf("Private Internet Access encryption preset: %s", *o.PIAEncPreset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node.Appendf("Tunnel IPv6: %s", helpers.BoolPtrToYesNo(o.IPv6))
|
||||||
|
|
||||||
if *o.MSSFix > 0 {
|
if *o.MSSFix > 0 {
|
||||||
node.Appendf("MSS Fix: %d", *o.MSSFix)
|
node.Appendf("MSS Fix: %d", *o.MSSFix)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,6 @@ func (o OpenVPNSelection) validate(vpnProvider string) (err error) {
|
|||||||
default:
|
default:
|
||||||
var allowedTCP, allowedUDP []uint16
|
var allowedTCP, allowedUDP []uint16
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case providers.Airvpn:
|
|
||||||
allowedTCP = []uint16{
|
|
||||||
53, 80, 443, // IP in 1, 3
|
|
||||||
1194, 2018, 41185, // IP in 1, 2, 3, 4
|
|
||||||
}
|
|
||||||
allowedUDP = []uint16{53, 80, 443, 1194, 2018, 41185}
|
|
||||||
case providers.Ivpn:
|
case providers.Ivpn:
|
||||||
allowedTCP = []uint16{80, 443, 1143}
|
allowedTCP = []uint16{80, 443, 1143}
|
||||||
allowedUDP = []uint16{53, 1194, 2049, 2050}
|
allowedUDP = []uint16{53, 1194, 2049, 2050}
|
||||||
|
|||||||
@@ -30,11 +30,9 @@ func (p *Provider) validate(vpnType string, storage Storage) (err error) {
|
|||||||
validNames = append(validNames, "pia") // Retro-compatibility
|
validNames = append(validNames, "pia") // Retro-compatibility
|
||||||
} else { // Wireguard
|
} else { // Wireguard
|
||||||
validNames = []string{
|
validNames = []string{
|
||||||
providers.Airvpn,
|
|
||||||
providers.Custom,
|
providers.Custom,
|
||||||
providers.Ivpn,
|
providers.Ivpn,
|
||||||
providers.Mullvad,
|
providers.Mullvad,
|
||||||
providers.Surfshark,
|
|
||||||
providers.Windscribe,
|
providers.Windscribe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ func Test_Settings_String(t *testing.T) {
|
|||||||
| ├── User: [not set]
|
| ├── User: [not set]
|
||||||
| ├── Password: [not set]
|
| ├── Password: [not set]
|
||||||
| ├── Private Internet Access encryption preset: strong
|
| ├── Private Internet Access encryption preset: strong
|
||||||
|
| ├── Tunnel IPv6: no
|
||||||
| ├── Network interface: tun0
|
| ├── Network interface: tun0
|
||||||
| ├── Run OpenVPN as: root
|
| ├── Run OpenVPN as: root
|
||||||
| └── Verbosity level: 1
|
| └── Verbosity level: 1
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ func (w Wireguard) validate(vpnProvider string) (err error) {
|
|||||||
providers.Custom,
|
providers.Custom,
|
||||||
providers.Ivpn,
|
providers.Ivpn,
|
||||||
providers.Mullvad,
|
providers.Mullvad,
|
||||||
providers.Surfshark,
|
|
||||||
providers.Windscribe,
|
providers.Windscribe,
|
||||||
) {
|
) {
|
||||||
// do not validate for VPN provider not supporting Wireguard
|
// do not validate for VPN provider not supporting Wireguard
|
||||||
@@ -54,12 +53,6 @@ func (w Wireguard) validate(vpnProvider string) (err error) {
|
|||||||
return fmt.Errorf("private key is not valid: %w", err)
|
return fmt.Errorf("private key is not valid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if vpnProvider == providers.Airvpn {
|
|
||||||
if *w.PreSharedKey == "" {
|
|
||||||
return fmt.Errorf("%w", ErrWireguardPreSharedKeyNotSet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate PreSharedKey
|
// Validate PreSharedKey
|
||||||
if *w.PreSharedKey != "" { // Note: this is optional
|
if *w.PreSharedKey != "" { // Note: this is optional
|
||||||
_, err = wgtypes.ParseKey(*w.PreSharedKey)
|
_, err = wgtypes.ParseKey(*w.PreSharedKey)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type WireguardSelection struct {
|
|||||||
// in the internal state.
|
// in the internal state.
|
||||||
EndpointIP net.IP
|
EndpointIP net.IP
|
||||||
// EndpointPort is a the server port to use for the VPN server.
|
// EndpointPort is a the server port to use for the VPN server.
|
||||||
// It is optional for VPN providers IVPN, Mullvad, Surfshark
|
// It is optional for VPN providers IVPN, Mullvad
|
||||||
// and Windscribe, and compulsory for the others.
|
// and Windscribe, and compulsory for the others.
|
||||||
// When optional, it can be set to 0 to indicate not use
|
// When optional, it can be set to 0 to indicate not use
|
||||||
// a custom endpoint port. It cannot be nil in the internal
|
// a custom endpoint port. It cannot be nil in the internal
|
||||||
@@ -36,9 +36,7 @@ type WireguardSelection struct {
|
|||||||
func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
||||||
// Validate EndpointIP
|
// Validate EndpointIP
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case providers.Airvpn, providers.Ivpn, providers.Mullvad,
|
case providers.Ivpn, providers.Mullvad, providers.Windscribe: // endpoint IP addresses are baked in
|
||||||
providers.Surfshark, providers.Windscribe:
|
|
||||||
// endpoint IP addresses are baked in
|
|
||||||
case providers.Custom:
|
case providers.Custom:
|
||||||
if len(w.EndpointIP) == 0 {
|
if len(w.EndpointIP) == 0 {
|
||||||
return ErrWireguardEndpointIPNotSet
|
return ErrWireguardEndpointIPNotSet
|
||||||
@@ -53,12 +51,7 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
|||||||
if *w.EndpointPort == 0 {
|
if *w.EndpointPort == 0 {
|
||||||
return ErrWireguardEndpointPortNotSet
|
return ErrWireguardEndpointPortNotSet
|
||||||
}
|
}
|
||||||
// EndpointPort cannot be set
|
case providers.Ivpn, providers.Mullvad, providers.Windscribe:
|
||||||
case providers.Surfshark:
|
|
||||||
if *w.EndpointPort != 0 {
|
|
||||||
return ErrWireguardEndpointPortSet
|
|
||||||
}
|
|
||||||
case providers.Airvpn, providers.Ivpn, providers.Mullvad, providers.Windscribe:
|
|
||||||
// EndpointPort is optional and can be 0
|
// EndpointPort is optional and can be 0
|
||||||
if *w.EndpointPort == 0 {
|
if *w.EndpointPort == 0 {
|
||||||
break // no custom endpoint port set
|
break // no custom endpoint port set
|
||||||
@@ -68,8 +61,6 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
|||||||
}
|
}
|
||||||
var allowed []uint16
|
var allowed []uint16
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case providers.Airvpn:
|
|
||||||
allowed = []uint16{1637, 47107}
|
|
||||||
case providers.Ivpn:
|
case providers.Ivpn:
|
||||||
allowed = []uint16{2049, 2050, 53, 30587, 41893, 48574, 58237}
|
allowed = []uint16{2049, 2050, 53, 30587, 41893, 48574, 58237}
|
||||||
case providers.Windscribe:
|
case providers.Windscribe:
|
||||||
@@ -87,9 +78,7 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
|||||||
|
|
||||||
// Validate PublicKey
|
// Validate PublicKey
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case providers.Ivpn, providers.Mullvad,
|
case providers.Ivpn, providers.Mullvad, providers.Windscribe: // public keys are baked in
|
||||||
providers.Surfshark, providers.Windscribe:
|
|
||||||
// public keys are baked in
|
|
||||||
case providers.Custom:
|
case providers.Custom:
|
||||||
if w.PublicKey == "" {
|
if w.PublicKey == "" {
|
||||||
return ErrWireguardPublicKeyNotSet
|
return ErrWireguardPublicKeyNotSet
|
||||||
|
|||||||
20
internal/configuration/sources/env/dns.go
vendored
20
internal/configuration/sources/env/dns.go
vendored
@@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readDNS() (dns settings.DNS, err error) {
|
func (r *Reader) readDNS() (dns settings.DNS, err error) {
|
||||||
dns.ServerAddress, err = s.readDNSServerAddress()
|
dns.ServerAddress, err = r.readDNSServerAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dns, err
|
return dns, err
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ func (s *Source) readDNS() (dns settings.DNS, err error) {
|
|||||||
return dns, fmt.Errorf("environment variable DNS_KEEP_NAMESERVER: %w", err)
|
return dns, fmt.Errorf("environment variable DNS_KEEP_NAMESERVER: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dns.DoT, err = s.readDoT()
|
dns.DoT, err = r.readDoT()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dns, fmt.Errorf("DoT settings: %w", err)
|
return dns, fmt.Errorf("DoT settings: %w", err)
|
||||||
}
|
}
|
||||||
@@ -26,22 +26,22 @@ func (s *Source) readDNS() (dns settings.DNS, err error) {
|
|||||||
return dns, nil
|
return dns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readDNSServerAddress() (address net.IP, err error) {
|
func (r *Reader) readDNSServerAddress() (address net.IP, err error) {
|
||||||
key, value := s.getEnvWithRetro("DNS_ADDRESS", "DNS_PLAINTEXT_ADDRESS")
|
key, s := r.getEnvWithRetro("DNS_ADDRESS", "DNS_PLAINTEXT_ADDRESS")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
address = net.ParseIP(value)
|
address = net.ParseIP(s)
|
||||||
if address == nil {
|
if address == nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w: %s", key, ErrIPAddressParse, value)
|
return nil, fmt.Errorf("environment variable %s: %w: %s", key, ErrIPAddressParse, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove in v4
|
// TODO remove in v4
|
||||||
if !address.Equal(net.IPv4(127, 0, 0, 1)) { //nolint:gomnd
|
if !address.Equal(net.IPv4(127, 0, 0, 1)) { //nolint:gomnd
|
||||||
s.warner.Warn(key + " is set to " + value +
|
r.warner.Warn(key + " is set to " + s +
|
||||||
" so the DNS over TLS (DoT) server will not be used." +
|
" so the DNS over TLS (DoT) server will not be used." +
|
||||||
" The default value changed to 127.0.0.1 so it uses the internal DoT serves." +
|
" The default value changed to 127.0.0.1 so it uses the internal DoT server." +
|
||||||
" If the DoT server fails to start, the IPv4 address of the first plaintext DNS server" +
|
" If the DoT server fails to start, the IPv4 address of the first plaintext DNS server" +
|
||||||
" corresponding to the first DoT provider chosen is used.")
|
" corresponding to the first DoT provider chosen is used.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import (
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readDNSBlacklist() (blacklist settings.DNSBlacklist, err error) {
|
func (r *Reader) readDNSBlacklist() (blacklist settings.DNSBlacklist, err error) {
|
||||||
blacklist.BlockMalicious, err = envToBoolPtr("BLOCK_MALICIOUS")
|
blacklist.BlockMalicious, err = envToBoolPtr("BLOCK_MALICIOUS")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return blacklist, fmt.Errorf("environment variable BLOCK_MALICIOUS: %w", err)
|
return blacklist, fmt.Errorf("environment variable BLOCK_MALICIOUS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blacklist.BlockSurveillance, err = s.readBlockSurveillance()
|
blacklist.BlockSurveillance, err = r.readBlockSurveillance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return blacklist, err
|
return blacklist, err
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,8 @@ func (s *Source) readDNSBlacklist() (blacklist settings.DNSBlacklist, err error)
|
|||||||
return blacklist, nil
|
return blacklist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readBlockSurveillance() (blocked *bool, err error) {
|
func (r *Reader) readBlockSurveillance() (blocked *bool, err error) {
|
||||||
key, value := s.getEnvWithRetro("BLOCK_SURVEILLANCE", "BLOCK_NSA")
|
key, value := r.getEnvWithRetro("BLOCK_SURVEILLANCE", "BLOCK_NSA")
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|||||||
4
internal/configuration/sources/env/dot.go
vendored
4
internal/configuration/sources/env/dot.go
vendored
@@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readDoT() (dot settings.DoT, err error) {
|
func (r *Reader) readDoT() (dot settings.DoT, err error) {
|
||||||
dot.Enabled, err = envToBoolPtr("DOT")
|
dot.Enabled, err = envToBoolPtr("DOT")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dot, fmt.Errorf("environment variable DOT: %w", err)
|
return dot, fmt.Errorf("environment variable DOT: %w", err)
|
||||||
@@ -22,7 +22,7 @@ func (s *Source) readDoT() (dot settings.DoT, err error) {
|
|||||||
return dot, err
|
return dot, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dot.Blacklist, err = s.readDNSBlacklist()
|
dot.Blacklist, err = r.readDNSBlacklist()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dot, err
|
return dot, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readFirewall() (firewall settings.Firewall, err error) {
|
func (r *Reader) readFirewall() (firewall settings.Firewall, err error) {
|
||||||
vpnInputPortStrings := envToCSV("FIREWALL_VPN_INPUT_PORTS")
|
vpnInputPortStrings := envToCSV("FIREWALL_VPN_INPUT_PORTS")
|
||||||
firewall.VPNInputPorts, err = stringsToPorts(vpnInputPortStrings)
|
firewall.VPNInputPorts, err = stringsToPorts(vpnInputPortStrings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -22,7 +22,7 @@ func (s *Source) readFirewall() (firewall settings.Firewall, err error) {
|
|||||||
return firewall, fmt.Errorf("environment variable FIREWALL_INPUT_PORTS: %w", err)
|
return firewall, fmt.Errorf("environment variable FIREWALL_INPUT_PORTS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
outboundSubnetsKey, _ := s.getEnvWithRetro("FIREWALL_OUTBOUND_SUBNETS", "EXTRA_SUBNETS")
|
outboundSubnetsKey, _ := r.getEnvWithRetro("FIREWALL_OUTBOUND_SUBNETS", "EXTRA_SUBNETS")
|
||||||
outboundSubnetStrings := envToCSV(outboundSubnetsKey)
|
outboundSubnetStrings := envToCSV(outboundSubnetsKey)
|
||||||
firewall.OutboundSubnets, err = stringsToIPNets(outboundSubnetStrings)
|
firewall.OutboundSubnets, err = stringsToIPNets(outboundSubnetStrings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
16
internal/configuration/sources/env/health.go
vendored
16
internal/configuration/sources/env/health.go
vendored
@@ -7,18 +7,18 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) ReadHealth() (health settings.Health, err error) {
|
func (r *Reader) ReadHealth() (health settings.Health, err error) {
|
||||||
health.ServerAddress = getCleanedEnv("HEALTH_SERVER_ADDRESS")
|
health.ServerAddress = getCleanedEnv("HEALTH_SERVER_ADDRESS")
|
||||||
_, health.TargetAddress = s.getEnvWithRetro("HEALTH_TARGET_ADDRESS", "HEALTH_ADDRESS_TO_PING")
|
_, health.TargetAddress = r.getEnvWithRetro("HEALTH_TARGET_ADDRESS", "HEALTH_ADDRESS_TO_PING")
|
||||||
|
|
||||||
health.VPN.Initial, err = s.readDurationWithRetro(
|
health.VPN.Initial, err = r.readDurationWithRetro(
|
||||||
"HEALTH_VPN_DURATION_INITIAL",
|
"HEALTH_VPN_DURATION_INITIAL",
|
||||||
"HEALTH_OPENVPN_DURATION_INITIAL")
|
"HEALTH_OPENVPN_DURATION_INITIAL")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return health, err
|
return health, err
|
||||||
}
|
}
|
||||||
|
|
||||||
health.VPN.Addition, err = s.readDurationWithRetro(
|
health.VPN.Addition, err = r.readDurationWithRetro(
|
||||||
"HEALTH_VPN_DURATION_ADDITION",
|
"HEALTH_VPN_DURATION_ADDITION",
|
||||||
"HEALTH_OPENVPN_DURATION_ADDITION")
|
"HEALTH_OPENVPN_DURATION_ADDITION")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -28,14 +28,14 @@ func (s *Source) ReadHealth() (health settings.Health, err error) {
|
|||||||
return health, nil
|
return health, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readDurationWithRetro(envKey, retroEnvKey string) (d *time.Duration, err error) {
|
func (r *Reader) readDurationWithRetro(envKey, retroEnvKey string) (d *time.Duration, err error) {
|
||||||
envKey, value := s.getEnvWithRetro(envKey, retroEnvKey)
|
envKey, s := r.getEnvWithRetro(envKey, retroEnvKey)
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
d = new(time.Duration)
|
d = new(time.Duration)
|
||||||
*d, err = time.ParseDuration(value)
|
*d, err = time.ParseDuration(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", envKey, err)
|
return nil, fmt.Errorf("environment variable %s: %w", envKey, err)
|
||||||
}
|
}
|
||||||
|
|||||||
48
internal/configuration/sources/env/httproxy.go
vendored
48
internal/configuration/sources/env/httproxy.go
vendored
@@ -7,12 +7,12 @@ import (
|
|||||||
"github.com/qdm12/govalid/binary"
|
"github.com/qdm12/govalid/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readHTTPProxy() (httpProxy settings.HTTPProxy, err error) {
|
func (r *Reader) readHTTPProxy() (httpProxy settings.HTTPProxy, err error) {
|
||||||
httpProxy.User = s.readHTTProxyUser()
|
httpProxy.User = r.readHTTProxyUser()
|
||||||
httpProxy.Password = s.readHTTProxyPassword()
|
httpProxy.Password = r.readHTTProxyPassword()
|
||||||
httpProxy.ListeningAddress = s.readHTTProxyListeningAddress()
|
httpProxy.ListeningAddress = r.readHTTProxyListeningAddress()
|
||||||
|
|
||||||
httpProxy.Enabled, err = s.readHTTProxyEnabled()
|
httpProxy.Enabled, err = r.readHTTProxyEnabled()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return httpProxy, err
|
return httpProxy, err
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ func (s *Source) readHTTPProxy() (httpProxy settings.HTTPProxy, err error) {
|
|||||||
return httpProxy, fmt.Errorf("environment variable HTTPPROXY_STEALTH: %w", err)
|
return httpProxy, fmt.Errorf("environment variable HTTPPROXY_STEALTH: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpProxy.Log, err = s.readHTTProxyLog()
|
httpProxy.Log, err = r.readHTTProxyLog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return httpProxy, err
|
return httpProxy, err
|
||||||
}
|
}
|
||||||
@@ -30,38 +30,38 @@ func (s *Source) readHTTPProxy() (httpProxy settings.HTTPProxy, err error) {
|
|||||||
return httpProxy, nil
|
return httpProxy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readHTTProxyUser() (user *string) {
|
func (r *Reader) readHTTProxyUser() (user *string) {
|
||||||
_, value := s.getEnvWithRetro("HTTPPROXY_USER", "PROXY_USER", "TINYPROXY_USER")
|
_, s := r.getEnvWithRetro("HTTPPROXY_USER", "PROXY_USER", "TINYPROXY_USER")
|
||||||
if value != "" {
|
if s != "" {
|
||||||
return &value
|
return &s
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readHTTProxyPassword() (user *string) {
|
func (r *Reader) readHTTProxyPassword() (user *string) {
|
||||||
_, value := s.getEnvWithRetro("HTTPPROXY_PASSWORD", "PROXY_PASSWORD", "TINYPROXY_PASSWORD")
|
_, s := r.getEnvWithRetro("HTTPPROXY_PASSWORD", "PROXY_PASSWORD", "TINYPROXY_PASSWORD")
|
||||||
if value != "" {
|
if s != "" {
|
||||||
return &value
|
return &s
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readHTTProxyListeningAddress() (listeningAddress string) {
|
func (r *Reader) readHTTProxyListeningAddress() (listeningAddress string) {
|
||||||
key, value := s.getEnvWithRetro("HTTPPROXY_LISTENING_ADDRESS", "PROXY_PORT", "TINYPROXY_PORT", "HTTPPROXY_PORT")
|
key, value := r.getEnvWithRetro("HTTPPROXY_LISTENING_ADDRESS", "PROXY_PORT", "TINYPROXY_PORT", "HTTPPROXY_PORT")
|
||||||
if key == "HTTPPROXY_LISTENING_ADDRESS" {
|
if key == "HTTPPROXY_LISTENING_ADDRESS" {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
return ":" + value
|
return ":" + value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readHTTProxyEnabled() (enabled *bool, err error) {
|
func (r *Reader) readHTTProxyEnabled() (enabled *bool, err error) {
|
||||||
key, value := s.getEnvWithRetro("HTTPPROXY", "PROXY", "TINYPROXY")
|
key, s := r.getEnvWithRetro("HTTPPROXY", "PROXY", "TINYPROXY")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled = new(bool)
|
enabled = new(bool)
|
||||||
*enabled, err = binary.Validate(value)
|
*enabled, err = binary.Validate(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
@@ -69,9 +69,9 @@ func (s *Source) readHTTProxyEnabled() (enabled *bool, err error) {
|
|||||||
return enabled, nil
|
return enabled, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readHTTProxyLog() (enabled *bool, err error) {
|
func (r *Reader) readHTTProxyLog() (enabled *bool, err error) {
|
||||||
key, value := s.getEnvWithRetro("HTTPPROXY_LOG", "PROXY_LOG_LEVEL", "TINYPROXY_LOG")
|
key, s := r.getEnvWithRetro("HTTPPROXY_LOG", "PROXY_LOG_LEVEL", "TINYPROXY_LOG")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ func (s *Source) readHTTProxyLog() (enabled *bool, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enabled = new(bool)
|
enabled = new(bool)
|
||||||
*enabled, err = binary.Validate(value, binaryOptions...)
|
*enabled, err = binary.Validate(s, binaryOptions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
|
|||||||
39
internal/configuration/sources/env/openvpn.go
vendored
39
internal/configuration/sources/env/openvpn.go
vendored
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/qdm12/govalid/binary"
|
"github.com/qdm12/govalid/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readOpenVPN() (
|
func (r *Reader) readOpenVPN() (
|
||||||
openVPN settings.OpenVPN, err error) {
|
openVPN settings.OpenVPN, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
err = unsetEnvKeys([]string{"OPENVPN_KEY", "OPENVPN_CERT",
|
err = unsetEnvKeys([]string{"OPENVPN_KEY", "OPENVPN_CERT",
|
||||||
@@ -16,14 +16,14 @@ func (s *Source) readOpenVPN() (
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
openVPN.Version = getCleanedEnv("OPENVPN_VERSION")
|
openVPN.Version = getCleanedEnv("OPENVPN_VERSION")
|
||||||
openVPN.User = s.readOpenVPNUser()
|
openVPN.User = r.readOpenVPNUser()
|
||||||
openVPN.Password = s.readOpenVPNPassword()
|
openVPN.Password = r.readOpenVPNPassword()
|
||||||
confFile := getCleanedEnv("OPENVPN_CUSTOM_CONFIG")
|
confFile := getCleanedEnv("OPENVPN_CUSTOM_CONFIG")
|
||||||
if confFile != "" {
|
if confFile != "" {
|
||||||
openVPN.ConfFile = &confFile
|
openVPN.ConfFile = &confFile
|
||||||
}
|
}
|
||||||
|
|
||||||
ciphersKey, _ := s.getEnvWithRetro("OPENVPN_CIPHERS", "OPENVPN_CIPHER")
|
ciphersKey, _ := r.getEnvWithRetro("OPENVPN_CIPHERS", "OPENVPN_CIPHER")
|
||||||
openVPN.Ciphers = envToCSV(ciphersKey)
|
openVPN.Ciphers = envToCSV(ciphersKey)
|
||||||
|
|
||||||
auth := getCleanedEnv("OPENVPN_AUTH")
|
auth := getCleanedEnv("OPENVPN_AUTH")
|
||||||
@@ -35,18 +35,23 @@ func (s *Source) readOpenVPN() (
|
|||||||
openVPN.Key = envToStringPtr("OPENVPN_KEY")
|
openVPN.Key = envToStringPtr("OPENVPN_KEY")
|
||||||
openVPN.EncryptedKey = envToStringPtr("OPENVPN_ENCRYPTED_KEY")
|
openVPN.EncryptedKey = envToStringPtr("OPENVPN_ENCRYPTED_KEY")
|
||||||
|
|
||||||
openVPN.KeyPassphrase = s.readOpenVPNKeyPassphrase()
|
openVPN.KeyPassphrase = r.readOpenVPNKeyPassphrase()
|
||||||
|
|
||||||
openVPN.PIAEncPreset = s.readPIAEncryptionPreset()
|
openVPN.PIAEncPreset = r.readPIAEncryptionPreset()
|
||||||
|
|
||||||
|
openVPN.IPv6, err = envToBoolPtr("OPENVPN_IPV6")
|
||||||
|
if err != nil {
|
||||||
|
return openVPN, fmt.Errorf("environment variable OPENVPN_IPV6: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
openVPN.MSSFix, err = envToUint16Ptr("OPENVPN_MSSFIX")
|
openVPN.MSSFix, err = envToUint16Ptr("OPENVPN_MSSFIX")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return openVPN, fmt.Errorf("environment variable OPENVPN_MSSFIX: %w", err)
|
return openVPN, fmt.Errorf("environment variable OPENVPN_MSSFIX: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, openVPN.Interface = s.getEnvWithRetro("VPN_INTERFACE", "OPENVPN_INTERFACE")
|
_, openVPN.Interface = r.getEnvWithRetro("VPN_INTERFACE", "OPENVPN_INTERFACE")
|
||||||
|
|
||||||
openVPN.ProcessUser, err = s.readOpenVPNProcessUser()
|
openVPN.ProcessUser, err = r.readOpenVPNProcessUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return openVPN, err
|
return openVPN, err
|
||||||
}
|
}
|
||||||
@@ -64,9 +69,9 @@ func (s *Source) readOpenVPN() (
|
|||||||
return openVPN, nil
|
return openVPN, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOpenVPNUser() (user *string) {
|
func (r *Reader) readOpenVPNUser() (user *string) {
|
||||||
user = new(string)
|
user = new(string)
|
||||||
_, *user = s.getEnvWithRetro("OPENVPN_USER", "USER")
|
_, *user = r.getEnvWithRetro("OPENVPN_USER", "USER")
|
||||||
if *user == "" {
|
if *user == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -76,9 +81,9 @@ func (s *Source) readOpenVPNUser() (user *string) {
|
|||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOpenVPNPassword() (password *string) {
|
func (r *Reader) readOpenVPNPassword() (password *string) {
|
||||||
password = new(string)
|
password = new(string)
|
||||||
_, *password = s.getEnvWithRetro("OPENVPN_PASSWORD", "PASSWORD")
|
_, *password = r.getEnvWithRetro("OPENVPN_PASSWORD", "PASSWORD")
|
||||||
if *password == "" {
|
if *password == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -86,7 +91,7 @@ func (s *Source) readOpenVPNPassword() (password *string) {
|
|||||||
return password
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOpenVPNKeyPassphrase() (passphrase *string) {
|
func (r *Reader) readOpenVPNKeyPassphrase() (passphrase *string) {
|
||||||
passphrase = new(string)
|
passphrase = new(string)
|
||||||
*passphrase = getCleanedEnv("OPENVPN_KEY_PASSPHRASE")
|
*passphrase = getCleanedEnv("OPENVPN_KEY_PASSPHRASE")
|
||||||
if *passphrase == "" {
|
if *passphrase == "" {
|
||||||
@@ -95,8 +100,8 @@ func (s *Source) readOpenVPNKeyPassphrase() (passphrase *string) {
|
|||||||
return passphrase
|
return passphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readPIAEncryptionPreset() (presetPtr *string) {
|
func (r *Reader) readPIAEncryptionPreset() (presetPtr *string) {
|
||||||
_, preset := s.getEnvWithRetro(
|
_, preset := r.getEnvWithRetro(
|
||||||
"PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET",
|
"PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET",
|
||||||
"PIA_ENCRYPTION", "ENCRYPTION")
|
"PIA_ENCRYPTION", "ENCRYPTION")
|
||||||
if preset != "" {
|
if preset != "" {
|
||||||
@@ -105,8 +110,8 @@ func (s *Source) readPIAEncryptionPreset() (presetPtr *string) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOpenVPNProcessUser() (processUser string, err error) {
|
func (r *Reader) readOpenVPNProcessUser() (processUser string, err error) {
|
||||||
key, value := s.getEnvWithRetro("OPENVPN_PROCESS_USER", "OPENVPN_ROOT")
|
key, value := r.getEnvWithRetro("OPENVPN_PROCESS_USER", "OPENVPN_ROOT")
|
||||||
if key == "OPENVPN_PROCESS_USER" {
|
if key == "OPENVPN_PROCESS_USER" {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,32 +10,32 @@ import (
|
|||||||
"github.com/qdm12/govalid/port"
|
"github.com/qdm12/govalid/port"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readOpenVPNSelection() (
|
func (r *Reader) readOpenVPNSelection() (
|
||||||
selection settings.OpenVPNSelection, err error) {
|
selection settings.OpenVPNSelection, err error) {
|
||||||
confFile := getCleanedEnv("OPENVPN_CUSTOM_CONFIG")
|
confFile := getCleanedEnv("OPENVPN_CUSTOM_CONFIG")
|
||||||
if confFile != "" {
|
if confFile != "" {
|
||||||
selection.ConfFile = &confFile
|
selection.ConfFile = &confFile
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.TCP, err = s.readOpenVPNProtocol()
|
selection.TCP, err = r.readOpenVPNProtocol()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return selection, err
|
return selection, err
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.CustomPort, err = s.readOpenVPNCustomPort()
|
selection.CustomPort, err = r.readOpenVPNCustomPort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return selection, err
|
return selection, err
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.PIAEncPreset = s.readPIAEncryptionPreset()
|
selection.PIAEncPreset = r.readPIAEncryptionPreset()
|
||||||
|
|
||||||
return selection, nil
|
return selection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrOpenVPNProtocolNotValid = errors.New("OpenVPN protocol is not valid")
|
var ErrOpenVPNProtocolNotValid = errors.New("OpenVPN protocol is not valid")
|
||||||
|
|
||||||
func (s *Source) readOpenVPNProtocol() (tcp *bool, err error) {
|
func (r *Reader) readOpenVPNProtocol() (tcp *bool, err error) {
|
||||||
envKey, protocol := s.getEnvWithRetro("OPENVPN_PROTOCOL", "PROTOCOL")
|
envKey, protocol := r.getEnvWithRetro("OPENVPN_PROTOCOL", "PROTOCOL")
|
||||||
|
|
||||||
switch strings.ToLower(protocol) {
|
switch strings.ToLower(protocol) {
|
||||||
case "":
|
case "":
|
||||||
@@ -50,14 +50,14 @@ func (s *Source) readOpenVPNProtocol() (tcp *bool, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOpenVPNCustomPort() (customPort *uint16, err error) {
|
func (r *Reader) readOpenVPNCustomPort() (customPort *uint16, err error) {
|
||||||
key, value := s.getEnvWithRetro("VPN_ENDPOINT_PORT", "PORT", "OPENVPN_PORT")
|
key, s := r.getEnvWithRetro("VPN_ENDPOINT_PORT", "PORT", "OPENVPN_PORT")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
customPort = new(uint16)
|
customPort = new(uint16)
|
||||||
*customPort, err = port.Validate(value)
|
*customPort, err = port.Validate(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readPortForward() (
|
func (r *Reader) readPortForward() (
|
||||||
portForwarding settings.PortForwarding, err error) {
|
portForwarding settings.PortForwarding, err error) {
|
||||||
key, _ := s.getEnvWithRetro(
|
key, _ := r.getEnvWithRetro(
|
||||||
"PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING",
|
"PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING",
|
||||||
"PORT_FORWARDING")
|
"PORT_FORWARDING")
|
||||||
portForwarding.Enabled, err = envToBoolPtr(key)
|
portForwarding.Enabled, err = envToBoolPtr(key)
|
||||||
@@ -16,7 +16,7 @@ func (s *Source) readPortForward() (
|
|||||||
return portForwarding, fmt.Errorf("environment variable %s: %w", key, err)
|
return portForwarding, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, value := s.getEnvWithRetro(
|
_, value := r.getEnvWithRetro(
|
||||||
"PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING_STATUS_FILE",
|
"PRIVATE_INTERNET_ACCESS_VPN_PORT_FORWARDING_STATUS_FILE",
|
||||||
"PORT_FORWARDING_STATUS_FILE")
|
"PORT_FORWARDING_STATUS_FILE")
|
||||||
if value != "" {
|
if value != "" {
|
||||||
|
|||||||
31
internal/configuration/sources/env/provider.go
vendored
31
internal/configuration/sources/env/provider.go
vendored
@@ -9,19 +9,19 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readProvider(vpnType string) (provider settings.Provider, err error) {
|
func (r *Reader) readProvider(vpnType string) (provider settings.Provider, err error) {
|
||||||
provider.Name = s.readVPNServiceProvider(vpnType)
|
provider.Name = r.readVPNServiceProvider(vpnType)
|
||||||
var providerName string
|
var providerName string
|
||||||
if provider.Name != nil {
|
if provider.Name != nil {
|
||||||
providerName = *provider.Name
|
providerName = *provider.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.ServerSelection, err = s.readServerSelection(providerName, vpnType)
|
provider.ServerSelection, err = r.readServerSelection(providerName, vpnType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return provider, fmt.Errorf("server selection: %w", err)
|
return provider, fmt.Errorf("server selection: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.PortForwarding, err = s.readPortForward()
|
provider.PortForwarding, err = r.readPortForward()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return provider, fmt.Errorf("port forwarding: %w", err)
|
return provider, fmt.Errorf("port forwarding: %w", err)
|
||||||
}
|
}
|
||||||
@@ -29,20 +29,17 @@ func (s *Source) readProvider(vpnType string) (provider settings.Provider, err e
|
|||||||
return provider, nil
|
return provider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readVPNServiceProvider(vpnType string) (vpnProviderPtr *string) {
|
func (r *Reader) readVPNServiceProvider(vpnType string) (vpnProviderPtr *string) {
|
||||||
_, value := s.getEnvWithRetro("VPN_SERVICE_PROVIDER", "VPNSP")
|
_, s := r.getEnvWithRetro("VPN_SERVICE_PROVIDER", "VPNSP")
|
||||||
if value == "" {
|
s = strings.ToLower(s)
|
||||||
if vpnType != vpn.Wireguard && getCleanedEnv("OPENVPN_CUSTOM_CONFIG") != "" {
|
switch {
|
||||||
// retro compatibility
|
case vpnType != vpn.Wireguard &&
|
||||||
return stringPtr(providers.Custom)
|
getCleanedEnv("OPENVPN_CUSTOM_CONFIG") != "": // retro compatibility
|
||||||
}
|
return stringPtr(providers.Custom)
|
||||||
|
case s == "":
|
||||||
return nil
|
return nil
|
||||||
}
|
case s == "pia": // retro compatibility
|
||||||
|
|
||||||
value = strings.ToLower(value)
|
|
||||||
if value == "pia" { // retro compatibility
|
|
||||||
return stringPtr(providers.PrivateInternetAccess)
|
return stringPtr(providers.PrivateInternetAccess)
|
||||||
}
|
}
|
||||||
|
return stringPtr(s)
|
||||||
return stringPtr(value)
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
internal/configuration/sources/env/publicip.go
vendored
12
internal/configuration/sources/env/publicip.go
vendored
@@ -7,13 +7,13 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readPublicIP() (publicIP settings.PublicIP, err error) {
|
func (r *Reader) readPublicIP() (publicIP settings.PublicIP, err error) {
|
||||||
publicIP.Period, err = readPublicIPPeriod()
|
publicIP.Period, err = readPublicIPPeriod()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return publicIP, err
|
return publicIP, err
|
||||||
}
|
}
|
||||||
|
|
||||||
publicIP.IPFilepath = s.readPublicIPFilepath()
|
publicIP.IPFilepath = r.readPublicIPFilepath()
|
||||||
|
|
||||||
return publicIP, nil
|
return publicIP, nil
|
||||||
}
|
}
|
||||||
@@ -33,10 +33,10 @@ func readPublicIPPeriod() (period *time.Duration, err error) {
|
|||||||
return period, nil
|
return period, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readPublicIPFilepath() (filepath *string) {
|
func (r *Reader) readPublicIPFilepath() (filepath *string) {
|
||||||
_, value := s.getEnvWithRetro("PUBLICIP_FILE", "IP_STATUS_FILE")
|
_, s := r.getEnvWithRetro("PUBLICIP_FILE", "IP_STATUS_FILE")
|
||||||
if value != "" {
|
if s != "" {
|
||||||
return &value
|
return &s
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
39
internal/configuration/sources/env/reader.go
vendored
39
internal/configuration/sources/env/reader.go
vendored
@@ -2,9 +2,12 @@ package env
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Source struct {
|
var _ sources.Source = (*Reader)(nil)
|
||||||
|
|
||||||
|
type Reader struct {
|
||||||
warner Warner
|
warner Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,36 +15,36 @@ type Warner interface {
|
|||||||
Warn(s string)
|
Warn(s string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(warner Warner) *Source {
|
func New(warner Warner) *Reader {
|
||||||
return &Source{
|
return &Reader{
|
||||||
warner: warner,
|
warner: warner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) String() string { return "environment variables" }
|
func (r *Reader) String() string { return "environment variables" }
|
||||||
|
|
||||||
func (s *Source) Read() (settings settings.Settings, err error) {
|
func (r *Reader) Read() (settings settings.Settings, err error) {
|
||||||
settings.VPN, err = s.readVPN()
|
settings.VPN, err = r.readVPN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Firewall, err = s.readFirewall()
|
settings.Firewall, err = r.readFirewall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.System, err = s.readSystem()
|
settings.System, err = r.readSystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Health, err = s.ReadHealth()
|
settings.Health, err = r.ReadHealth()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.HTTPProxy, err = s.readHTTPProxy()
|
settings.HTTPProxy, err = r.readHTTPProxy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
@@ -51,7 +54,7 @@ func (s *Source) Read() (settings settings.Settings, err error) {
|
|||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.PublicIP, err = s.readPublicIP()
|
settings.PublicIP, err = r.readPublicIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
@@ -66,17 +69,17 @@ func (s *Source) Read() (settings settings.Settings, err error) {
|
|||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Shadowsocks, err = s.readShadowsocks()
|
settings.Shadowsocks, err = r.readShadowsocks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.DNS, err = s.readDNS()
|
settings.DNS, err = r.readDNS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.ControlServer, err = s.readControlServer()
|
settings.ControlServer, err = r.readControlServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
@@ -89,8 +92,8 @@ func (s *Source) Read() (settings settings.Settings, err error) {
|
|||||||
return settings, nil
|
return settings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) onRetroActive(oldKey, newKey string) {
|
func (r *Reader) onRetroActive(oldKey, newKey string) {
|
||||||
s.warner.Warn(
|
r.warner.Warn(
|
||||||
"You are using the old environment variable " + oldKey +
|
"You are using the old environment variable " + oldKey +
|
||||||
", please consider changing it to " + newKey)
|
", please consider changing it to " + newKey)
|
||||||
}
|
}
|
||||||
@@ -101,14 +104,14 @@ func (s *Source) onRetroActive(oldKey, newKey string) {
|
|||||||
// and end on returning the value corresponding to the currentKey.
|
// and end on returning the value corresponding to the currentKey.
|
||||||
// Note retroKeys should be in order from oldest to most
|
// Note retroKeys should be in order from oldest to most
|
||||||
// recent retro-compatibility key.
|
// recent retro-compatibility key.
|
||||||
func (s *Source) getEnvWithRetro(currentKey string,
|
func (r *Reader) getEnvWithRetro(currentKey string,
|
||||||
retroKeys ...string) (key, value string) {
|
retroKeys ...string) (key, value string) {
|
||||||
// We check retro-compatibility keys first since
|
// We check retro-compatibility keys first since
|
||||||
// the current key might be set in the Dockerfile.
|
// the current key might be set in the Dockerfile.
|
||||||
for _, key = range retroKeys {
|
for _, key = range retroKeys {
|
||||||
value = getCleanedEnv(key)
|
value = getCleanedEnv(key)
|
||||||
if value != "" {
|
if value != "" {
|
||||||
s.onRetroActive(key, currentKey)
|
r.onRetroActive(key, currentKey)
|
||||||
return key, value
|
return key, value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
internal/configuration/sources/env/server.go
vendored
14
internal/configuration/sources/env/server.go
vendored
@@ -7,13 +7,13 @@ import (
|
|||||||
"github.com/qdm12/govalid/binary"
|
"github.com/qdm12/govalid/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readControlServer() (controlServer settings.ControlServer, err error) {
|
func (r *Reader) readControlServer() (controlServer settings.ControlServer, err error) {
|
||||||
controlServer.Log, err = readControlServerLog()
|
controlServer.Log, err = readControlServerLog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return controlServer, err
|
return controlServer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
controlServer.Address = s.readControlServerAddress()
|
controlServer.Address = r.readControlServerAddress()
|
||||||
|
|
||||||
return controlServer, nil
|
return controlServer, nil
|
||||||
}
|
}
|
||||||
@@ -32,17 +32,17 @@ func readControlServerLog() (enabled *bool, err error) {
|
|||||||
return &log, nil
|
return &log, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readControlServerAddress() (address *string) {
|
func (r *Reader) readControlServerAddress() (address *string) {
|
||||||
key, value := s.getEnvWithRetro("HTTP_CONTROL_SERVER_ADDRESS", "HTTP_CONTROL_SERVER_PORT")
|
key, s := r.getEnvWithRetro("HTTP_CONTROL_SERVER_ADDRESS", "HTTP_CONTROL_SERVER_PORT")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "HTTP_CONTROL_SERVER_ADDRESS" {
|
if key == "HTTP_CONTROL_SERVER_ADDRESS" {
|
||||||
return &value
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
address = new(string)
|
address = new(string)
|
||||||
*address = ":" + value
|
*address = ":" + s
|
||||||
return address
|
return address
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,45 +15,44 @@ var (
|
|||||||
ErrServerNumberNotValid = errors.New("server number is not valid")
|
ErrServerNumberNotValid = errors.New("server number is not valid")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readServerSelection(vpnProvider, vpnType string) (
|
func (r *Reader) readServerSelection(vpnProvider, vpnType string) (
|
||||||
ss settings.ServerSelection, err error) {
|
ss settings.ServerSelection, err error) {
|
||||||
ss.VPN = vpnType
|
ss.VPN = vpnType
|
||||||
|
|
||||||
ss.TargetIP, err = s.readOpenVPNTargetIP()
|
ss.TargetIP, err = r.readOpenVPNTargetIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ss, err
|
return ss, err
|
||||||
}
|
}
|
||||||
|
|
||||||
countriesKey, _ := s.getEnvWithRetro("SERVER_COUNTRIES", "COUNTRY")
|
countriesKey, _ := r.getEnvWithRetro("SERVER_COUNTRIES", "COUNTRY")
|
||||||
ss.Countries = envToCSV(countriesKey)
|
ss.Countries = envToCSV(countriesKey)
|
||||||
if vpnProvider == providers.Cyberghost && len(ss.Countries) == 0 {
|
if vpnProvider == providers.Cyberghost && len(ss.Countries) == 0 {
|
||||||
// Retro-compatibility for Cyberghost using the REGION variable
|
// Retro-compatibility for Cyberghost using the REGION variable
|
||||||
ss.Countries = envToCSV("REGION")
|
ss.Countries = envToCSV("REGION")
|
||||||
if len(ss.Countries) > 0 {
|
if len(ss.Countries) > 0 {
|
||||||
s.onRetroActive("REGION", "SERVER_COUNTRIES")
|
r.onRetroActive("REGION", "SERVER_COUNTRIES")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
regionsKey, _ := s.getEnvWithRetro("SERVER_REGIONS", "REGION")
|
regionsKey, _ := r.getEnvWithRetro("SERVER_REGIONS", "REGION")
|
||||||
ss.Regions = envToCSV(regionsKey)
|
ss.Regions = envToCSV(regionsKey)
|
||||||
|
|
||||||
citiesKey, _ := s.getEnvWithRetro("SERVER_CITIES", "CITY")
|
citiesKey, _ := r.getEnvWithRetro("SERVER_CITIES", "CITY")
|
||||||
ss.Cities = envToCSV(citiesKey)
|
ss.Cities = envToCSV(citiesKey)
|
||||||
|
|
||||||
ss.ISPs = envToCSV("ISP")
|
ss.ISPs = envToCSV("ISP")
|
||||||
|
|
||||||
hostnamesKey, _ := s.getEnvWithRetro("SERVER_HOSTNAMES", "SERVER_HOSTNAME")
|
hostnamesKey, _ := r.getEnvWithRetro("SERVER_HOSTNAMES", "SERVER_HOSTNAME")
|
||||||
ss.Hostnames = envToCSV(hostnamesKey)
|
ss.Hostnames = envToCSV(hostnamesKey)
|
||||||
|
|
||||||
serverNamesKey, _ := s.getEnvWithRetro("SERVER_NAMES", "SERVER_NAME")
|
serverNamesKey, _ := r.getEnvWithRetro("SERVER_NAMES", "SERVER_NAME")
|
||||||
ss.Names = envToCSV(serverNamesKey)
|
ss.Names = envToCSV(serverNamesKey)
|
||||||
|
|
||||||
if csv := getCleanedEnv("SERVER_NUMBER"); csv != "" {
|
if csv := getCleanedEnv("SERVER_NUMBER"); csv != "" {
|
||||||
numbersStrings := strings.Split(csv, ",")
|
numbersStrings := strings.Split(csv, ",")
|
||||||
numbers := make([]uint16, len(numbersStrings))
|
numbers := make([]uint16, len(numbersStrings))
|
||||||
for i, numberString := range numbersStrings {
|
for i, numberString := range numbersStrings {
|
||||||
const base, bitSize = 10, 16
|
number, err := strconv.Atoi(numberString)
|
||||||
number, err := strconv.ParseInt(numberString, base, bitSize)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ss, fmt.Errorf("%w: %s",
|
return ss, fmt.Errorf("%w: %s",
|
||||||
ErrServerNumberNotValid, numberString)
|
ErrServerNumberNotValid, numberString)
|
||||||
@@ -67,7 +66,7 @@ func (s *Source) readServerSelection(vpnProvider, vpnType string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mullvad only
|
// Mullvad only
|
||||||
ss.OwnedOnly, err = s.readOwnedOnly()
|
ss.OwnedOnly, err = r.readOwnedOnly()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ss, err
|
return ss, err
|
||||||
}
|
}
|
||||||
@@ -96,12 +95,12 @@ func (s *Source) readServerSelection(vpnProvider, vpnType string) (
|
|||||||
return ss, fmt.Errorf("environment variable STREAM_ONLY: %w", err)
|
return ss, fmt.Errorf("environment variable STREAM_ONLY: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.OpenVPN, err = s.readOpenVPNSelection()
|
ss.OpenVPN, err = r.readOpenVPNSelection()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ss, err
|
return ss, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.Wireguard, err = s.readWireguardSelection()
|
ss.Wireguard, err = r.readWireguardSelection()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ss, err
|
return ss, err
|
||||||
}
|
}
|
||||||
@@ -113,23 +112,23 @@ var (
|
|||||||
ErrInvalidIP = errors.New("invalid IP address")
|
ErrInvalidIP = errors.New("invalid IP address")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readOpenVPNTargetIP() (ip net.IP, err error) {
|
func (r *Reader) readOpenVPNTargetIP() (ip net.IP, err error) {
|
||||||
envKey, value := s.getEnvWithRetro("VPN_ENDPOINT_IP", "OPENVPN_TARGET_IP")
|
envKey, s := r.getEnvWithRetro("VPN_ENDPOINT_IP", "OPENVPN_TARGET_IP")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = net.ParseIP(value)
|
ip = net.ParseIP(s)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
||||||
envKey, ErrInvalidIP, value)
|
envKey, ErrInvalidIP, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readOwnedOnly() (ownedOnly *bool, err error) {
|
func (r *Reader) readOwnedOnly() (ownedOnly *bool, err error) {
|
||||||
envKey, _ := s.getEnvWithRetro("OWNED_ONLY", "OWNED")
|
envKey, _ := r.getEnvWithRetro("OWNED_ONLY", "OWNED")
|
||||||
ownedOnly, err = envToBoolPtr(envKey)
|
ownedOnly, err = envToBoolPtr(envKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", envKey, err)
|
return nil, fmt.Errorf("environment variable %s: %w", envKey, err)
|
||||||
|
|||||||
@@ -7,25 +7,25 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readShadowsocks() (shadowsocks settings.Shadowsocks, err error) {
|
func (r *Reader) readShadowsocks() (shadowsocks settings.Shadowsocks, err error) {
|
||||||
shadowsocks.Enabled, err = envToBoolPtr("SHADOWSOCKS")
|
shadowsocks.Enabled, err = envToBoolPtr("SHADOWSOCKS")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return shadowsocks, fmt.Errorf("environment variable SHADOWSOCKS: %w", err)
|
return shadowsocks, fmt.Errorf("environment variable SHADOWSOCKS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowsocks.Address = s.readShadowsocksAddress()
|
shadowsocks.Address = r.readShadowsocksAddress()
|
||||||
shadowsocks.LogAddresses, err = envToBoolPtr("SHADOWSOCKS_LOG")
|
shadowsocks.LogAddresses, err = envToBoolPtr("SHADOWSOCKS_LOG")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return shadowsocks, fmt.Errorf("environment variable SHADOWSOCKS_LOG: %w", err)
|
return shadowsocks, fmt.Errorf("environment variable SHADOWSOCKS_LOG: %w", err)
|
||||||
}
|
}
|
||||||
shadowsocks.CipherName = s.readShadowsocksCipher()
|
shadowsocks.CipherName = r.readShadowsocksCipher()
|
||||||
shadowsocks.Password = envToStringPtr("SHADOWSOCKS_PASSWORD")
|
shadowsocks.Password = envToStringPtr("SHADOWSOCKS_PASSWORD")
|
||||||
|
|
||||||
return shadowsocks, nil
|
return shadowsocks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readShadowsocksAddress() (address string) {
|
func (r *Reader) readShadowsocksAddress() (address string) {
|
||||||
key, value := s.getEnvWithRetro("SHADOWSOCKS_LISTENING_ADDRESS", "SHADOWSOCKS_PORT")
|
key, value := r.getEnvWithRetro("SHADOWSOCKS_LISTENING_ADDRESS", "SHADOWSOCKS_PORT")
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ func (s *Source) readShadowsocksAddress() (address string) {
|
|||||||
return ":" + value
|
return ":" + value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readShadowsocksCipher() (cipher string) {
|
func (r *Reader) readShadowsocksCipher() (cipher string) {
|
||||||
_, cipher = s.getEnvWithRetro("SHADOWSOCKS_CIPHER", "SHADOWSOCKS_METHOD")
|
_, cipher = r.getEnvWithRetro("SHADOWSOCKS_CIPHER", "SHADOWSOCKS_METHOD")
|
||||||
return strings.ToLower(cipher)
|
return strings.ToLower(cipher)
|
||||||
}
|
}
|
||||||
|
|||||||
10
internal/configuration/sources/env/system.go
vendored
10
internal/configuration/sources/env/system.go
vendored
@@ -14,13 +14,13 @@ var (
|
|||||||
ErrSystemTimezoneNotValid = errors.New("timezone is not valid")
|
ErrSystemTimezoneNotValid = errors.New("timezone is not valid")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readSystem() (system settings.System, err error) {
|
func (r *Reader) readSystem() (system settings.System, err error) {
|
||||||
system.PUID, err = s.readID("PUID", "UID")
|
system.PUID, err = r.readID("PUID", "UID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return system, err
|
return system, err
|
||||||
}
|
}
|
||||||
|
|
||||||
system.PGID, err = s.readID("PGID", "GID")
|
system.PGID, err = r.readID("PGID", "GID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return system, err
|
return system, err
|
||||||
}
|
}
|
||||||
@@ -32,9 +32,9 @@ func (s *Source) readSystem() (system settings.System, err error) {
|
|||||||
|
|
||||||
var ErrSystemIDNotValid = errors.New("system ID is not valid")
|
var ErrSystemIDNotValid = errors.New("system ID is not valid")
|
||||||
|
|
||||||
func (s *Source) readID(key, retroKey string) (
|
func (r *Reader) readID(key, retroKey string) (
|
||||||
id *uint32, err error) {
|
id *uint32, err error) {
|
||||||
idEnvKey, idString := s.getEnvWithRetro(key, retroKey)
|
idEnvKey, idString := r.getEnvWithRetro(key, retroKey)
|
||||||
if idString == "" {
|
if idString == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ func Test_Reader_readID(t *testing.T) {
|
|||||||
setTestEnv(t, key, testCase.keyValue)
|
setTestEnv(t, key, testCase.keyValue)
|
||||||
setTestEnv(t, retroKey, testCase.retroValue)
|
setTestEnv(t, retroKey, testCase.retroValue)
|
||||||
|
|
||||||
source := &Source{}
|
reader := &Reader{}
|
||||||
id, err := source.readID(key, retroKey)
|
id, err := reader.readID(key, retroKey)
|
||||||
|
|
||||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
8
internal/configuration/sources/env/vpn.go
vendored
8
internal/configuration/sources/env/vpn.go
vendored
@@ -7,20 +7,20 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readVPN() (vpn settings.VPN, err error) {
|
func (r *Reader) readVPN() (vpn settings.VPN, err error) {
|
||||||
vpn.Type = strings.ToLower(getCleanedEnv("VPN_TYPE"))
|
vpn.Type = strings.ToLower(getCleanedEnv("VPN_TYPE"))
|
||||||
|
|
||||||
vpn.Provider, err = s.readProvider(vpn.Type)
|
vpn.Provider, err = r.readProvider(vpn.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vpn, fmt.Errorf("VPN provider: %w", err)
|
return vpn, fmt.Errorf("VPN provider: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
vpn.OpenVPN, err = s.readOpenVPN()
|
vpn.OpenVPN, err = r.readOpenVPN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vpn, fmt.Errorf("OpenVPN: %w", err)
|
return vpn, fmt.Errorf("OpenVPN: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
vpn.Wireguard, err = s.readWireguard()
|
vpn.Wireguard, err = r.readWireguard()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vpn, fmt.Errorf("wireguard: %w", err)
|
return vpn, fmt.Errorf("wireguard: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
11
internal/configuration/sources/env/wireguard.go
vendored
11
internal/configuration/sources/env/wireguard.go
vendored
@@ -8,22 +8,22 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readWireguard() (wireguard settings.Wireguard, err error) {
|
func (r *Reader) readWireguard() (wireguard settings.Wireguard, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
err = unsetEnvKeys([]string{"WIREGUARD_PRIVATE_KEY", "WIREGUARD_PRESHARED_KEY"}, err)
|
err = unsetEnvKeys([]string{"WIREGUARD_PRIVATE_KEY", "WIREGUARD_PRESHARED_KEY"}, err)
|
||||||
}()
|
}()
|
||||||
wireguard.PrivateKey = envToStringPtr("WIREGUARD_PRIVATE_KEY")
|
wireguard.PrivateKey = envToStringPtr("WIREGUARD_PRIVATE_KEY")
|
||||||
wireguard.PreSharedKey = envToStringPtr("WIREGUARD_PRESHARED_KEY")
|
wireguard.PreSharedKey = envToStringPtr("WIREGUARD_PRESHARED_KEY")
|
||||||
_, wireguard.Interface = s.getEnvWithRetro("VPN_INTERFACE", "WIREGUARD_INTERFACE")
|
_, wireguard.Interface = r.getEnvWithRetro("VPN_INTERFACE", "WIREGUARD_INTERFACE")
|
||||||
wireguard.Addresses, err = s.readWireguardAddresses()
|
wireguard.Addresses, err = r.readWireguardAddresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wireguard, err // already wrapped
|
return wireguard, err // already wrapped
|
||||||
}
|
}
|
||||||
return wireguard, nil
|
return wireguard, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readWireguardAddresses() (addresses []net.IPNet, err error) {
|
func (r *Reader) readWireguardAddresses() (addresses []net.IPNet, err error) {
|
||||||
key, addressesCSV := s.getEnvWithRetro("WIREGUARD_ADDRESSES", "WIREGUARD_ADDRESS")
|
key, addressesCSV := r.getEnvWithRetro("WIREGUARD_ADDRESSES", "WIREGUARD_ADDRESS")
|
||||||
if addressesCSV == "" {
|
if addressesCSV == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,6 @@ func (s *Source) readWireguardAddresses() (addresses []net.IPNet, err error) {
|
|||||||
addressStrings := strings.Split(addressesCSV, ",")
|
addressStrings := strings.Split(addressesCSV, ",")
|
||||||
addresses = make([]net.IPNet, len(addressStrings))
|
addresses = make([]net.IPNet, len(addressStrings))
|
||||||
for i, addressString := range addressStrings {
|
for i, addressString := range addressStrings {
|
||||||
addressString = strings.TrimSpace(addressString)
|
|
||||||
ip, ipNet, err := net.ParseCIDR(addressString)
|
ip, ipNet, err := net.ParseCIDR(addressString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import (
|
|||||||
"github.com/qdm12/govalid/port"
|
"github.com/qdm12/govalid/port"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readWireguardSelection() (
|
func (r *Reader) readWireguardSelection() (
|
||||||
selection settings.WireguardSelection, err error) {
|
selection settings.WireguardSelection, err error) {
|
||||||
selection.EndpointIP, err = s.readWireguardEndpointIP()
|
selection.EndpointIP, err = r.readWireguardEndpointIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return selection, err
|
return selection, err
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.EndpointPort, err = s.readWireguardCustomPort()
|
selection.EndpointPort, err = r.readWireguardCustomPort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return selection, err
|
return selection, err
|
||||||
}
|
}
|
||||||
@@ -28,29 +28,29 @@ func (s *Source) readWireguardSelection() (
|
|||||||
|
|
||||||
var ErrIPAddressParse = errors.New("cannot parse IP address")
|
var ErrIPAddressParse = errors.New("cannot parse IP address")
|
||||||
|
|
||||||
func (s *Source) readWireguardEndpointIP() (endpointIP net.IP, err error) {
|
func (r *Reader) readWireguardEndpointIP() (endpointIP net.IP, err error) {
|
||||||
key, value := s.getEnvWithRetro("VPN_ENDPOINT_IP", "WIREGUARD_ENDPOINT_IP")
|
key, s := r.getEnvWithRetro("VPN_ENDPOINT_IP", "WIREGUARD_ENDPOINT_IP")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
endpointIP = net.ParseIP(value)
|
endpointIP = net.ParseIP(s)
|
||||||
if endpointIP == nil {
|
if endpointIP == nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
||||||
key, ErrIPAddressParse, value)
|
key, ErrIPAddressParse, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return endpointIP, nil
|
return endpointIP, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readWireguardCustomPort() (customPort *uint16, err error) {
|
func (r *Reader) readWireguardCustomPort() (customPort *uint16, err error) {
|
||||||
key, value := s.getEnvWithRetro("VPN_ENDPOINT_PORT", "WIREGUARD_ENDPOINT_PORT")
|
key, s := r.getEnvWithRetro("VPN_ENDPOINT_PORT", "WIREGUARD_ENDPOINT_PORT")
|
||||||
if value == "" {
|
if s == "" {
|
||||||
return nil, nil //nolint:nilnil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
customPort = new(uint16)
|
customPort = new(uint16)
|
||||||
*customPort, err = port.Validate(value)
|
*customPort, err = port.Validate(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ package files
|
|||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
|
||||||
func (s *Source) ReadHealth() (settings settings.Health, err error) { return settings, nil }
|
func (r *Reader) ReadHealth() (settings settings.Health, err error) { return settings, nil }
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const (
|
|||||||
openVPNEncryptedKey = "/gluetun/openvpn_encrypted_key"
|
openVPNEncryptedKey = "/gluetun/openvpn_encrypted_key"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readOpenVPN() (settings settings.OpenVPN, err error) {
|
func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) {
|
||||||
settings.Key, err = readPEMFile(OpenVPNClientKeyPath)
|
settings.Key, err = readPEMFile(OpenVPNClientKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("client key: %w", err)
|
return settings, fmt.Errorf("client key: %w", err)
|
||||||
|
|||||||
@@ -2,23 +2,26 @@ package files
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Source struct{}
|
var _ sources.Source = (*Reader)(nil)
|
||||||
|
|
||||||
func New() *Source {
|
type Reader struct{}
|
||||||
return &Source{}
|
|
||||||
|
func New() *Reader {
|
||||||
|
return &Reader{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) String() string { return "files" }
|
func (r *Reader) String() string { return "files" }
|
||||||
|
|
||||||
func (s *Source) Read() (settings settings.Settings, err error) {
|
func (r *Reader) Read() (settings settings.Settings, err error) {
|
||||||
settings.VPN, err = s.readVPN()
|
settings.VPN, err = r.readVPN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.System, err = s.readSystem()
|
settings.System, err = r.readSystem()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readSystem() (system settings.System, err error) {
|
func (r *Reader) readSystem() (system settings.System, err error) {
|
||||||
// TODO timezone from /etc/localtime
|
// TODO timezone from /etc/localtime
|
||||||
return system, nil
|
return system, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Source) readVPN() (vpn settings.VPN, err error) {
|
func (r *Reader) readVPN() (vpn settings.VPN, err error) {
|
||||||
vpn.OpenVPN, err = s.readOpenVPN()
|
vpn.OpenVPN, err = r.readOpenVPN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vpn, fmt.Errorf("OpenVPN: %w", err)
|
return vpn, fmt.Errorf("OpenVPN: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,29 @@
|
|||||||
package merge
|
package mux
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfigSource interface {
|
var _ sources.Source = (*Reader)(nil)
|
||||||
Read() (settings settings.Settings, err error)
|
|
||||||
ReadHealth() (settings settings.Health, err error)
|
type Reader struct {
|
||||||
String() string
|
sources []sources.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
type Source struct {
|
func New(sources ...sources.Source) *Reader {
|
||||||
sources []ConfigSource
|
return &Reader{
|
||||||
}
|
|
||||||
|
|
||||||
func New(sources ...ConfigSource) *Source {
|
|
||||||
return &Source{
|
|
||||||
sources: sources,
|
sources: sources,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) String() string {
|
func (r *Reader) String() string {
|
||||||
sources := make([]string, len(s.sources))
|
sources := make([]string, len(r.sources))
|
||||||
for i := range s.sources {
|
for i := range r.sources {
|
||||||
sources[i] = s.sources[i].String()
|
sources[i] = r.sources[i].String()
|
||||||
}
|
}
|
||||||
return strings.Join(sources, ", ")
|
return strings.Join(sources, ", ")
|
||||||
}
|
}
|
||||||
@@ -34,8 +31,8 @@ func (s *Source) String() string {
|
|||||||
// Read reads the settings for each source, merging unset fields
|
// Read reads the settings for each source, merging unset fields
|
||||||
// with field set by the next source.
|
// with field set by the next source.
|
||||||
// It then set defaults to remaining unset fields.
|
// It then set defaults to remaining unset fields.
|
||||||
func (s *Source) Read() (settings settings.Settings, err error) {
|
func (r *Reader) Read() (settings settings.Settings, err error) {
|
||||||
for _, source := range s.sources {
|
for _, source := range r.sources {
|
||||||
settingsFromSource, err := source.Read()
|
settingsFromSource, err := source.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("reading from %s: %w", source, err)
|
return settings, fmt.Errorf("reading from %s: %w", source, err)
|
||||||
@@ -50,8 +47,8 @@ func (s *Source) Read() (settings settings.Settings, err error) {
|
|||||||
// with field set by the next source.
|
// with field set by the next source.
|
||||||
// It then set defaults to remaining unset fields, and validate
|
// It then set defaults to remaining unset fields, and validate
|
||||||
// all the fields.
|
// all the fields.
|
||||||
func (s *Source) ReadHealth() (settings settings.Health, err error) {
|
func (r *Reader) ReadHealth() (settings settings.Health, err error) {
|
||||||
for _, source := range s.sources {
|
for _, source := range r.sources {
|
||||||
settingsFromSource, err := source.ReadHealth()
|
settingsFromSource, err := source.ReadHealth()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("reading from %s: %w", source, err)
|
return settings, fmt.Errorf("reading from %s: %w", source, err)
|
||||||
@@ -2,4 +2,4 @@ package secrets
|
|||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
|
||||||
func (s *Source) ReadHealth() (settings settings.Health, err error) { return settings, nil }
|
func (r *Reader) ReadHealth() (settings settings.Health, err error) { return settings, nil }
|
||||||
|
|||||||
@@ -2,17 +2,21 @@ package secrets
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/sources"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Source struct{}
|
var _ sources.Source = (*Reader)(nil)
|
||||||
|
|
||||||
func New() *Source {
|
type Reader struct {
|
||||||
return &Source{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) String() string { return "secret files" }
|
func New() *Reader {
|
||||||
|
return &Reader{}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Source) Read() (settings settings.Settings, err error) {
|
func (r *Reader) String() string { return "secret files" }
|
||||||
|
|
||||||
|
func (r *Reader) Read() (settings settings.Settings, err error) {
|
||||||
settings.VPN, err = readVPN()
|
settings.VPN, err = readVPN()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, err
|
return settings, err
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package cli
|
package sources
|
||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
import "github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
|
||||||
type Source interface {
|
type Source interface {
|
||||||
Read() (settings settings.Settings, err error)
|
Read() (settings settings.Settings, err error)
|
||||||
ReadHealth() (health settings.Health, err error)
|
ReadHealth() (settings settings.Health, err error)
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
package openvpn
|
package openvpn
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AES128cbc = "aes-128-cbc"
|
AES128cbc = "aes-128-cbc"
|
||||||
AES192cbc = "aes-192-cbc"
|
AES256cbc = "aes-256-cbc"
|
||||||
AES256cbc = "aes-256-cbc"
|
AES128gcm = "aes-128-gcm"
|
||||||
AES128gcm = "aes-128-gcm"
|
AES256gcm = "aes-256-gcm"
|
||||||
AES192gcm = "aes-192-gcm"
|
|
||||||
AES256gcm = "aes-256-gcm"
|
|
||||||
Chacha20Poly1305 = "chacha20-poly1305"
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package providers
|
|||||||
const (
|
const (
|
||||||
// Custom is the VPN provider name for custom
|
// Custom is the VPN provider name for custom
|
||||||
// VPN configurations.
|
// VPN configurations.
|
||||||
Airvpn = "airvpn"
|
|
||||||
Custom = "custom"
|
Custom = "custom"
|
||||||
Cyberghost = "cyberghost"
|
Cyberghost = "cyberghost"
|
||||||
Example = "example"
|
Example = "example"
|
||||||
@@ -33,7 +32,6 @@ const (
|
|||||||
// All returns all the providers except the custom provider.
|
// All returns all the providers except the custom provider.
|
||||||
func All() []string {
|
func All() []string {
|
||||||
return []string{
|
return []string{
|
||||||
Airvpn,
|
|
||||||
Cyberghost,
|
Cyberghost,
|
||||||
Expressvpn,
|
Expressvpn,
|
||||||
Fastestvpn,
|
Fastestvpn,
|
||||||
|
|||||||
@@ -101,9 +101,6 @@ func (c *Config) enable(ctx context.Context) (err error) {
|
|||||||
if err := c.acceptOutputFromIPToSubnet(ctx, network.InterfaceName, network.IP, *network.IPNet, remove); err != nil {
|
if err := c.acceptOutputFromIPToSubnet(ctx, network.InterfaceName, network.IP, *network.IPNet, remove); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = c.acceptIpv6MulticastOutput(ctx, network.InterfaceName, remove); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = c.allowOutboundSubnets(ctx); err != nil {
|
if err = c.allowOutboundSubnets(ctx); err != nil {
|
||||||
|
|||||||
@@ -179,18 +179,6 @@ func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
|
|||||||
return c.runIP6tablesInstruction(ctx, instruction)
|
return c.runIP6tablesInstruction(ctx, instruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NDP uses multicast address (theres no broadcast in IPv6 like ARP uses in IPv4).
|
|
||||||
func (c *Config) acceptIpv6MulticastOutput(ctx context.Context,
|
|
||||||
intf string, remove bool) error {
|
|
||||||
interfaceFlag := "-o " + intf
|
|
||||||
if intf == "*" { // all interfaces
|
|
||||||
interfaceFlag = ""
|
|
||||||
}
|
|
||||||
instruction := fmt.Sprintf("%s OUTPUT %s -d ff02::1:ff/104 -j ACCEPT",
|
|
||||||
appendOrDelete(remove), interfaceFlag)
|
|
||||||
return c.runIP6tablesInstruction(ctx, instruction)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used for port forwarding, with intf set to tun.
|
// Used for port forwarding, with intf set to tun.
|
||||||
func (c *Config) acceptInputToPort(ctx context.Context, intf string, port uint16, remove bool) error {
|
func (c *Config) acceptInputToPort(ctx context.Context, intf string, port uint16, remove bool) error {
|
||||||
interfaceFlag := "-i " + intf
|
interfaceFlag := "-i " + intf
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package httpproxy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -33,8 +32,7 @@ func (h *handler) isAuthorized(responseWriter http.ResponseWriter, request *http
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if h.username != usernamePassword[0] || h.password != usernamePassword[1] {
|
if h.username != usernamePassword[0] || h.password != usernamePassword[1] {
|
||||||
h.logger.Info(fmt.Sprintf("Username (%q) or password (%q) mismatch from %s",
|
h.logger.Info("Username or password mismatch from " + request.RemoteAddr)
|
||||||
usernamePassword[0], usernamePassword[1], request.RemoteAddr))
|
|
||||||
h.logger.Debug("username provided \"" + usernamePassword[0] +
|
h.logger.Debug("username provided \"" + usernamePassword[0] +
|
||||||
"\" and password provided \"" + usernamePassword[1] + "\"")
|
"\" and password provided \"" + usernamePassword[1] + "\"")
|
||||||
responseWriter.WriteHeader(http.StatusUnauthorized)
|
responseWriter.WriteHeader(http.StatusUnauthorized)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/providers"
|
"github.com/qdm12/gluetun/internal/constants/providers"
|
||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func boolToMarkdown(b bool) string {
|
func boolToMarkdown(b bool) string {
|
||||||
@@ -27,7 +26,6 @@ const (
|
|||||||
hostnameHeader = "Hostname"
|
hostnameHeader = "Hostname"
|
||||||
ispHeader = "ISP"
|
ispHeader = "ISP"
|
||||||
multiHopHeader = "MultiHop"
|
multiHopHeader = "MultiHop"
|
||||||
nameHeader = "Name"
|
|
||||||
numberHeader = "Number"
|
numberHeader = "Number"
|
||||||
ownedHeader = "Owned"
|
ownedHeader = "Owned"
|
||||||
portForwardHeader = "Port forwarding"
|
portForwardHeader = "Port forwarding"
|
||||||
@@ -59,8 +57,6 @@ func (s *Server) ToMarkdown(headers ...string) (markdown string) {
|
|||||||
fields[i] = s.ISP
|
fields[i] = s.ISP
|
||||||
case multiHopHeader:
|
case multiHopHeader:
|
||||||
fields[i] = boolToMarkdown(s.MultiHop)
|
fields[i] = boolToMarkdown(s.MultiHop)
|
||||||
case nameHeader:
|
|
||||||
fields[i] = s.ServerName
|
|
||||||
case numberHeader:
|
case numberHeader:
|
||||||
fields[i] = fmt.Sprint(s.Number)
|
fields[i] = fmt.Sprint(s.Number)
|
||||||
case ownedHeader:
|
case ownedHeader:
|
||||||
@@ -76,7 +72,7 @@ func (s *Server) ToMarkdown(headers ...string) (markdown string) {
|
|||||||
case tcpHeader:
|
case tcpHeader:
|
||||||
fields[i] = boolToMarkdown(s.TCP)
|
fields[i] = boolToMarkdown(s.TCP)
|
||||||
case udpHeader:
|
case udpHeader:
|
||||||
fields[i] = boolToMarkdown(s.UDP || s.VPN == vpn.Wireguard)
|
fields[i] = boolToMarkdown(s.UDP)
|
||||||
case vpnHeader:
|
case vpnHeader:
|
||||||
fields[i] = s.VPN
|
fields[i] = s.VPN
|
||||||
}
|
}
|
||||||
@@ -102,9 +98,6 @@ func (s *Servers) ToMarkdown(vpnProvider string) (markdown string) {
|
|||||||
|
|
||||||
func getMarkdownHeaders(vpnProvider string) (headers []string) {
|
func getMarkdownHeaders(vpnProvider string) (headers []string) {
|
||||||
switch vpnProvider {
|
switch vpnProvider {
|
||||||
case providers.Airvpn:
|
|
||||||
return []string{regionHeader, countryHeader, cityHeader, vpnHeader,
|
|
||||||
udpHeader, tcpHeader, hostnameHeader, nameHeader}
|
|
||||||
case providers.Cyberghost:
|
case providers.Cyberghost:
|
||||||
return []string{countryHeader, hostnameHeader, tcpHeader, udpHeader}
|
return []string{countryHeader, hostnameHeader, tcpHeader, udpHeader}
|
||||||
case providers.Expressvpn:
|
case providers.Expressvpn:
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ var (
|
|||||||
ErrVPNFieldEmpty = errors.New("vpn field is empty")
|
ErrVPNFieldEmpty = errors.New("vpn field is empty")
|
||||||
ErrHostnameFieldEmpty = errors.New("hostname field is empty")
|
ErrHostnameFieldEmpty = errors.New("hostname field is empty")
|
||||||
ErrIPsFieldEmpty = errors.New("ips field is empty")
|
ErrIPsFieldEmpty = errors.New("ips field is empty")
|
||||||
ErrNoNetworkProtocol = errors.New("both TCP and UDP fields are false for OpenVPN")
|
ErrNoNetworkProtocol = errors.New("both TCP and UDP fields are false")
|
||||||
ErrNetworkProtocolSet = errors.New("no network protocol should be set")
|
|
||||||
ErrWireguardPublicKeyEmpty = errors.New("wireguard public key field is empty")
|
ErrWireguardPublicKeyEmpty = errors.New("wireguard public key field is empty")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,9 +51,7 @@ func (s *Server) HasMinimumInformation() (err error) {
|
|||||||
return ErrHostnameFieldEmpty
|
return ErrHostnameFieldEmpty
|
||||||
case len(s.IPs) == 0:
|
case len(s.IPs) == 0:
|
||||||
return ErrIPsFieldEmpty
|
return ErrIPsFieldEmpty
|
||||||
case s.VPN == vpn.Wireguard && (s.TCP || s.UDP):
|
case !s.TCP && !s.UDP:
|
||||||
return ErrNetworkProtocolSet
|
|
||||||
case s.VPN == vpn.OpenVPN && !s.TCP && !s.UDP:
|
|
||||||
return ErrNoNetworkProtocol
|
return ErrNoNetworkProtocol
|
||||||
case s.VPN == vpn.Wireguard && s.WgPubKey == "":
|
case s.VPN == vpn.Wireguard && s.WgPubKey == "":
|
||||||
return ErrWireguardPublicKeyEmpty
|
return ErrWireguardPublicKeyEmpty
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
package netlink
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *NetLink) IsIPv6Supported() (supported bool, err error) {
|
|
||||||
links, err := n.LinkList()
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("listing links: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, link := range links {
|
|
||||||
routes, err := n.RouteList(link, netlink.FAMILY_V6)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("listing IPv6 routes for link %s: %w",
|
|
||||||
link.Attrs().Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(routes) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
@@ -81,7 +81,7 @@ func extractProto(line string) (protocol string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch fields[1] {
|
switch fields[1] {
|
||||||
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
|
case "tcp", "udp":
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("%w: %s", errProtocolNotSupported, fields[1])
|
return "", fmt.Errorf("%w: %s", errProtocolNotSupported, fields[1])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
package airvpn
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
|
||||||
connection models.Connection, err error) {
|
|
||||||
defaults := utils.NewConnectionDefaults(443, 1194, 1637) //nolint:gomnd
|
|
||||||
return utils.GetConnection(p.Name(),
|
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package airvpn
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
|
||||||
AuthUserPass: true,
|
|
||||||
RemoteCertTLS: true,
|
|
||||||
Auth: openvpn.SHA512,
|
|
||||||
CA: "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", //nolint:lll
|
|
||||||
TLSCrypt: "a3a7d8f4e778d279d9076a8d47a9aa0c6054aed5752ddefa5efac1ea982740f1ffcabadf0d3709dae18c1fad61e14f72a8eb7cb931ed0209e67c1d325353a657a1198ef649f1c23861a2a19f2c6b27aa5e43be761e0c71e9c2e8d33b75af289effb1b1e4ec603d865f74e2b4348ff631c5c81202d90003ed263dca4022aa9861520e00cc26e40fa171b9985a2763ccb4c63560b7e6b0f897978fb25a2d5889cd6d46a29509fa09830aff18d6e81a8dc1a0182402e3039c3316180e618705ca35f2763f8a62ca5983d145faa2276532ae5e18459a0b729dc67f41b928e592b39467ec3d79c70205595718b1bce56ca4ff58e692ce09c8282d2770d2bf5c217c06", //nolint:lll
|
|
||||||
ExtraLines: []string{
|
|
||||||
"comp-lzo no", // Explicitly disable compression
|
|
||||||
"push-peer-info",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
switch settings.Version {
|
|
||||||
case openvpn.Openvpn24:
|
|
||||||
providerSettings.Ciphers = []string{openvpn.AES256cbc}
|
|
||||||
case openvpn.Openvpn25:
|
|
||||||
providerSettings.Ciphers = []string{
|
|
||||||
openvpn.AES256gcm, openvpn.AES256cbc, openvpn.AES192gcm,
|
|
||||||
openvpn.AES192cbc, openvpn.AES128gcm, openvpn.AES128cbc,
|
|
||||||
openvpn.Chacha20Poly1305}
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("openvpn version %q is not implemented", settings.Version))
|
|
||||||
}
|
|
||||||
|
|
||||||
providerSettings.SetEnv = map[string]string{"UV_IPV6": "no"}
|
|
||||||
if ipv6Supported {
|
|
||||||
providerSettings.SetEnv["UV_IPV6"] = "yes"
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package airvpn
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/providers"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/airvpn/updater"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Provider struct {
|
|
||||||
storage common.Storage
|
|
||||||
randSource rand.Source
|
|
||||||
utils.NoPortForwarder
|
|
||||||
common.Fetcher
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(storage common.Storage, randSource rand.Source,
|
|
||||||
client *http.Client) *Provider {
|
|
||||||
return &Provider{
|
|
||||||
storage: storage,
|
|
||||||
randSource: randSource,
|
|
||||||
NoPortForwarder: utils.NewNoPortForwarding(providers.Example),
|
|
||||||
Fetcher: updater.New(client),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) Name() string {
|
|
||||||
return providers.Airvpn
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package updater
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type apiData struct {
|
|
||||||
Servers []apiServer `json:"servers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiServer struct {
|
|
||||||
PublicName string `json:"public_name"`
|
|
||||||
CountryName string `json:"country_name"`
|
|
||||||
CountryCode string `json:"country_code"`
|
|
||||||
Location string `json:"location"`
|
|
||||||
Continent string `json:"continent"`
|
|
||||||
IPv4In1 net.IP `json:"ip_v4_in1"`
|
|
||||||
IPv4In2 net.IP `json:"ip_v4_in2"`
|
|
||||||
IPv4In3 net.IP `json:"ip_v4_in3"`
|
|
||||||
IPv4In4 net.IP `json:"ip_v4_in4"`
|
|
||||||
IPv6In1 net.IP `json:"ip_v6_in1"`
|
|
||||||
IPv6In2 net.IP `json:"ip_v6_in2"`
|
|
||||||
IPv6In3 net.IP `json:"ip_v6_in3"`
|
|
||||||
IPv6In4 net.IP `json:"ip_v6_in4"`
|
|
||||||
Health string `json:"health"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchAPI(ctx context.Context, client *http.Client) (
|
|
||||||
data apiData, err error) {
|
|
||||||
const url = "https://airvpn.org/api/status/"
|
|
||||||
|
|
||||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return data, fmt.Errorf("creating HTTP request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := client.Do(request)
|
|
||||||
if err != nil {
|
|
||||||
return data, fmt.Errorf("doing HTTP request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if response.StatusCode != http.StatusOK {
|
|
||||||
_ = response.Body.Close()
|
|
||||||
return data, fmt.Errorf("%w: %d %s",
|
|
||||||
common.ErrHTTPStatusCodeNotOK, response.StatusCode, response.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder := json.NewDecoder(response.Body)
|
|
||||||
if err := decoder.Decode(&data); err != nil {
|
|
||||||
_ = response.Body.Close()
|
|
||||||
return data, fmt.Errorf("unmarshaling response body: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := response.Body.Close(); err != nil {
|
|
||||||
return data, fmt.Errorf("closing response body: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package updater
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
|
||||||
servers []models.Server, err error) {
|
|
||||||
data, err := fetchAPI(ctx, u.client)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("fetching API: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// every API server model has:
|
|
||||||
// - Wireguard server using IPv4In1
|
|
||||||
// - Wiregard server using IPv6In1
|
|
||||||
// - OpenVPN TCP+UDP+SSH+SSL server with tls-auth using IPv4In1 and IPv6In1
|
|
||||||
// - OpenVPN TCP+UDP+SSH+SSL server with tls-auth using IPv4In2 and IPv6In2
|
|
||||||
// - OpenVPN TCP+UDP+SSH+SSL server with tls-crypt using IPv4In3 and IPv6In3
|
|
||||||
// - OpenVPN TCP+UDP+SSH+SSL server with tls-crypt using IPv6In4 and IPv6In4
|
|
||||||
const numberOfServersPerAPIServer = 1 + // Wireguard server using IPv4In1
|
|
||||||
1 + // Wiregard server using IPv6In1
|
|
||||||
4 + // OpenVPN TCP server with tls-auth using IPv4In3, IPv6In3, IPv4In4, IPv6In4
|
|
||||||
4 // OpenVPN UDP server with tls-auth using IPv4In3, IPv6In3, IPv4In4, IPv6In4
|
|
||||||
projectedNumberOfServers := numberOfServersPerAPIServer * len(data.Servers)
|
|
||||||
|
|
||||||
if projectedNumberOfServers < minServers {
|
|
||||||
return nil, fmt.Errorf("%w: %d and expected at least %d",
|
|
||||||
common.ErrNotEnoughServers, projectedNumberOfServers, minServers)
|
|
||||||
}
|
|
||||||
|
|
||||||
servers = make([]models.Server, 0, projectedNumberOfServers)
|
|
||||||
for _, apiServer := range data.Servers {
|
|
||||||
if apiServer.Health != "ok" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
baseServer := models.Server{
|
|
||||||
ServerName: apiServer.PublicName,
|
|
||||||
Country: apiServer.CountryName,
|
|
||||||
City: apiServer.Location,
|
|
||||||
Region: apiServer.Continent,
|
|
||||||
}
|
|
||||||
|
|
||||||
baseWireguardServer := baseServer
|
|
||||||
baseWireguardServer.VPN = vpn.Wireguard
|
|
||||||
baseWireguardServer.WgPubKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk="
|
|
||||||
|
|
||||||
ipv4WireguadServer := baseWireguardServer
|
|
||||||
ipv4WireguadServer.IPs = []net.IP{apiServer.IPv4In1}
|
|
||||||
ipv4WireguadServer.Hostname = apiServer.CountryCode + ".vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv4WireguadServer)
|
|
||||||
|
|
||||||
ipv6WireguadServer := baseWireguardServer
|
|
||||||
ipv6WireguadServer.IPs = []net.IP{apiServer.IPv6In1}
|
|
||||||
ipv6WireguadServer.Hostname = apiServer.CountryCode + ".ipv6.vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv6WireguadServer)
|
|
||||||
|
|
||||||
baseOpenVPNServer := baseServer
|
|
||||||
baseOpenVPNServer.VPN = vpn.OpenVPN
|
|
||||||
baseOpenVPNServer.UDP = true
|
|
||||||
baseOpenVPNServer.TCP = true
|
|
||||||
|
|
||||||
// Ignore IPs 1 and 2 since tls-crypt is superior to tls-auth really.
|
|
||||||
|
|
||||||
ipv4In3OpenVPNServer := baseOpenVPNServer
|
|
||||||
ipv4In3OpenVPNServer.IPs = []net.IP{apiServer.IPv4In3}
|
|
||||||
ipv4In3OpenVPNServer.Hostname = apiServer.CountryCode + "3.vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv4In3OpenVPNServer)
|
|
||||||
|
|
||||||
ipv6In3OpenVPNServer := baseOpenVPNServer
|
|
||||||
ipv6In3OpenVPNServer.IPs = []net.IP{apiServer.IPv6In3}
|
|
||||||
ipv6In3OpenVPNServer.Hostname = apiServer.CountryCode + "3.ipv6.vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv6In3OpenVPNServer)
|
|
||||||
|
|
||||||
ipv4In4OpenVPNServer := baseOpenVPNServer
|
|
||||||
ipv4In4OpenVPNServer.IPs = []net.IP{apiServer.IPv4In4}
|
|
||||||
ipv4In4OpenVPNServer.Hostname = apiServer.CountryCode + "4.vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv4In4OpenVPNServer)
|
|
||||||
|
|
||||||
ipv6In4OpenVPNServer := baseOpenVPNServer
|
|
||||||
ipv6In4OpenVPNServer.IPs = []net.IP{apiServer.IPv6In4}
|
|
||||||
ipv6In4OpenVPNServer.Hostname = apiServer.CountryCode + "4.ipv6.vpn.airdns.org"
|
|
||||||
servers = append(servers, ipv6In4OpenVPNServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(models.SortableServers(servers))
|
|
||||||
|
|
||||||
return servers, nil
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package updater
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Updater struct {
|
|
||||||
client *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client) *Updater {
|
|
||||||
return &Updater{
|
|
||||||
client: client,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,10 +10,7 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var ErrNotEnoughServers = errors.New("not enough servers found")
|
||||||
ErrNotEnoughServers = errors.New("not enough servers found")
|
|
||||||
ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Fetcher interface {
|
type Fetcher interface {
|
||||||
FetchServers(ctx context.Context, minServers int) (servers []models.Server, err error)
|
FetchServers(ctx context.Context, minServers int) (servers []models.Server, err error)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GetConnection gets the connection from the OpenVPN configuration file.
|
// GetConnection gets the connection from the OpenVPN configuration file.
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
switch selection.VPN {
|
switch selection.VPN {
|
||||||
case vpn.OpenVPN:
|
case vpn.OpenVPN:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
var ErrExtractData = errors.New("failed extracting information from custom configuration file")
|
var ErrExtractData = errors.New("failed extracting information from custom configuration file")
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
lines, _, err := p.extractor.Data(*settings.ConfFile)
|
lines, _, err := p.extractor.Data(*settings.ConfFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Configuration file is already validated in settings validation in
|
// Configuration file is already validated in settings validation in
|
||||||
@@ -24,13 +24,13 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
panic(fmt.Sprintf("failed extracting information from custom configuration file: %s", err))
|
panic(fmt.Sprintf("failed extracting information from custom configuration file: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
lines = modifyConfig(lines, connection, settings, ipv6Supported)
|
lines = modifyConfig(lines, connection, settings)
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyConfig(lines []string, connection models.Connection,
|
func modifyConfig(lines []string, connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (modified []string) {
|
settings settings.OpenVPN) (modified []string) {
|
||||||
// Remove some lines
|
// Remove some lines
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
switch {
|
switch {
|
||||||
@@ -57,7 +57,7 @@ func modifyConfig(lines []string, connection models.Connection,
|
|||||||
"cipher ", "ncp-ciphers ", "data-ciphers ", "data-ciphers-fallback "),
|
"cipher ", "ncp-ciphers ", "data-ciphers ", "data-ciphers-fallback "),
|
||||||
*settings.Auth != "" && strings.HasPrefix(line, "auth "),
|
*settings.Auth != "" && strings.HasPrefix(line, "auth "),
|
||||||
*settings.MSSFix > 0 && strings.HasPrefix(line, "mssfix "),
|
*settings.MSSFix > 0 && strings.HasPrefix(line, "mssfix "),
|
||||||
!ipv6Supported && hasPrefixOneOf(line, "tun-ipv6",
|
!*settings.IPv6 && hasPrefixOneOf(line, "tun-ipv6",
|
||||||
`pull-filter ignore "route-ipv6"`,
|
`pull-filter ignore "route-ipv6"`,
|
||||||
`pull-filter ignore "ifconfig-ipv6"`):
|
`pull-filter ignore "ifconfig-ipv6"`):
|
||||||
default:
|
default:
|
||||||
@@ -87,7 +87,7 @@ func modifyConfig(lines []string, connection models.Connection,
|
|||||||
if *settings.MSSFix > 0 {
|
if *settings.MSSFix > 0 {
|
||||||
modified = append(modified, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
|
modified = append(modified, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
|
||||||
}
|
}
|
||||||
if !ipv6Supported {
|
if !*settings.IPv6 {
|
||||||
modified = append(modified, `pull-filter ignore "route-ipv6"`)
|
modified = append(modified, `pull-filter ignore "route-ipv6"`)
|
||||||
modified = append(modified, `pull-filter ignore "ifconfig-ipv6"`)
|
modified = append(modified, `pull-filter ignore "ifconfig-ipv6"`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,10 @@ func Test_modifyConfig(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
lines []string
|
lines []string
|
||||||
settings settings.OpenVPN
|
settings settings.OpenVPN
|
||||||
connection models.Connection
|
connection models.Connection
|
||||||
ipv6Supported bool
|
modified []string
|
||||||
modified []string
|
|
||||||
}{
|
}{
|
||||||
"mixed": {
|
"mixed": {
|
||||||
lines: []string{
|
lines: []string{
|
||||||
@@ -50,7 +49,6 @@ func Test_modifyConfig(t *testing.T) {
|
|||||||
Port: 1194,
|
Port: 1194,
|
||||||
Protocol: constants.UDP,
|
Protocol: constants.UDP,
|
||||||
},
|
},
|
||||||
ipv6Supported: false,
|
|
||||||
modified: []string{
|
modified: []string{
|
||||||
"up bla",
|
"up bla",
|
||||||
"keep me here",
|
"keep me here",
|
||||||
@@ -84,7 +82,7 @@ func Test_modifyConfig(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
modified := modifyConfig(testCase.lines,
|
modified := modifyConfig(testCase.lines,
|
||||||
testCase.connection, testCase.settings, testCase.ipv6Supported)
|
testCase.connection, testCase.settings)
|
||||||
|
|
||||||
assert.Equal(t, testCase.modified, modified)
|
assert.Equal(t, testCase.modified, modified)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
RemoteCertTLS: true,
|
RemoteCertTLS: true,
|
||||||
@@ -22,5 +22,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
Ping: 10,
|
Ping: 10,
|
||||||
CA: "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", //nolint:lll
|
CA: "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", //nolint:lll
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import "github.com/qdm12/gluetun/internal/constants"
|
|||||||
|
|
||||||
func getGroupIDToProtocol() map[string]string {
|
func getGroupIDToProtocol() map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"87-1": constants.UDP, // Premium UDP
|
"87-1": constants.UDP, // Premium UDP Europe
|
||||||
"87-8": constants.UDP, // NoSpy UDP
|
"94-1": constants.UDP, // Premium UDP USA
|
||||||
"87-19": constants.UDP, // Gaming UDP
|
"95-1": constants.UDP, // Premium UDP Asia
|
||||||
"97-1": constants.TCP, // Premium TCP
|
"87-8": constants.UDP, // NoSpy UDP Europe
|
||||||
"97-8": constants.TCP, // NoSpy TCP
|
"97-1": constants.TCP, // Premium TCP Europe
|
||||||
"97-19": constants.TCP, // Gaming TCP
|
"93-1": constants.TCP, // Premium TCP USA
|
||||||
|
"96-1": constants.TCP, // Premium TCP Asia
|
||||||
|
"97-8": constants.TCP, // NoSpy TCP Europe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
// TODO: Set the default ports for each VPN protocol+network protocol
|
// TODO: Set the default ports for each VPN protocol+network protocol
|
||||||
// combination. If one combination is not supported, set it to `0`.
|
// combination. If one combination is not supported, set it to `0`.
|
||||||
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
// TODO: Set the necessary fields in `providerSettings` to
|
// TODO: Set the necessary fields in `providerSettings` to
|
||||||
// generate the right OpenVPN configuration file.
|
// generate the right OpenVPN configuration file.
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
@@ -22,5 +22,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
CA: "MIIDZzCCAk+gAwIBAgIUVwHEFE6geihigDSNkBppm2Zamx0wDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxEDAOBgNVBAoMB0dsdWV0dW4wHhcNMjIwNzAxMTY1MzE5WhcNMjcwNjMwMTY1MzE5WjBDMQswCQYDVQQGEwJDQTEPMA0GA1UECAwGUXVlYmVjMREwDwYDVQQHDAhNb250cmVhbDEQMA4GA1UECgwHR2x1ZXR1bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmJRhTUr+87NFkHL2PWjIz7efHqQgrWuDQt8oOBHvl0Hm72N+ckO+5Q0zG4XtqlpBjFjGUSjfNUWSrRztbXlMmzDcjHKjYHUPepJpoF100fK2q3XPiFRl6sEXzYeOdFgpaTdmGHS6DL9aWeCoYA/k6NV8YqHXujr14gOYOAWG6cRimpTJf8DtEDcxtp1w6fOEoN0b5PvV7dcpLiva8LYyZKPvFYBzlc5BZxOLvq6bvhQm54R6zoHFpaKOf7FeqhxI6KOQu4IPwU12YBlOP5CbkMAQ1cWWVQ4pnh0Hwh71Sjm848jS/OcammNzsp4xWaKt/pzcix3fpJt/MDP/9fxA8CAwEAAaNTMFEwHQYDVR0OBBYEFCIQ9l28Yy1/3qJvFarXjhKdG9tVMB8GA1UdIwQYMBaAFCIQ9l28Yy1/3qJvFarXjhKdG9tVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKLPmLTppXYTTOOxHhTMyHI0oTl7ID2PQfJsref+jDshB3hib98BC17b9ESpLnwx7ugg17NRl7RYutxjuVw/CK/gwAnTMg3D3mdAnKkMRr3UxnD89KprLIpf7WQCmyJaxalsD5jjgl3kuGM7jf2FJNxQz5RrXBGlQHa465ouov+Rp5v/K5Umyt6wsCZXEbOF0SdUhEGU3nxVbFsoPimNYSHHwc29USnQmyW1O/drFDoTcOK4GdHFEVkrHQgqwU8ay1fYGYfIUDhsV/5AAWgQC41r9FWr+VQgyJC94qmDg0c46RE123dL/YifVUl2DKuJ0aOY+OkSgwknKZ+FQd+8d6k=", //nolint:lll
|
CA: "MIIDZzCCAk+gAwIBAgIUVwHEFE6geihigDSNkBppm2Zamx0wDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxEDAOBgNVBAoMB0dsdWV0dW4wHhcNMjIwNzAxMTY1MzE5WhcNMjcwNjMwMTY1MzE5WjBDMQswCQYDVQQGEwJDQTEPMA0GA1UECAwGUXVlYmVjMREwDwYDVQQHDAhNb250cmVhbDEQMA4GA1UECgwHR2x1ZXR1bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmJRhTUr+87NFkHL2PWjIz7efHqQgrWuDQt8oOBHvl0Hm72N+ckO+5Q0zG4XtqlpBjFjGUSjfNUWSrRztbXlMmzDcjHKjYHUPepJpoF100fK2q3XPiFRl6sEXzYeOdFgpaTdmGHS6DL9aWeCoYA/k6NV8YqHXujr14gOYOAWG6cRimpTJf8DtEDcxtp1w6fOEoN0b5PvV7dcpLiva8LYyZKPvFYBzlc5BZxOLvq6bvhQm54R6zoHFpaKOf7FeqhxI6KOQu4IPwU12YBlOP5CbkMAQ1cWWVQ4pnh0Hwh71Sjm848jS/OcammNzsp4xWaKt/pzcix3fpJt/MDP/9fxA8CAwEAAaNTMFEwHQYDVR0OBBYEFCIQ9l28Yy1/3qJvFarXjhKdG9tVMB8GA1UdIwQYMBaAFCIQ9l28Yy1/3qJvFarXjhKdG9tVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKLPmLTppXYTTOOxHhTMyHI0oTl7ID2PQfJsref+jDshB3hib98BC17b9ESpLnwx7ugg17NRl7RYutxjuVw/CK/gwAnTMg3D3mdAnKkMRr3UxnD89KprLIpf7WQCmyJaxalsD5jjgl3kuGM7jf2FJNxQz5RrXBGlQHa465ouov+Rp5v/K5Umyt6wsCZXEbOF0SdUhEGU3nxVbFsoPimNYSHHwc29USnQmyW1O/drFDoTcOK4GdHFEVkrHQgqwU8ay1fYGYfIUDhsV/5AAWgQC41r9FWr+VQgyJC94qmDg0c46RE123dL/YifVUl2DKuJ0aOY+OkSgwknKZ+FQd+8d6k=", //nolint:lll
|
||||||
TLSAuth: "bc470c93ff9f5602a8abb27dee84a52814d10f20490ad23c47d5d82120c1bf859e93d0696b455d4a1b8d55d40c2685c41ca1d0aef29a3efd27274c4ef09020a3978fe45784b335da6df2d12db97bbb838416515f2a96f04715fd28949c6fe296a925cfada3f8b8928ed7fc963c1563272f5cf46e5e1d9c845d7703ca881497b7e6564a9d1dea9358adffd435295479f47d5298fabf5359613ff5992cb57ff081a04dfb81a26513a6b44a9b5490ad265f8a02384832a59cc3e075ad545461060b7bcab49bac815163cb80983dd51d5b1fd76170ffd904d8291071e96efc3fb777856c717b148d08a510f5687b8a8285dcffe737b98916dd15ef6235dee4266d3b", //nolint:lll
|
TLSAuth: "bc470c93ff9f5602a8abb27dee84a52814d10f20490ad23c47d5d82120c1bf859e93d0696b455d4a1b8d55d40c2685c41ca1d0aef29a3efd27274c4ef09020a3978fe45784b335da6df2d12db97bbb838416515f2a96f04715fd28949c6fe296a925cfada3f8b8928ed7fc963c1563272f5cf46e5e1d9c845d7703ca881497b7e6564a9d1dea9358adffd435295479f47d5298fabf5359613ff5992cb57ff081a04dfb81a26513a6b44a9b5490ad265f8a02384832a59cc3e075ad545461060b7bcab49bac815163cb80983dd51d5b1fd76170ffd904d8291071e96efc3fb777856c717b148d08a510f5687b8a8285dcffe737b98916dd15ef6235dee4266d3b", //nolint:lll
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,10 +99,10 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
|||||||
Region: serverData.Region,
|
Region: serverData.Region,
|
||||||
City: serverData.City,
|
City: serverData.City,
|
||||||
WgPubKey: serverData.WgPubKey,
|
WgPubKey: serverData.WgPubKey,
|
||||||
|
UDP: true,
|
||||||
}
|
}
|
||||||
if serverData.OpenVPNHostname != "" {
|
if serverData.OpenVPNHostname != "" {
|
||||||
server.VPN = vpn.OpenVPN
|
server.VPN = vpn.OpenVPN
|
||||||
server.UDP = true
|
|
||||||
server.TCP = true
|
server.TCP = true
|
||||||
server.Hostname = serverData.OpenVPNHostname
|
server.Hostname = serverData.OpenVPNHostname
|
||||||
server.IPs = hostToIPs[serverData.OpenVPNHostname]
|
server.IPs = hostToIPs[serverData.OpenVPNHostname]
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
filteredServers []models.Server
|
filteredServers []models.Server
|
||||||
storageErr error
|
storageErr error
|
||||||
selection settings.ServerSelection
|
selection settings.ServerSelection
|
||||||
ipv6Supported bool
|
|
||||||
connection models.Connection
|
connection models.Connection
|
||||||
errWrapped error
|
errWrapped error
|
||||||
errMessage string
|
errMessage string
|
||||||
@@ -95,12 +94,12 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
|
|
||||||
if testCase.panicMessage != "" {
|
if testCase.panicMessage != "" {
|
||||||
assert.PanicsWithValue(t, testCase.panicMessage, func() {
|
assert.PanicsWithValue(t, testCase.panicMessage, func() {
|
||||||
_, _ = provider.GetConnection(testCase.selection, testCase.ipv6Supported)
|
_, _ = provider.GetConnection(testCase.selection)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
|
connection, err := provider.GetConnection(testCase.selection)
|
||||||
|
|
||||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||||
if testCase.errWrapped != nil {
|
if testCase.errWrapped != nil {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
RemoteCertTLS: true,
|
RemoteCertTLS: true,
|
||||||
@@ -31,5 +31,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
// Always verify against `Server` x509 name prefix, security hole I guess?
|
// Always verify against `Server` x509 name prefix, security hole I guess?
|
||||||
VerifyX509Name: "Server",
|
VerifyX509Name: "Server",
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(4443, 4443, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(4443, 4443, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -32,5 +32,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
"comp-lzo",
|
"comp-lzo",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ func parseFilename(fileName string) (
|
|||||||
country string, tcp, udp bool, err error,
|
country string, tcp, udp bool, err error,
|
||||||
) {
|
) {
|
||||||
const (
|
const (
|
||||||
tcpSuffix = "-tcp.ovpn"
|
tcpSuffix = "-TCP.ovpn"
|
||||||
udpSuffix = "-udp.ovpn"
|
udpSuffix = "-UDP.ovpn"
|
||||||
)
|
)
|
||||||
var suffix string
|
var suffix string
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(strings.ToLower(fileName), tcpSuffix):
|
case strings.HasSuffix(fileName, tcpSuffix):
|
||||||
suffix = tcpSuffix
|
suffix = tcpSuffix
|
||||||
tcp = true
|
tcp = true
|
||||||
case strings.HasSuffix(strings.ToLower(fileName), udpSuffix):
|
case strings.HasSuffix(fileName, udpSuffix):
|
||||||
suffix = udpSuffix
|
suffix = udpSuffix
|
||||||
udp = true
|
udp = true
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ func parallelResolverSettings(hosts []string) (settings resolver.ParallelSetting
|
|||||||
const (
|
const (
|
||||||
maxFailRatio = 0.1
|
maxFailRatio = 0.1
|
||||||
maxNoNew = 1
|
maxNoNew = 1
|
||||||
maxFails = 4
|
maxFails = 2
|
||||||
maxDuration = 3 * time.Second
|
|
||||||
)
|
)
|
||||||
return resolver.ParallelSettings{
|
return resolver.ParallelSettings{
|
||||||
Hosts: hosts,
|
Hosts: hosts,
|
||||||
MaxFailRatio: maxFailRatio,
|
MaxFailRatio: maxFailRatio,
|
||||||
Repeat: resolver.RepeatSettings{
|
Repeat: resolver.RepeatSettings{
|
||||||
MaxDuration: maxDuration,
|
MaxDuration: time.Second,
|
||||||
MaxNoNew: maxNoNew,
|
MaxNoNew: maxNoNew,
|
||||||
MaxFails: maxFails,
|
MaxFails: maxFails,
|
||||||
SortIPs: true,
|
SortIPs: true,
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(8080, 553, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(8080, 553, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -21,5 +21,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
RSAKey: "MIIEpAIBAAKCAQEA5XY3ERJYWs/YIeBoybivNlu+M32rJs+CAZsh7BnnetTxytI4ngsMRoqXETuis8udp2hsqEHsglLR9tlk9C8yCuKhxbkpdrXFWdISmUq5sa7/wqg/zJF1AZm5Jy0oHNyTHfG6XW61I/h9IN5dmcR9YLir8DVDBNllbtt0z+DnvOhYJOqC30ENahWkTmNKl1cT7EBrR5slddiBJleAb08z77pwsD310e6jWTBySsBcPy+xu/Jj2QgVil/3mstZZDI+noFzs3SkTFBkha/lNTP7NODBQ6m39iaJxz6ZR1xE3v7XU0H5WnpZIcQ2+kmu5Krk2y1GYMKL+9oaotXFPz9v+QIDAQABAoIBAQCcMcssOMOiFWc3MC3EWo4SP4MKQ9n0Uj5Z34LI151FdJyehlj54+VYQ1Cv71tCbjED2sZUBoP69mtsT/EzcsjqtfiOwgrifrs2+BOm+0HKHKiGlcbP9peiHkT10PxEITWXpYtJvGlbcfOjIxqt6B28cBjCK09ShrVQL9ylAKBearRRUacszppntMNTMtN/uG48ZR9Wm+xAczImdG6CrG5sLI/++JwM5PDChLvn5JgMGyOfQZdjNe1oSOVLmqFeG5uu/FS4oMon9+HtfjHJr4ZgA1yQ2wQh3GvEjlP8zwHxEpRJYbxpj6ZbjHZJ2HLX/Gcd9/cXiN8+fQ2zPIYQyG9dAoGBAPUUmt2nJNvl7gj0GbZZ3XR9o+hvj7bJ74W2NhMrw6kjrrzHTAUQd1sBQS8szAQCLqf2ou1aw9AMMBdsLAHydXxvbH7IBAla7rKr23iethtSfjhTNSgQLJHVZlNHfp3hzNtCQZ7j0qVjrteNotrdVF7kKPHDXAK00ICy6SPNjvrXAoGBAO+vdnO15jLeZbbi3lQNS4r8oCadyqyX7ouKE6MtKNhiPsNPGqHKiGcKs/+QylVgYvSmm7TgpsCAiEYeLSPT+Yq3y7HtwVpULlpfAhEJXmvn/6hGpOizx1WNGWhw7nHPWPDzf+jqCGzHdhK0aEZR3MZZQ+U+uKfGiJ8vrvgB7eGvAoGAWxxp5nU48rcsIw/8bxpBhgkfYk33M5EnBqKSv9XJS5wEXhIJZOiWNrLktNEGl4boKXE7aNoRacreJhcE1UR6AOS7hPZ+6atwiePyF4mJUeb9HZtxa493wk9/Vv6BR9il++1Jz/QKX4oLef8hyBP4Rb60qgxirG7kBLR+j9zfhskCgYEAzA5y5xIeuIIU0H4XUDG9dcebxSSjbwsuYIgeLdb9pjMGQhsvjjyyoh8/nT20tLkJpkXN3FFCRjNnUWLRhWYrVkkh1wqWiYOPrwqh5MU4KN/sDWSPcznTY+drkTpMFoKzsvdrl2zf3VR3FneXKv742bkXj601Ykko+XWMHcLutisCgYBSq8IrsjzfaTQiTGI9a7WWsvzK92bq7Abnfq7swAXWcJd/bnjTQKLrrvt2bmwNvlWKAb3c69BFMn0X4t4PuN0iJQ39D6aQAEaM7HwWAmjf5TbodbmgbGxdsUB4xcCIQQ1mvTkigXWrCg0YAD2GZSoaslXAAVv6nR5qWEIa0Hx9GA==", //nolint:lll
|
RSAKey: "MIIEpAIBAAKCAQEA5XY3ERJYWs/YIeBoybivNlu+M32rJs+CAZsh7BnnetTxytI4ngsMRoqXETuis8udp2hsqEHsglLR9tlk9C8yCuKhxbkpdrXFWdISmUq5sa7/wqg/zJF1AZm5Jy0oHNyTHfG6XW61I/h9IN5dmcR9YLir8DVDBNllbtt0z+DnvOhYJOqC30ENahWkTmNKl1cT7EBrR5slddiBJleAb08z77pwsD310e6jWTBySsBcPy+xu/Jj2QgVil/3mstZZDI+noFzs3SkTFBkha/lNTP7NODBQ6m39iaJxz6ZR1xE3v7XU0H5WnpZIcQ2+kmu5Krk2y1GYMKL+9oaotXFPz9v+QIDAQABAoIBAQCcMcssOMOiFWc3MC3EWo4SP4MKQ9n0Uj5Z34LI151FdJyehlj54+VYQ1Cv71tCbjED2sZUBoP69mtsT/EzcsjqtfiOwgrifrs2+BOm+0HKHKiGlcbP9peiHkT10PxEITWXpYtJvGlbcfOjIxqt6B28cBjCK09ShrVQL9ylAKBearRRUacszppntMNTMtN/uG48ZR9Wm+xAczImdG6CrG5sLI/++JwM5PDChLvn5JgMGyOfQZdjNe1oSOVLmqFeG5uu/FS4oMon9+HtfjHJr4ZgA1yQ2wQh3GvEjlP8zwHxEpRJYbxpj6ZbjHZJ2HLX/Gcd9/cXiN8+fQ2zPIYQyG9dAoGBAPUUmt2nJNvl7gj0GbZZ3XR9o+hvj7bJ74W2NhMrw6kjrrzHTAUQd1sBQS8szAQCLqf2ou1aw9AMMBdsLAHydXxvbH7IBAla7rKr23iethtSfjhTNSgQLJHVZlNHfp3hzNtCQZ7j0qVjrteNotrdVF7kKPHDXAK00ICy6SPNjvrXAoGBAO+vdnO15jLeZbbi3lQNS4r8oCadyqyX7ouKE6MtKNhiPsNPGqHKiGcKs/+QylVgYvSmm7TgpsCAiEYeLSPT+Yq3y7HtwVpULlpfAhEJXmvn/6hGpOizx1WNGWhw7nHPWPDzf+jqCGzHdhK0aEZR3MZZQ+U+uKfGiJ8vrvgB7eGvAoGAWxxp5nU48rcsIw/8bxpBhgkfYk33M5EnBqKSv9XJS5wEXhIJZOiWNrLktNEGl4boKXE7aNoRacreJhcE1UR6AOS7hPZ+6atwiePyF4mJUeb9HZtxa493wk9/Vv6BR9il++1Jz/QKX4oLef8hyBP4Rb60qgxirG7kBLR+j9zfhskCgYEAzA5y5xIeuIIU0H4XUDG9dcebxSSjbwsuYIgeLdb9pjMGQhsvjjyyoh8/nT20tLkJpkXN3FFCRjNnUWLRhWYrVkkh1wqWiYOPrwqh5MU4KN/sDWSPcznTY+drkTpMFoKzsvdrl2zf3VR3FneXKv742bkXj601Ykko+XWMHcLutisCgYBSq8IrsjzfaTQiTGI9a7WWsvzK92bq7Abnfq7swAXWcJd/bnjTQKLrrvt2bmwNvlWKAb3c69BFMn0X4t4PuN0iJQ39D6aQAEaM7HwWAmjf5TbodbmgbGxdsUB4xcCIQQ1mvTkigXWrCg0YAD2GZSoaslXAAVv6nR5qWEIa0Hx9GA==", //nolint:lll
|
||||||
Ping: 5,
|
Ping: 5,
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
Ciphers: []string{
|
Ciphers: []string{
|
||||||
@@ -19,5 +19,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
|
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
|
||||||
CA: "MIIErTCCA5WgAwIBAgIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wHhcNMTIwMTExMTkzMjIwWhcNMjgxMTAyMTkzMjIwWjCBlTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkZMMRQwEgYDVQQHEwtXaW50ZXIgUGFyazERMA8GA1UEChMISVBWYW5pc2gxFTATBgNVBAsTDElQVmFuaXNoIFZQTjEUMBIGA1UEAxMLSVBWYW5pc2ggQ0ExIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAaXB2YW5pc2guY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9DBWNr/IKOuY3TmDP5x7vYZR0DGxLbXU8TyAzBbjUtFFMbhxlHiXVQrZHmgzih94x7BgXM7tWpmMKYVb+gNaqMdWE680Qm3nOwmhy/dulXDkEHAwD05i/iTx4ZaUdtV2vsKBxRg1vdC4AEiwD7bqV4HOi13xcG971aQ55Mj1KeCdA0aNvpat1LWx2jjWxsfI8s2Lv5Fkoi1HO1+vTnnaEsJZrBgAkLXpItqP29Lik3/OBIvkBIxlKrhiVPixE5qNiD+eSPirsmROvsyIonoJtuY4Dw5K6pcNlKyYiwo1IOFYU3YxffwFJk+bSW4WVBhsdf5dGxq/uOHmuz5gdwxCwIDAQABo4H9MIH6MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFEv9FCWJHefBcIPX9p8RHCVOGe6uMIHKBgNVHSMEgcIwgb+AFEv9FCWJHefBcIPX9p8RHCVOGe6uoYGbpIGYMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb22CCQDGCs0kvLjygzANBgkqhkiG9w0BAQ0FAAOCAQEAI2dkh/43ksV2fdYpVGhYaFZPVqCJoToCez0IvOmLeLGzow+EOSrY508oyjYeNP4VJEjApqo0NrMbKl8g/8bpLBcotOCF1c1HZ+y9v7648uumh01SMjsbBeHOuQcLb+7gX6c0pEmxWv8qj5JiW3/1L1bktnjW5Yp5oFkFSMXjOnIoYKHyKLjN2jtwH6XowUNYpg4qVtKU0CXPdOznWcd9/zSfa393HwJPeeVLbKYaFMC4IEbIUmKYtWyoJ9pJ58smU3pWsHZUg9Zc0LZZNjkNlBdQSLmUHAJ33Bd7pJS0JQeiWviC+4UTmzEWRKa7pDGnYRYNu2cUo0/voStphv8EVA==", //nolint:lll
|
CA: "MIIErTCCA5WgAwIBAgIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wHhcNMTIwMTExMTkzMjIwWhcNMjgxMTAyMTkzMjIwWjCBlTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkZMMRQwEgYDVQQHEwtXaW50ZXIgUGFyazERMA8GA1UEChMISVBWYW5pc2gxFTATBgNVBAsTDElQVmFuaXNoIFZQTjEUMBIGA1UEAxMLSVBWYW5pc2ggQ0ExIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAaXB2YW5pc2guY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9DBWNr/IKOuY3TmDP5x7vYZR0DGxLbXU8TyAzBbjUtFFMbhxlHiXVQrZHmgzih94x7BgXM7tWpmMKYVb+gNaqMdWE680Qm3nOwmhy/dulXDkEHAwD05i/iTx4ZaUdtV2vsKBxRg1vdC4AEiwD7bqV4HOi13xcG971aQ55Mj1KeCdA0aNvpat1LWx2jjWxsfI8s2Lv5Fkoi1HO1+vTnnaEsJZrBgAkLXpItqP29Lik3/OBIvkBIxlKrhiVPixE5qNiD+eSPirsmROvsyIonoJtuY4Dw5K6pcNlKyYiwo1IOFYU3YxffwFJk+bSW4WVBhsdf5dGxq/uOHmuz5gdwxCwIDAQABo4H9MIH6MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFEv9FCWJHefBcIPX9p8RHCVOGe6uMIHKBgNVHSMEgcIwgb+AFEv9FCWJHefBcIPX9p8RHCVOGe6uoYGbpIGYMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb22CCQDGCs0kvLjygzANBgkqhkiG9w0BAQ0FAAOCAQEAI2dkh/43ksV2fdYpVGhYaFZPVqCJoToCez0IvOmLeLGzow+EOSrY508oyjYeNP4VJEjApqo0NrMbKl8g/8bpLBcotOCF1c1HZ+y9v7648uumh01SMjsbBeHOuQcLb+7gX6c0pEmxWv8qj5JiW3/1L1bktnjW5Yp5oFkFSMXjOnIoYKHyKLjN2jtwH6XowUNYpg4qVtKU0CXPdOznWcd9/zSfa393HwJPeeVLbKYaFMC4IEbIUmKYtWyoJ9pJ58smU3pWsHZUg9Zc0LZZNjkNlBdQSLmUHAJ33Bd7pJS0JQeiWviC+4UTmzEWRKa7pDGnYRYNu2cUo0/voStphv8EVA==", //nolint:lll
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(443, 1194, 58237) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 1194, 58237) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
filteredServers []models.Server
|
filteredServers []models.Server
|
||||||
storageErr error
|
storageErr error
|
||||||
selection settings.ServerSelection
|
selection settings.ServerSelection
|
||||||
ipv6Supported bool
|
|
||||||
connection models.Connection
|
connection models.Connection
|
||||||
errWrapped error
|
errWrapped error
|
||||||
errMessage string
|
errMessage string
|
||||||
@@ -104,7 +103,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
parallelResolver := (common.ParallelResolver)(nil)
|
parallelResolver := (common.ParallelResolver)(nil)
|
||||||
provider := New(storage, randSource, client, warner, parallelResolver)
|
provider := New(storage, randSource, client, warner, parallelResolver)
|
||||||
|
|
||||||
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
|
connection, err := provider.GetConnection(testCase.selection)
|
||||||
|
|
||||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||||
if testCase.errWrapped != nil {
|
if testCase.errWrapped != nil {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -25,5 +25,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
"key-direction 1",
|
"key-direction 1",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
|||||||
return nil, fmt.Errorf("failed fetching API: %w", err)
|
return nil, fmt.Errorf("failed fetching API: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hosts := make(map[string]struct{}, len(data.Servers))
|
hosts := make([]string, 0, len(data.Servers))
|
||||||
|
|
||||||
for _, serverData := range data.Servers {
|
for _, serverData := range data.Servers {
|
||||||
openVPNHost := serverData.Hostnames.OpenVPN
|
openVPNHost := serverData.Hostnames.OpenVPN
|
||||||
if openVPNHost != "" {
|
if openVPNHost != "" {
|
||||||
hosts[openVPNHost] = struct{}{}
|
hosts = append(hosts, openVPNHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
wireguardHost := serverData.Hostnames.Wireguard
|
wireguardHost := serverData.Hostnames.Wireguard
|
||||||
if wireguardHost != "" {
|
if wireguardHost != "" {
|
||||||
hosts[wireguardHost] = struct{}{}
|
hosts = append(hosts, wireguardHost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,13 +36,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
|||||||
common.ErrNotEnoughServers, len(hosts), minServers)
|
common.ErrNotEnoughServers, len(hosts), minServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
hostsSlice := make(sort.StringSlice, 0, len(hosts))
|
resolveSettings := parallelResolverSettings(hosts)
|
||||||
for host := range hosts {
|
|
||||||
hostsSlice = append(hostsSlice, host)
|
|
||||||
}
|
|
||||||
hostsSlice.Sort() // for predictable unit tests
|
|
||||||
|
|
||||||
resolveSettings := parallelResolverSettings(hostsSlice)
|
|
||||||
hostToIPs, warnings, err := u.parallelResolver.Resolve(ctx, resolveSettings)
|
hostToIPs, warnings, err := u.parallelResolver.Resolve(ctx, resolveSettings)
|
||||||
for _, warning := range warnings {
|
for _, warning := range warnings {
|
||||||
u.warner.Warn(warning)
|
u.warner.Warn(warning)
|
||||||
@@ -56,40 +50,31 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
|||||||
common.ErrNotEnoughServers, len(servers), minServers)
|
common.ErrNotEnoughServers, len(servers), minServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
servers = make([]models.Server, 0, len(hostToIPs))
|
servers = make([]models.Server, 0, len(hosts))
|
||||||
for _, serverData := range data.Servers {
|
for _, serverData := range data.Servers {
|
||||||
|
vpnType := vpn.OpenVPN
|
||||||
|
hostname := serverData.Hostnames.OpenVPN
|
||||||
|
tcp := true
|
||||||
|
wgPubKey := ""
|
||||||
|
if hostname == "" {
|
||||||
|
vpnType = vpn.Wireguard
|
||||||
|
hostname = serverData.Hostnames.Wireguard
|
||||||
|
tcp = false
|
||||||
|
wgPubKey = serverData.WgPubKey
|
||||||
|
}
|
||||||
|
|
||||||
server := models.Server{
|
server := models.Server{
|
||||||
Country: serverData.Country,
|
VPN: vpnType,
|
||||||
City: serverData.City,
|
Country: serverData.Country,
|
||||||
ISP: serverData.ISP,
|
City: serverData.City,
|
||||||
}
|
ISP: serverData.ISP,
|
||||||
|
Hostname: hostname,
|
||||||
openVPNHostname := serverData.Hostnames.OpenVPN
|
WgPubKey: wgPubKey,
|
||||||
wireguardHostname := serverData.Hostnames.Wireguard
|
TCP: tcp,
|
||||||
if openVPNHostname == "" && wireguardHostname == "" {
|
UDP: true,
|
||||||
warning := fmt.Sprintf("server data %v has no OpenVPN nor Wireguard hostname", serverData)
|
IPs: hostToIPs[hostname],
|
||||||
warnings = append(warnings, warning)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if openVPNHostname != "" {
|
|
||||||
openVPNServer := server
|
|
||||||
openVPNServer.Hostname = openVPNHostname
|
|
||||||
openVPNServer.VPN = vpn.OpenVPN
|
|
||||||
openVPNServer.UDP = true
|
|
||||||
openVPNServer.TCP = true
|
|
||||||
openVPNServer.IPs = hostToIPs[openVPNHostname]
|
|
||||||
servers = append(servers, openVPNServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
if wireguardHostname != "" {
|
|
||||||
wireguardServer := server
|
|
||||||
wireguardServer.Hostname = wireguardHostname
|
|
||||||
wireguardServer.VPN = vpn.Wireguard
|
|
||||||
wireguardServer.IPs = hostToIPs[wireguardHostname]
|
|
||||||
wireguardServer.WgPubKey = serverData.WgPubKey
|
|
||||||
servers = append(servers, wireguardServer)
|
|
||||||
}
|
}
|
||||||
|
servers = append(servers, server)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(models.SortableServers(servers))
|
sort.Sort(models.SortableServers(servers))
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
||||||
{VPN: vpn.Wireguard,
|
{VPN: vpn.Wireguard,
|
||||||
Country: "Country3", City: "City C",
|
Country: "Country3", City: "City C",
|
||||||
Hostname: "hostc",
|
Hostname: "hostc", UDP: true,
|
||||||
WgPubKey: "xyz",
|
WgPubKey: "xyz",
|
||||||
IPs: []net.IP{{5, 5, 5, 5}, {6, 6, 6, 6}}},
|
IPs: []net.IP{{5, 5, 5, 5}, {6, 6, 6, 6}}},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
filteredServers []models.Server
|
filteredServers []models.Server
|
||||||
storageErr error
|
storageErr error
|
||||||
selection settings.ServerSelection
|
selection settings.ServerSelection
|
||||||
ipv6Supported bool
|
|
||||||
connection models.Connection
|
connection models.Connection
|
||||||
errWrapped error
|
errWrapped error
|
||||||
errMessage string
|
errMessage string
|
||||||
@@ -102,7 +101,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
|||||||
client := (*http.Client)(nil)
|
client := (*http.Client)(nil)
|
||||||
provider := New(storage, randSource, client)
|
provider := New(storage, randSource, client)
|
||||||
|
|
||||||
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
|
connection, err := provider.GetConnection(testCase.selection)
|
||||||
|
|
||||||
assert.ErrorIs(t, err, testCase.errWrapped)
|
assert.ErrorIs(t, err, testCase.errWrapped)
|
||||||
if testCase.errWrapped != nil {
|
if testCase.errWrapped != nil {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -24,5 +24,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
CA: "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", //nolint:lll
|
CA: "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", //nolint:lll
|
||||||
UDPLines: []string{"fast-io"},
|
UDPLines: []string{"fast-io"},
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func (hts hostToServer) add(data serverData) (err error) {
|
|||||||
server.TCP = true
|
server.TCP = true
|
||||||
case "wireguard":
|
case "wireguard":
|
||||||
server.VPN = vpn.Wireguard
|
server.VPN = vpn.Wireguard
|
||||||
|
server.UDP = true
|
||||||
case "bridge":
|
case "bridge":
|
||||||
// ignore bridge servers
|
// ignore bridge servers
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -32,5 +32,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
"comp-lzo no", // Explicitly disable compression
|
"comp-lzo no", // Explicitly disable compression
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -33,5 +33,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
`pull-filter ignore "redirect-gateway def1 ipv6"`,
|
`pull-filter ignore "redirect-gateway def1 ipv6"`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
|
defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
func (p *Provider) OpenVPNConfig(connection models.Connection,
|
||||||
settings settings.OpenVPN, ipv6Supported bool) (lines []string) {
|
settings settings.OpenVPN) (lines []string) {
|
||||||
//nolint:gomnd
|
//nolint:gomnd
|
||||||
providerSettings := utils.OpenVPNProviderSettings{
|
providerSettings := utils.OpenVPNProviderSettings{
|
||||||
AuthUserPass: true,
|
AuthUserPass: true,
|
||||||
@@ -21,5 +21,5 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
VerifyX509Type: "name",
|
VerifyX509Type: "name",
|
||||||
CA: "MIIFKDCCAxCgAwIBAgIJAMtrmqZxIV/OMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMMB1ByaXZhZG8wHhcNMjAwMTA4MjEyODQ1WhcNMzUwMTA5MjEyODQ1WjASMRAwDgYDVQQDDAdQcml2YWRvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPwOgiwNJzZTnKIXwAB0TSu/Lu2qt2U2I8obtQjwhi/7OrfmbmYykSdro70al2XPhnwAGGdCxW6LDnp0UN/IOhD11mgBPo14f5CLkBQjSJ6VN5miPbvK746LsNZl9H8rQGvDuPo4CG9BfPZMiDRGlsMxij/jztzgT1gmuxQ7WHfFRcNzBas1dHa9hV/d3TU6/t47x4SE/ljdcCtJiu7Zn6ODKQoys3mB7Luz2ngqUJWvkqsg+E4+3eJ0M8Hlbn5TPaRJBID7DAdYo6Vs6xGCYr981ThFcmoIQ10js10yANrrfGAzd03b3TnLAgko0uQMHjliMZL6L8sWOPHxyxJI0us88SFh4UgcFyRHKHPKux7w24SxAlZUYoUcTHp9VjG5XvDKYxzgV2RdM4ulBGbQRQ3y3/CyddsyQYMvA55Ets0LfPaBvDIcct70iXijGsdvlX1du3ArGpG7Vaje/RU4nbbGT6HYRdt5YyZfof288ukMOSj20nVcmS+c/4tqsxSerRb1aq5LOi1IemSkTMeC5gCbexk+L1vl7NT/58sxjGmu5bXwnvev/lIItfi2AlITrfUSEv19iDMKkeshwn/+sFJBMWYyluP+yJ56yR+MWoXvLlSWphLDTqq19yx3BZn0P1tgbXoR0g8PTdJFcz8z3RIb7myVLYulV1oGG/3rka0CAwEAAaOBgDB+MB0GA1UdDgQWBBTFtJkZCVDuDAD6k5bJzefjJdO3DTBCBgNVHSMEOzA5gBTFtJkZCVDuDAD6k5bJzefjJdO3DaEWpBQwEjEQMA4GA1UEAwwHUHJpdmFkb4IJAMtrmqZxIV/OMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQB7MUSXMeBb9wlSv4sUaT1JHEwE26nlBw+TKmezfuPU5pBlY0LYr6qQZY95DHqsRJ7ByUzGUrGo17dNGXlcuNc6TAaQQEDRPo6y+LVh2TWMk15TUMI+MkqryJtCret7xGvDigKYMJgBy58HN3RAVr1B7cL9youwzLgc2Y/NcFKvnQJKeiIYAJ7g0CcnJiQvgZTS7xdwkEBXfsngmUCIG320DLPEL+Ze0HiUrxwWljMRya6i40AeH3Zu2i532xX1wV5+cjA4RJWIKg6ri/Q54iFGtZrA9/nc6y9uoQHkmz8cGyVUmJxFzMrrIICVqUtVRxLhkTMe4UzwRWTBeGgtW4tS0yq1QonAKfOyjgRw/CeY55D2UGvnAFZdTadtYXS4Alu2P9zdwoEk3fzHiVmDjqfJVr5wz9383aABUFrPI3nz6ed/Z6LZflKh1k+DUDEp8NxU4klUULWsSOKoa5zGX51G8cdHxwQLImXvtGuN5eSR8jCTgxFZhdps/xes4KkyfIz9FMYG748M+uOTgKITf4zdJ9BAyiQaOufVQZ8WjhWzWk9YHec9VqPkzpWNGkVjiRI5ewuXwZzZ164tMv2hikBXSuUCnFz37/ZNwGlDi0oBdDszCk2GxccdFHHaCSmpjU5MrdJ+5IhtTKGeTx+US2hTIVHQFIO99DmacxSYvLNcSQ==", //nolint:lll
|
CA: "MIIFKDCCAxCgAwIBAgIJAMtrmqZxIV/OMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMMB1ByaXZhZG8wHhcNMjAwMTA4MjEyODQ1WhcNMzUwMTA5MjEyODQ1WjASMRAwDgYDVQQDDAdQcml2YWRvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPwOgiwNJzZTnKIXwAB0TSu/Lu2qt2U2I8obtQjwhi/7OrfmbmYykSdro70al2XPhnwAGGdCxW6LDnp0UN/IOhD11mgBPo14f5CLkBQjSJ6VN5miPbvK746LsNZl9H8rQGvDuPo4CG9BfPZMiDRGlsMxij/jztzgT1gmuxQ7WHfFRcNzBas1dHa9hV/d3TU6/t47x4SE/ljdcCtJiu7Zn6ODKQoys3mB7Luz2ngqUJWvkqsg+E4+3eJ0M8Hlbn5TPaRJBID7DAdYo6Vs6xGCYr981ThFcmoIQ10js10yANrrfGAzd03b3TnLAgko0uQMHjliMZL6L8sWOPHxyxJI0us88SFh4UgcFyRHKHPKux7w24SxAlZUYoUcTHp9VjG5XvDKYxzgV2RdM4ulBGbQRQ3y3/CyddsyQYMvA55Ets0LfPaBvDIcct70iXijGsdvlX1du3ArGpG7Vaje/RU4nbbGT6HYRdt5YyZfof288ukMOSj20nVcmS+c/4tqsxSerRb1aq5LOi1IemSkTMeC5gCbexk+L1vl7NT/58sxjGmu5bXwnvev/lIItfi2AlITrfUSEv19iDMKkeshwn/+sFJBMWYyluP+yJ56yR+MWoXvLlSWphLDTqq19yx3BZn0P1tgbXoR0g8PTdJFcz8z3RIb7myVLYulV1oGG/3rka0CAwEAAaOBgDB+MB0GA1UdDgQWBBTFtJkZCVDuDAD6k5bJzefjJdO3DTBCBgNVHSMEOzA5gBTFtJkZCVDuDAD6k5bJzefjJdO3DaEWpBQwEjEQMA4GA1UEAwwHUHJpdmFkb4IJAMtrmqZxIV/OMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQB7MUSXMeBb9wlSv4sUaT1JHEwE26nlBw+TKmezfuPU5pBlY0LYr6qQZY95DHqsRJ7ByUzGUrGo17dNGXlcuNc6TAaQQEDRPo6y+LVh2TWMk15TUMI+MkqryJtCret7xGvDigKYMJgBy58HN3RAVr1B7cL9youwzLgc2Y/NcFKvnQJKeiIYAJ7g0CcnJiQvgZTS7xdwkEBXfsngmUCIG320DLPEL+Ze0HiUrxwWljMRya6i40AeH3Zu2i532xX1wV5+cjA4RJWIKg6ri/Q54iFGtZrA9/nc6y9uoQHkmz8cGyVUmJxFzMrrIICVqUtVRxLhkTMe4UzwRWTBeGgtW4tS0yq1QonAKfOyjgRw/CeY55D2UGvnAFZdTadtYXS4Alu2P9zdwoEk3fzHiVmDjqfJVr5wz9383aABUFrPI3nz6ed/Z6LZflKh1k+DUDEp8NxU4klUULWsSOKoa5zGX51G8cdHxwQLImXvtGuN5eSR8jCTgxFZhdps/xes4KkyfIz9FMYG748M+uOTgKITf4zdJ9BAyiQaOufVQZ8WjhWzWk9YHec9VqPkzpWNGkVjiRI5ewuXwZzZ164tMv2hikBXSuUCnFz37/ZNwGlDi0oBdDszCk2GxccdFHHaCSmpjU5MrdJ+5IhtTKGeTx+US2hTIVHQFIO99DmacxSYvLNcSQ==", //nolint:lll
|
||||||
}
|
}
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
|
func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
// Set port defaults depending on encryption preset.
|
// Set port defaults depending on encryption preset.
|
||||||
var defaults utils.ConnectionDefaults
|
var defaults utils.ConnectionDefaults
|
||||||
@@ -21,5 +21,5 @@ func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Support
|
|||||||
}
|
}
|
||||||
|
|
||||||
return utils.GetConnection(p.Name(),
|
return utils.GetConnection(p.Name(),
|
||||||
p.storage, selection, defaults, ipv6Supported, p.randSource)
|
p.storage, selection, defaults, p.randSource)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func Test_newHTTPClient(t *testing.T) {
|
|||||||
piaTransport, ok := piaClient.Transport.(*http.Transport)
|
piaTransport, ok := piaClient.Transport.(*http.Transport)
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
|
|
||||||
subjects := piaTransport.TLSClientConfig.RootCAs.Subjects() //nolint:staticcheck
|
subjects := piaTransport.TLSClientConfig.RootCAs.Subjects()
|
||||||
assert.NotEmpty(t, subjects)
|
assert.NotEmpty(t, subjects)
|
||||||
piaCertFound := false
|
piaCertFound := false
|
||||||
for _, subject := range subjects {
|
for _, subject := range subjects {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user