Add linters and fix lint issues

This commit is contained in:
Quentin McGaw
2020-10-20 02:45:28 +00:00
parent f9bef8ecda
commit 9c73faaaeb
107 changed files with 739 additions and 422 deletions
+13
View File
@@ -7,30 +7,43 @@ linters-settings:
linters:
disable-all: true
enable:
- asciicheck
- bodyclose
- deadcode
- dogsled
- dupl
- errcheck
- exhaustive
- exportloopref
- gci
- gochecknoglobals
- gochecknoinits
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- goheader
- goimports
- golint
- gomnd
- goprintffuncname
- gosec
- gosimple
- govet
- ineffassign
- interfacer
- lll
- maligned
- misspell
- nakedret
- nestif
- noctx
- nolintlint
- prealloc
- rowserrcheck
- scopelint
- sqlclosecheck
- staticcheck
- structcheck
- typecheck
+21 -10
View File
@@ -73,8 +73,9 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
defer cancel()
logger := createLogger()
httpClient := &http.Client{Timeout: 15 * time.Second}
client := network.NewClient(15 * time.Second)
const clientTimeout = 15 * time.Second
httpClient := &http.Client{Timeout: clientTimeout}
client := network.NewClient(clientTimeout)
// Create configurators
fileManager := files.NewFileManager()
alpineConf := alpine.NewConfigurator(fileManager)
@@ -205,7 +206,8 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
go openvpnLooper.Run(ctx, wg)
updaterOptions := updater.NewOptions("127.0.0.1")
updaterLooper := updater.NewLooper(updaterOptions, allSettings.UpdaterPeriod, allServers, storage, openvpnLooper.SetAllServers, httpClient, logger)
updaterLooper := updater.NewLooper(updaterOptions, allSettings.UpdaterPeriod,
allServers, storage, openvpnLooper.SetAllServers, httpClient, logger)
wg.Add(1)
// wait for updaterLooper.Restart() or its ticket launched with RunRestartTicker
go updaterLooper.Run(ctx, wg)
@@ -215,14 +217,16 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
// wait for unboundLooper.Restart or its ticker launched with RunRestartTicker
go unboundLooper.Run(ctx, wg, signalDNSReady)
publicIPLooper := publicip.NewLooper(client, logger, fileManager, allSettings.System.IPStatusFilepath, allSettings.PublicIPPeriod, uid, gid)
publicIPLooper := publicip.NewLooper(client, logger, fileManager,
allSettings.System.IPStatusFilepath, allSettings.PublicIPPeriod, uid, gid)
wg.Add(1)
go publicIPLooper.Run(ctx, wg)
wg.Add(1)
go publicIPLooper.RunRestartTicker(ctx, wg)
publicIPLooper.SetPeriod(allSettings.PublicIPPeriod) // call after RunRestartTicker
tinyproxyLooper := tinyproxy.NewLooper(tinyProxyConf, firewallConf, allSettings.TinyProxy, logger, streamMerger, uid, gid, defaultInterface)
tinyproxyLooper := tinyproxy.NewLooper(tinyProxyConf, firewallConf,
allSettings.TinyProxy, logger, streamMerger, uid, gid, defaultInterface)
restartTinyproxy := tinyproxyLooper.Restart
wg.Add(1)
go tinyproxyLooper.Run(ctx, wg)
@@ -246,7 +250,8 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
)
controlServerAddress := fmt.Sprintf("0.0.0.0:%d", allSettings.ControlServer.Port)
controlServerLogging := allSettings.ControlServer.Log
httpServer := server.New(controlServerAddress, controlServerLogging, logger, openvpnLooper, unboundLooper, updaterLooper)
httpServer := server.New(controlServerAddress, controlServerLogging,
logger, openvpnLooper, unboundLooper, updaterLooper)
wg.Add(1)
go httpServer.Run(ctx, wg)
@@ -309,8 +314,10 @@ func createLogger() logging.Logger {
return logger
}
func printVersions(ctx context.Context, logger logging.Logger, versionFunctions map[string]func(ctx context.Context) (string, error)) {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
func printVersions(ctx context.Context, logger logging.Logger,
versionFunctions map[string]func(ctx context.Context) (string, error)) {
const timeout = 5 * time.Second
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
for name, f := range versionFunctions {
version, err := f(ctx)
@@ -322,7 +329,9 @@ func printVersions(ctx context.Context, logger logging.Logger, versionFunctions
}
}
func collectStreamLines(ctx context.Context, streamMerger command.StreamMerger, logger logging.Logger, signalTunnelReady func()) {
//nolint:lll
func collectStreamLines(ctx context.Context, streamMerger command.StreamMerger,
logger logging.Logger, signalTunnelReady func()) {
// Blocking line merging paramsReader for all programs: openvpn, tinyproxy, unbound and shadowsocks
logger.Info("Launching standard output merger")
streamMerger.CollectLines(ctx, func(line string) {
@@ -331,6 +340,8 @@ func collectStreamLines(ctx context.Context, streamMerger command.StreamMerger,
return
}
switch level {
case logging.DebugLevel:
logger.Debug(line)
case logging.InfoLevel:
logger.Info(line)
case logging.WarnLevel:
@@ -374,7 +385,7 @@ func routeReadyEvents(ctx context.Context, wg *sync.WaitGroup, tunnelReadyCh, dn
restartTickerCancel() // stop previous restart tickers
tickerWg.Wait()
restartTickerContext, restartTickerCancel = context.WithCancel(ctx)
tickerWg.Add(2)
tickerWg.Add(2) //nolint:gomnd
go unboundLooper.RunRestartTicker(restartTickerContext, tickerWg)
go updaterLooper.RunRestartTicker(restartTickerContext, tickerWg)
defaultInterface, _, err := routing.DefaultRoute()
+3 -2
View File
@@ -5,7 +5,7 @@ import (
"os/user"
)
// CreateUser creates a user in Alpine with the given UID
// CreateUser creates a user in Alpine with the given UID.
func (c *configurator) CreateUser(username string, uid int) error {
UIDStr := fmt.Sprintf("%d", uid)
u, err := c.lookupUID(UIDStr)
@@ -23,7 +23,8 @@ func (c *configurator) CreateUser(username string, uid int) error {
if err != nil && !unknownUsername {
return fmt.Errorf("cannot create user: %w", err)
} else if u != nil {
return fmt.Errorf("cannot create user: user with name %s already exists for ID %s instead of %d", username, u.Uid, uid)
return fmt.Errorf("cannot create user: user with name %s already exists for ID %s instead of %d",
username, u.Uid, uid)
}
passwd, err := c.fileManager.ReadFile("/etc/passwd")
if err != nil {
+2 -1
View File
@@ -117,7 +117,8 @@ func Update(args []string) error {
return fmt.Errorf("at least one of -file or -stdout must be specified")
}
ctx := context.Background()
httpClient := &http.Client{Timeout: 10 * time.Second}
const clientTimeout = 10 * time.Second
httpClient := &http.Client{Timeout: clientTimeout}
storage := storage.New(logger)
const writeSync = false
currentServers, err := storage.SyncServers(constants.GetAllServers(), writeSync)
+2
View File
@@ -7,6 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
CyberghostCertificate = "MIIGWjCCBEKgAwIBAgIJAJxUG61mxDS7MA0GCSqGSIb3DQEBDQUAMHsxCzAJBgNVBAYTAlJPMRIwEAYDVQQHEwlCdWNoYXJlc3QxGDAWBgNVBAoTD0N5YmVyR2hvc3QgUy5BLjEbMBkGA1UEAxMSQ3liZXJHaG9zdCBSb290IENBMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGN5YmVyZ2hvc3Qucm8wHhcNMTcwNjE5MDgxNzI1WhcNMzcwNjE0MDgxNzI1WjB7MQswCQYDVQQGEwJSTzESMBAGA1UEBxMJQnVjaGFyZXN0MRgwFgYDVQQKEw9DeWJlckdob3N0IFMuQS4xGzAZBgNVBAMTEkN5YmVyR2hvc3QgUm9vdCBDQTEhMB8GCSqGSIb3DQEJARYSaW5mb0BjeWJlcmdob3N0LnJvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7O8+mji2FlQhJXn/G4VLrKPjGtxgQBAdjo0dZEQzKX08q14dLkslmOLgShStWKrOiLXGAvB1rPvvk613jtA0KjQLpgyLy9lIWohQKYjj5jrJYXMZMkbSHBYI9L8L7iezBEFYrjYKdDo51nq99wRFhKdbyKKjDh3e2L2SVEZLT1ogkK5gWzjvH+mjjtjUUicK+YjGwWOz6I+KKaG4Ve/D/cE6nCLbhHIMMnargZEu7sqA6BFeS4kEP/ZdCZoTSX2n43XV1q63nJt/v0KDetbZDciFVW9h9SVPG4qT44p0550N+Mom7zTX7S/ID5T9dplgU8sRGtIMrG0cIMD9zmpFgUnMusCrR7jJFr0sMAveTbgZg95LmstV6R6WKZkSFdUrE0DHl4dHoZvTFX+1LhwhHgjgDLaosX0vhG/C/7LpoVWimd6RRQT3M9o4Fa1TuhfvBzQ20QHrmRV/yKvGNK0xckZ6EZ/QY7Z55ORU15Tgab4ebnblYPWoEmn0mIYP3LFFeoR5OS1EX7+j4kPv+bwPGsmpHjxmZyq2Y7sJBpbOCJgbkn52WZdPBIRDpPdIHQ8pAJC4T0iMK9xvAwWNl/V6EYYNpR97osyEDXn+BTdAHlhJ5fck9KlwI9mb1Kg1bhbvbmaIAiOLenSULYf3j6rI1ygo3R2cCyybtuAq8M7z0OECAwEAAaOB4DCB3TAdBgNVHQ4EFgQU6tdK1g/He5qzjeAoM5eHt4in9iUwga0GA1UdIwSBpTCBooAU6tdK1g/He5qzjeAoM5eHt4in9iWhf6R9MHsxCzAJBgNVBAYTAlJPMRIwEAYDVQQHEwlCdWNoYXJlc3QxGDAWBgNVBAoTD0N5YmVyR2hvc3QgUy5BLjEbMBkGA1UEAxMSQ3liZXJHaG9zdCBSb290IENBMSEwHwYJKoZIhvcNAQkBFhJpbmZvQGN5YmVyZ2hvc3Qucm+CCQCcVButZsQ0uzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4ICAQDNyQ92kj4qiNjnHk99qvnFw9qGfwB9ofaPL74zh0G5hEe3Wgb2o4fqUGnvUNgOu53gJksz3DcPQ8t40wfmm9I1Z8tiM9qrqvkuQ+nKcLgdooXtEsTybPIYDZ2cWR/5E0TKRvC7RFzKgQ4D77Vbi4TdaHiDV7ZNfU1iLCoBGcYm80hcUHEs5KIVLwUmcSOTmbZBySJxcSD0yUpS7nlZGwLY6VQrU+JFwDSisbXT4DXf3iSzp7FzW0/u/SFvWsPHrjE0hkPoZPalYvouaJEHKAhip0ZwSmitlxbBnmm8+K/3c9mLA5/uXrirfpuhhs8V3lyV2mczVtSiTl6gpi88gc//JY80JeHdupjO25T3XEzY9cpxecmkWaUEjLMx4wVoXQuUiPonfILM6OLwi+zUS8gQErdFeGvcQXbncPa4SdJuHkF8lgiX2i8S8fPGdXvU37E9bdAXwP5nZriYq1s0D59Qfvz+vLXVkmyZp6ztxjKjKolemPMak0Y5c1Q4RjNF6tmQoFuy/ACSkWy14Tzu2dFp7UiVbGg1FOvKhfs48zC2/IUQv1arqmPT/9LVq3B2DVT9UKXRUXX/f/jSSsVjkz4uUe2jUyL+XHX1nSmROTPHSAJ+oKf0BLnfqUxFkEUTwLnayssP2nwGgq35b7wEbTFIXdrjHGFUVQIDeERz8UThew=="
CyberghostClientCertificate = "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"
@@ -40,6 +41,7 @@ func CyberghostGroupChoices() (choices []string) {
return choices
}
//nolint:lll
func CyberghostServers() []models.CyberghostServer {
return []models.CyberghostServer{
{Region: "Albania", Group: "Premium TCP Europe", IPs: []net.IP{{31, 171, 152, 99}, {31, 171, 152, 102}, {31, 171, 152, 104}, {31, 171, 152, 106}, {31, 171, 152, 107}, {31, 171, 152, 108}, {31, 171, 152, 109}, {31, 171, 152, 133}, {31, 171, 152, 139}, {31, 171, 152, 140}}},
+42 -15
View File
@@ -7,19 +7,19 @@ import (
)
const (
// Cloudflare is a DNS over TLS provider
// Cloudflare is a DNS over TLS provider.
Cloudflare models.DNSProvider = "cloudflare"
// Google is a DNS over TLS provider
// Google is a DNS over TLS provider.
Google models.DNSProvider = "google"
// Quad9 is a DNS over TLS provider
// Quad9 is a DNS over TLS provider.
Quad9 models.DNSProvider = "quad9"
// Quadrant is a DNS over TLS provider
// Quadrant is a DNS over TLS provider.
Quadrant models.DNSProvider = "quadrant"
// CleanBrowsing is a DNS over TLS provider
// CleanBrowsing is a DNS over TLS provider.
CleanBrowsing models.DNSProvider = "cleanbrowsing"
// SecureDNS is a DNS over TLS provider
// SecureDNS is a DNS over TLS provider.
SecureDNS models.DNSProvider = "securedns"
// LibreDNS is a DNS over TLS provider
// LibreDNS is a DNS over TLS provider.
LibreDNS models.DNSProvider = "libredns"
)
@@ -28,37 +28,63 @@ const (
func DNSProviderMapping() map[models.DNSProvider]models.DNSProviderData {
return map[models.DNSProvider]models.DNSProviderData{
Cloudflare: {
IPs: []net.IP{{1, 1, 1, 1}, {1, 0, 0, 1}, {0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11}, {0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x01}},
IPs: []net.IP{
{1, 1, 1, 1},
{1, 0, 0, 1},
{0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11},
{0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x01},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("cloudflare-dns.com"),
},
Google: {
IPs: []net.IP{{8, 8, 8, 8}, {8, 8, 4, 4}, {0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x88}, {0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x44}},
IPs: []net.IP{
{8, 8, 8, 8},
{8, 8, 4, 4},
{0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x88},
{0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x44},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("dns.google"),
},
Quad9: {
IPs: []net.IP{{9, 9, 9, 9}, {149, 112, 112, 112}, {0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe}, {0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9}},
IPs: []net.IP{
{9, 9, 9, 9},
{149, 112, 112, 112},
{0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe},
{0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("dns.quad9.net"),
},
Quadrant: {
IPs: []net.IP{{12, 159, 2, 159}, {0x20, 0x1, 0x18, 0x90, 0x14, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x59}},
IPs: []net.IP{
{12, 159, 2, 159},
{0x20, 0x1, 0x18, 0x90, 0x14, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x59},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("dns-tls.qis.io"),
},
CleanBrowsing: {
IPs: []net.IP{{185, 228, 168, 9}, {185, 228, 169, 9}, {0x2a, 0xd, 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, {0x2a, 0xd, 0x2a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}},
IPs: []net.IP{
{185, 228, 168, 9},
{185, 228, 169, 9},
{0x2a, 0xd, 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
{0x2a, 0xd, 0x2a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("security-filter-dns.cleanbrowsing.org"),
},
SecureDNS: {
IPs: []net.IP{{146, 185, 167, 43}, {0x2a, 0x3, 0xb0, 0xc0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0xe, 0x9a, 0x30, 0x1}},
IPs: []net.IP{
{146, 185, 167, 43},
{0x2a, 0x3, 0xb0, 0xc0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0xe, 0x9a, 0x30, 0x1},
},
SupportsTLS: true,
SupportsIPv6: true,
Host: models.DNSHost("dot.securedns.eu"),
@@ -72,6 +98,7 @@ func DNSProviderMapping() map[models.DNSProvider]models.DNSProviderData {
}
// Block lists URLs
//nolint:lll
const (
AdsBlockListHostnamesURL models.URL = "https://raw.githubusercontent.com/qdm12/files/master/ads-hostnames.updated"
AdsBlockListIPsURL models.URL = "https://raw.githubusercontent.com/qdm12/files/master/ads-ips.updated"
@@ -81,8 +108,8 @@ const (
SurveillanceBlockListIPsURL models.URL = "https://raw.githubusercontent.com/qdm12/files/master/surveillance-ips.updated"
)
// DNS certificates to fetch
// TODO obtain from source directly, see qdm12/updated)
// DNS certificates to fetch.
// TODO obtain from source directly, see qdm12/updated).
const (
NamedRootURL models.URL = "https://raw.githubusercontent.com/qdm12/files/master/named.root.updated"
RootKeyURL models.URL = "https://raw.githubusercontent.com/qdm12/files/master/root.key.updated"
+2 -1
View File
@@ -7,6 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
MullvadCertificate = "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"
)
@@ -53,7 +54,7 @@ func MullvadISPChoices() (choices []string) {
return choices
}
//nolint:dupl
//nolint:dupl,lll
func MullvadServers() []models.MullvadServer {
return []models.MullvadServer{
{Country: "Albania", City: "Tirana", ISP: "iRegister", Owned: false, IPs: []net.IP{{31, 171, 154, 210}}, IPsV6: []net.IP{{0x2a, 0x4, 0x27, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f}}},
+2
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
NordvpnCertificate = "MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQMA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2MDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNVBAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQFkfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJrXMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kUeQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOVskEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXuMP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRRhPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42sQt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvyWEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6MyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiSTLWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8gnQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/k6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2SDxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/pyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAok0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp+RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhdNdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVawDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojCVPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0SPApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA=="
NordvpnOpenvpnStaticKeyV1 = "e685bdaf659a25a200e2b9e39e51ff030fc72cf1ce07232bd8b2be5e6c670143f51e937e670eee09d4f2ea5a6e4e69965db852c275351b86fc4ca892d78ae002d6f70d029bd79c4d1c26cf14e9588033cf639f8a74809f29f72b9d58f9b8f5fefc7938eade40e9fed6cb92184abb2cc10eb1a296df243b251df0643d53724cdb5a92a1d6cb817804c4a9319b57d53be580815bcfcb2df55018cc83fc43bc7ff82d51f9b88364776ee9d12fc85cc7ea5b9741c4f598c485316db066d52db4540e212e1518a9bd4828219e24b20d88f598a196c9de96012090e333519ae18d35099427e7b372d348d352dc4c85e18cd4b93f8a56ddb2e64eb67adfc9b337157ff4"
@@ -20,6 +21,7 @@ func NordvpnRegionChoices() (choices []string) {
return choices
}
//nolint:gomnd
func NordvpnServers() []models.NordvpnServer {
return []models.NordvpnServer{
{Region: "Albania", Number: 18, TCP: true, UDP: true, IP: net.IP{31, 171, 152, 19}},
+12 -12
View File
@@ -5,28 +5,28 @@ import (
)
const (
// UnboundConf is the file path to the Unbound configuration file
// UnboundConf is the file path to the Unbound configuration file.
UnboundConf models.Filepath = "/etc/unbound/unbound.conf"
// ResolvConf is the file path to the system resolv.conf file
// ResolvConf is the file path to the system resolv.conf file.
ResolvConf models.Filepath = "/etc/resolv.conf"
// CACertificates is the file path to the CA certificates file
// CACertificates is the file path to the CA certificates file.
CACertificates models.Filepath = "/etc/ssl/certs/ca-certificates.crt"
// OpenVPNAuthConf is the file path to the OpenVPN auth file
// OpenVPNAuthConf is the file path to the OpenVPN auth file.
OpenVPNAuthConf models.Filepath = "/etc/openvpn/auth.conf"
// OpenVPNConf is the file path to the OpenVPN client configuration file
// OpenVPNConf is the file path to the OpenVPN client configuration file.
OpenVPNConf models.Filepath = "/etc/openvpn/target.ovpn"
// PIAPortForward is the file path to the port forwarding JSON information for PIA v4 servers
// PIAPortForward is the file path to the port forwarding JSON information for PIA v4 servers.
PIAPortForward models.Filepath = "/gluetun/piaportforward.json"
// TunnelDevice is the file path to tun device
// TunnelDevice is the file path to tun device.
TunnelDevice models.Filepath = "/dev/net/tun"
// NetRoute is the path to the file containing information on the network route
// NetRoute is the path to the file containing information on the network route.
NetRoute models.Filepath = "/proc/net/route"
// TinyProxyConf is the filepath to the tinyproxy configuration file
// TinyProxyConf is the filepath to the tinyproxy configuration file.
TinyProxyConf models.Filepath = "/etc/tinyproxy/tinyproxy.conf"
// ShadowsocksConf is the filepath to the shadowsocks configuration file
// ShadowsocksConf is the filepath to the shadowsocks configuration file.
ShadowsocksConf models.Filepath = "/etc/shadowsocks.json"
// RootHints is the filepath to the root.hints file used by Unbound
// RootHints is the filepath to the root.hints file used by Unbound.
RootHints models.Filepath = "/etc/unbound/root.hints"
// RootKey is the filepath to the root.key file used by Unbound
// RootKey is the filepath to the root.key file used by Unbound.
RootKey models.Filepath = "/etc/unbound/root.key"
)
+8
View File
@@ -0,0 +1,8 @@
package constants
import "os"
const (
UserReadPermission os.FileMode = 0400
AllReadWritePermissions os.FileMode = 0666
)
+3
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
PIAEncryptionPresetNormal = "normal"
PIAEncryptionPresetStrong = "strong"
@@ -24,6 +25,7 @@ func PIAGeoChoices() (choices []string) {
return choices
}
//nolint:lll
func PIAServers() []models.PIAServer {
return []models.PIAServer{
{Region: "AU Melbourne", PortForward: true, OpenvpnUDP: models.PIAServerOpenvpn{CN: "melbourne405", IPs: []net.IP{{103, 2, 198, 108}}}, OpenvpnTCP: models.PIAServerOpenvpn{CN: "melbourne405", IPs: []net.IP{{103, 2, 198, 103}}}},
@@ -133,6 +135,7 @@ func PIAOldGeoChoices() (choices []string) {
return choices
}
//nolint:lll
func PIAOldServers() []models.PIAOldServer {
return []models.PIAOldServer{
{Region: "AU Melbourne", IPs: []net.IP{{27, 50, 82, 131}, {43, 250, 204, 105}, {43, 250, 204, 107}, {43, 250, 204, 109}, {43, 250, 204, 111}, {43, 250, 204, 113}, {43, 250, 204, 115}, {43, 250, 204, 117}, {43, 250, 204, 119}, {43, 250, 204, 123}, {43, 250, 204, 125}}},
+2
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
PurevpnCertificateAuthority = "MIIE6DCCA9CgAwIBAgIJAMjXFoeo5uSlMA0GCSqGSIb3DQEBCwUAMIGoMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxGDAWBgNVBAoTD1NlY3VyZS1TZXJ2ZXJDQTELMAkGA1UECxMCSVQxGDAWBgNVBAMTD1NlY3VyZS1TZXJ2ZXJDQTEYMBYGA1UEKRMPU2VjdXJlLVNlcnZlckNBMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWluMB4XDTE2MDExNTE1MzQwOVoXDTI2MDExMjE1MzQwOVowgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDluufhyLlyvXzPUL16kAWAdivl1roQv3QHbuRshyKacf/1Er1JqEbtW3Mx9Fvr/u27qU2W8lQI6DaJhU2BfijPe/KHkib55mvHzIVvoexxya26nk79F2c+d9PnuuMdThWQO3El5a/i2AASnM7T7piIBT2WRZW2i8RbfJaTT7G7LP7OpMKIV1qyBg/cWoO7cIWQW4jmzqrNryIkF0AzStLN1DxvnQZwgXBGv0CwuAkfQuNSLu0PQgPp0PhdukNZFllv5D29IhPr0Z+kwPtrAgPQo+lHlOBHBMUpDT4XChTPeAvMaUSBsqmonAE8UUHEabWrqYN/kWNHCNkYXMkiVmK1AgMBAAGjggERMIIBDTAdBgNVHQ4EFgQU456ijsFrYnzHBShLAPpOUqQ+Z2cwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvga2HMwOtUxWH/inL2qk24KX2pxLg939JNhqoyNrUpbDHag5xPQYXUmUpKrNJZ0z+o/ZnNUPHydTSXE7Z7E45J0GDN5E7g4pakndKnDLSjp03NgGsCGW+cXnz6UBPM5FStFvGdDeModeSUyoS9fjk+mYROvmiy5EiVDP91sKGcPLR7Ym0M7zl2aaqV7bb98HmMoBOxpeZQinof67nKrCsgz/xjktWFgcmPl4/PQSsmqQD0fTtWxGuRX+FzwvF2OCMCAJgp1RqJNlk2g50/kBIoJVPPCfjDFeDU5zGaWGSQ9+z1L6/z7VXdjUiHL0ouOcHwbiS4ZjTr9nMn6WdAHU2"
PurevpnCertificate = "MIIEnzCCA4egAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBqDELMAkGA1UEBhMCSEsxEDAOBgNVBAgTB0NlbnRyYWwxCzAJBgNVBAcTAkhLMRgwFgYDVQQKEw9TZWN1cmUtU2VydmVyQ0ExCzAJBgNVBAsTAklUMRgwFgYDVQQDEw9TZWN1cmUtU2VydmVyQ0ExGDAWBgNVBCkTD1NlY3VyZS1TZXJ2ZXJDQTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjAeFw0xNjAxMTUxNjE1MzhaFw0yNjAxMTIxNjE1MzhaMIGdMQswCQYDVQQGEwJISzEQMA4GA1UECBMHQ2VudHJhbDELMAkGA1UEBxMCSEsxFjAUBgNVBAoTDVNlY3VyZS1DbGllbnQxCzAJBgNVBAsTAklUMRYwFAYDVQQDEw1TZWN1cmUtQ2xpZW50MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxsnyn4v6xxDPnuDaYS0b9M1N8nxgg7OBPBlK+FWRxdTQ8yxt5U5CZGm7riVp7fya2J2iPZIgmHQEv/KbxztsHAVlYSfYYlalrnhEL3bDP2tY+N43AwB1k5BrPq2s1pPLT2XG951drDKG4PUuFHUP1sHzW5oQlfVCmxgIMAP8OYkCAwEAAaOCAV8wggFbMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU9MwUnUDbQKKZKjoeieD2OD5NlAEwgd0GA1UdIwSB1TCB0oAU456ijsFrYnzHBShLAPpOUqQ+Z2ehga6kgaswgagxCzAJBgNVBAYTAkhLMRAwDgYDVQQIEwdDZW50cmFsMQswCQYDVQQHEwJISzEYMBYGA1UEChMPU2VjdXJlLVNlcnZlckNBMQswCQYDVQQLEwJJVDEYMBYGA1UEAxMPU2VjdXJlLVNlcnZlckNBMRgwFgYDVQQpEw9TZWN1cmUtU2VydmVyQ0ExHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQDI1xaHqObkpTATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBAFyFo2VUX/UFixsdPdK9/Yt6mkCWc+XS1xbapGXXb9U1d+h1iBCIV9odUHgNCXWpz1hR5Uu/OCzaZ0asLE4IFMZlQmJs8sMT0c1tfPPGW45vxbL0lhqnQ8PNcBH7huNK7VFjUh4szXRKmaQPaM4S91R3L4CaNfVeHfAg7mN2m9Zn5Gto1Q1/CFMGKu2hxwGEw5p+X1czBWEvg/O09ckx/ggkkI1NcZsNiYQ+6Pz8DdGGX3+05YwLZu94+O6iIMrzxl/il0eK83g3YPbsOrASARvw6w/8sOnJCK5eOacl21oww875KisnYdWjHB1FiI+VzQ1/gyoDsL5kPTJVuu2CoG8="
@@ -40,6 +41,7 @@ func PurevpnCityChoices() (choices []string) {
return choices
}
//nolint:lll
func PurevpnServers() []models.PurevpnServer {
return []models.PurevpnServer{
{Region: "Africa", Country: "Algeria", City: "Algiers", IPs: []net.IP{{172, 94, 64, 2}}},
+1
View File
@@ -3,6 +3,7 @@ package constants
import "github.com/qdm12/gluetun/internal/models"
func GetAllServers() (allServers models.AllServers) {
//nolint:gomnd
return models.AllServers{
Version: 1, // used for migration of the top level scheme
Cyberghost: models.CyberghostServers{
+140 -25
View File
@@ -1,8 +1,8 @@
package constants
import (
"crypto/md5" //nolint:gosec
"encoding/base64"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"testing"
@@ -11,49 +11,164 @@ import (
"github.com/stretchr/testify/assert"
)
func digestServerModelVersion(t *testing.T, server interface{}, version uint16) string { //nolint:unparam
func digestServerModelVersion(t *testing.T, server interface{}, version uint16) string {
bytes, err := json.Marshal(server)
if err != nil {
t.Fatal(err)
}
bytes = append(bytes, []byte(fmt.Sprintf("%d", version))...)
arr := md5.Sum(bytes) //nolint:gosec
return base64.RawStdEncoding.EncodeToString(arr[:])
arr := sha256.Sum256(bytes)
hexString := hex.EncodeToString(arr[:])
if len(hexString) > 8 {
hexString = hexString[:8]
}
return hexString
}
func Test_versions(t *testing.T) {
t.Parallel()
allServers := GetAllServers()
assert.Equal(t, "e8eLGRpb1sNX8mDNPOjA6g", digestServerModelVersion(t, models.CyberghostServer{}, allServers.Cyberghost.Version))
assert.Equal(t, "4yL2lFcxXd/l1ByxBQ7d3g", digestServerModelVersion(t, models.MullvadServer{}, allServers.Mullvad.Version))
assert.Equal(t, "fjzfUqJH0KvetGRdZYEtOg", digestServerModelVersion(t, models.NordvpnServer{}, allServers.Nordvpn.Version))
assert.Equal(t, "1Ux7clCAJI6fwj0O61Dtpg", digestServerModelVersion(t, models.PIAServer{}, allServers.Pia.Version))
assert.Equal(t, "EZ/SBXQOCS/iJU7A9yc7vg", digestServerModelVersion(t, models.PurevpnServer{}, allServers.Purevpn.Version))
assert.Equal(t, "7yfMpHwzRpEngA/6nYsNag", digestServerModelVersion(t, models.SurfsharkServer{}, allServers.Surfshark.Version))
assert.Equal(t, "7yfMpHwzRpEngA/6nYsNag", digestServerModelVersion(t, models.VyprvpnServer{}, allServers.Vyprvpn.Version))
assert.Equal(t, "7yfMpHwzRpEngA/6nYsNag", digestServerModelVersion(t, models.WindscribeServer{}, allServers.Windscribe.Version))
const format = "you forgot to update the version for %s"
testCases := map[string]struct {
model interface{}
version uint16
digest string
}{
"Cyberghost": {
model: models.CyberghostServer{},
version: allServers.Cyberghost.Version,
digest: "fd6242bb",
},
"Mullvad": {
model: models.MullvadServer{},
version: allServers.Mullvad.Version,
digest: "665e9dc1",
},
"Nordvpn": {
model: models.NordvpnServer{},
version: allServers.Nordvpn.Version,
digest: "040de8d0",
},
"Private Internet Access": {
model: models.PIAServer{},
version: allServers.Pia.Version,
digest: "f1e01afe",
},
"Private Internet Access Old": {
model: models.PIAOldServer{},
version: allServers.PiaOld.Version,
digest: "4e25ce4a",
},
"Purevpn": {
model: models.PurevpnServer{},
version: allServers.Purevpn.Version,
digest: "cc1a2219",
},
"Surfshark": {
model: models.SurfsharkServer{},
version: allServers.Surfshark.Version,
digest: "042bef64",
},
"Vyprvpn": {
model: models.VyprvpnServer{},
version: allServers.Vyprvpn.Version,
digest: "042bef64",
},
"Windscribe": {
model: models.WindscribeServer{},
version: allServers.Windscribe.Version,
digest: "042bef64",
},
}
for name, testCase := range testCases {
name := name
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
digest := digestServerModelVersion(t, testCase.model, testCase.version)
failureMessage := fmt.Sprintf(format, name)
assert.Equal(t, testCase.digest, digest, failureMessage)
})
}
}
func digestServersTimestamp(t *testing.T, servers interface{}, timestamp int64) string { //nolint:unparam
func digestServersTimestamp(t *testing.T, servers interface{}, timestamp int64) string {
bytes, err := json.Marshal(servers)
if err != nil {
t.Fatal(err)
}
bytes = append(bytes, []byte(fmt.Sprintf("%d", timestamp))...)
arr := md5.Sum(bytes) //nolint:gosec
return base64.RawStdEncoding.EncodeToString(arr[:])
arr := sha256.Sum256(bytes)
hexString := hex.EncodeToString(arr[:])
if len(hexString) > 8 {
hexString = hexString[:8]
}
return hexString
}
func Test_timestamps(t *testing.T) {
t.Parallel()
allServers := GetAllServers()
assert.Equal(t, "EFMpdq2b9COLevjXmje5zg", digestServersTimestamp(t, allServers.Cyberghost.Servers, allServers.Cyberghost.Timestamp))
assert.Equal(t, "EU4fTzD7jWC9N5kmN5bOEg", digestServersTimestamp(t, allServers.Mullvad.Servers, allServers.Mullvad.Timestamp))
assert.Equal(t, "OLI62FoTf2wis25Nw4FLpg", digestServersTimestamp(t, allServers.Nordvpn.Servers, allServers.Nordvpn.Timestamp))
assert.Equal(t, "beZCOXNWxzrPsUWCyQM99A", digestServersTimestamp(t, allServers.Pia.Servers, allServers.Pia.Timestamp))
assert.Equal(t, "e8mWsWynkSUGiJLvjALRvQ", digestServersTimestamp(t, allServers.PiaOld.Servers, allServers.PiaOld.Timestamp))
assert.Equal(t, "kwJdVWTiBOspfrRwZIA+Sg", digestServersTimestamp(t, allServers.Purevpn.Servers, allServers.Purevpn.Timestamp))
assert.Equal(t, "q28ju2KJqLhrggJTTjXSiw", digestServersTimestamp(t, allServers.Surfshark.Servers, allServers.Surfshark.Timestamp))
assert.Equal(t, "KdIQWi2tYUM4aMXvWfVBEg", digestServersTimestamp(t, allServers.Vyprvpn.Servers, allServers.Vyprvpn.Timestamp))
assert.Equal(t, "faQUVtOnLMVezN0giHSz3Q", digestServersTimestamp(t, allServers.Windscribe.Servers, allServers.Windscribe.Timestamp))
const format = "you forgot to update the timestamp for %s"
testCases := map[string]struct {
servers interface{}
timestamp int64
digest string
}{
"Cyberghost": {
servers: allServers.Cyberghost.Servers,
timestamp: allServers.Cyberghost.Timestamp,
digest: "160631de",
},
"Mullvad": {
servers: allServers.Mullvad.Servers,
timestamp: allServers.Mullvad.Timestamp,
digest: "e1fee56f",
},
"Nordvpn": {
servers: allServers.Nordvpn.Servers,
timestamp: allServers.Nordvpn.Timestamp,
digest: "9fc9a579",
},
"Private Internet Access": {
servers: allServers.Pia.Servers,
timestamp: allServers.Pia.Timestamp,
digest: "1571e777",
},
"Private Internet Access Old": {
servers: allServers.PiaOld.Servers,
timestamp: allServers.PiaOld.Timestamp,
digest: "3566a800",
},
"Purevpn": {
servers: allServers.Purevpn.Servers,
timestamp: allServers.Purevpn.Timestamp,
digest: "cdf9b708",
},
"Surfshark": {
servers: allServers.Surfshark.Servers,
timestamp: allServers.Surfshark.Timestamp,
digest: "79484811",
},
"Vyprvpn": {
servers: allServers.Vyprvpn.Servers,
timestamp: allServers.Vyprvpn.Timestamp,
digest: "1992457c",
},
"Windscribe": {
servers: allServers.Windscribe.Servers,
timestamp: allServers.Windscribe.Timestamp,
digest: "eacad593",
},
}
for name, testCase := range testCases {
name := name
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
digest := digestServersTimestamp(t, testCase.servers, testCase.timestamp)
failureMessage := fmt.Sprintf(format, name)
assert.Equal(t, testCase.digest, digest, failureMessage)
})
}
}
+3 -3
View File
@@ -1,13 +1,13 @@
package constants
const (
// Announcement is a message announcement
// Announcement is a message announcement.
Announcement = "Port forwarding is working for PIA v4 servers"
// AnnouncementExpiration is the expiration date of the announcement in format yyyy-mm-dd
// AnnouncementExpiration is the expiration date of the announcement in format yyyy-mm-dd.
AnnouncementExpiration = "2020-11-15"
)
const (
// IssueLink is the link for users to use to create issues
// IssueLink is the link for users to use to create issues.
IssueLink = "https://github.com/qdm12/gluetun/issues/new"
)
+1
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
SurfsharkCertificate = "MIIFTTCCAzWgAwIBAgIJAMs9S3fqwv+mMA0GCSqGSIb3DQEBCwUAMD0xCzAJBgNVBAYTAlZHMRIwEAYDVQQKDAlTdXJmc2hhcmsxGjAYBgNVBAMMEVN1cmZzaGFyayBSb290IENBMB4XDTE4MDMxNDA4NTkyM1oXDTI4MDMxMTA4NTkyM1owPTELMAkGA1UEBhMCVkcxEjAQBgNVBAoMCVN1cmZzaGFyazEaMBgGA1UEAwwRU3VyZnNoYXJrIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDEGMNj0aisM63oSkmVJyZPaYX7aPsZtzsxo6m6p5Wta3MGASoryRsBuRaH6VVa0fwbI1nw5ubyxkuaNa4v3zHVwuSq6F1p8S811+1YP1av+jqDcMyojH0ujZSHIcb/i5LtaHNXBQ3qN48Cc7sqBnTIIFpmb5HthQ/4pW+a82b1guM5dZHsh7q+LKQDIGmvtMtO1+NEnmj81BApFayiaD1ggvwDI4x7o/Y3ksfWSCHnqXGyqzSFLh8QuQrTmWUm84YHGFxoI1/8AKdIyVoB6BjcaMKtKs/pbctk6vkzmYf0XmGovDKPQF6MwUekchLjB5gSBNnptSQ9kNgnTLqi0OpSwI6ixX52Ksva6UM8P01ZIhWZ6ua/T/tArgODy5JZMW+pQ1A6L0b7egIeghpwKnPRG+5CzgO0J5UE6gv000mqbmC3CbiS8xi2xuNgruAyY2hUOoV9/BuBev8ttE5ZCsJH3YlG6NtbZ9hPc61GiBSx8NJnX5QHyCnfic/X87eST/amZsZCAOJ5v4EPSaKrItt+HrEFWZQIq4fJmHJNNbYvWzCE08AL+5/6Z+lxb/Bm3dapx2zdit3x2e+miGHekuiE8lQWD0rXD4+T+nDRi3X+kyt8Ex/8qRiUfrisrSHFzVMRungIMGdO9O/zCINFrb7wahm4PqU2f12Z9TRCOTXciQIDAQABo1AwTjAdBgNVHQ4EFgQUYRpbQwyDahLMN3F2ony3+UqOYOgwHwYDVR0jBBgwFoAUYRpbQwyDahLMN3F2ony3+UqOYOgwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAn9zV7F/XVnFNZhHFrt0ZS1Yqz+qM9CojLmiyblMFh0p7t+Hh+VKVgMwrz0LwDH4UsOosXA28eJPmech6/bjfymkoXISy/NUSTFpUChGO9RabGGxJsT4dugOw9MPaIVZffny4qYOc/rXDXDSfF2b+303lLPI43y9qoe0oyZ1vtk/UKG75FkWfFUogGNbpOkuz+et5Y0aIEiyg0yh6/l5Q5h8+yom0HZnREHhqieGbkaGKLkyu7zQ4D4tRK/mBhd8nv+09GtPEG+D5LPbabFVxKjBMP4Vp24WuSUOqcGSsURHevawPVBfgmsxf1UCjelaIwngdh6WfNCRXa5QQPQTKubQvkvXONCDdhmdXQccnRX1nJWhPYi0onffvjsWUfztRypsKzX4dvM9k7xnIcGSGEnCC4RCgt1UiZIj7frcCMssbA6vJ9naM0s7JF7N3VKeHJtqe1OCRHMYnWUZt9vrqX6IoIHlZCoLlv39wFW9QNxelcAOCVbD+19MZ0ZXt7LitjIqe7yF5WxDQN4xru087FzQ4Hfj7eH1SNLLyKZkA1eecjmRoi/OoqAt7afSnwtQLtMUc2bQDg6rHt5C0e4dCLqP/9PGZTSJiwmtRHJ/N5qYWIh9ju83APvLm/AGBTR2pXmj9G3KdVOkpIC7L35dI623cSEC3Q3UZutsEm/UplsM="
SurfsharkOpenvpnStaticKeyV1 = "b02cb1d7c6fee5d4f89b8de72b51a8d0c7b282631d6fc19be1df6ebae9e2779e6d9f097058a31c97f57f0c35526a44ae09a01d1284b50b954d9246725a1ead1ff224a102ed9ab3da0152a15525643b2eee226c37041dc55539d475183b889a10e18bb94f079a4a49888da566b99783460ece01daaf93548beea6c827d9674897e7279ff1a19cb092659e8c1860fbad0db4ad0ad5732f1af4655dbd66214e552f04ed8fd0104e1d4bf99c249ac229ce169d9ba22068c6c0ab742424760911d4636aafb4b85f0c952a9ce4275bc821391aa65fcd0d2394f006e3fba0fd34c4bc4ab260f4b45dec3285875589c97d3087c9134d3a3aa2f904512e85aa2dc2202498"
+6 -6
View File
@@ -5,16 +5,16 @@ import (
)
const (
// TinyProxyInfoLevel is the info log level for TinyProxy
// TinyProxyInfoLevel is the info log level for TinyProxy.
TinyProxyInfoLevel models.TinyProxyLogLevel = "Info"
// TinyProxyConnectLevel is the info log level for TinyProxy
// TinyProxyConnectLevel is the info log level for TinyProxy.
TinyProxyConnectLevel models.TinyProxyLogLevel = "Connect"
// TinyProxyNoticeLevel is the info log level for TinyProxy
// TinyProxyNoticeLevel is the info log level for TinyProxy.
TinyProxyNoticeLevel models.TinyProxyLogLevel = "Notice"
// TinyProxyWarnLevel is the warning log level for TinyProxy
// TinyProxyWarnLevel is the warning log level for TinyProxy.
TinyProxyWarnLevel models.TinyProxyLogLevel = "Warning"
// TinyProxyErrorLevel is the error log level for TinyProxy
// TinyProxyErrorLevel is the error log level for TinyProxy.
TinyProxyErrorLevel models.TinyProxyLogLevel = "Error"
// TinyProxyCriticalLevel is the critical log level for TinyProxy
// TinyProxyCriticalLevel is the critical log level for TinyProxy.
TinyProxyCriticalLevel models.TinyProxyLogLevel = "Critical"
)
+11 -11
View File
@@ -5,29 +5,29 @@ import (
)
const (
// PrivateInternetAccess is a VPN provider
// PrivateInternetAccess is a VPN provider.
PrivateInternetAccess models.VPNProvider = "private internet access"
// PrivateInternetAccessOld is the pre summer 2020 PIA provider
// PrivateInternetAccessOld is the pre summer 2020 PIA provider.
PrivateInternetAccessOld models.VPNProvider = "private internet access old"
// Mullvad is a VPN provider
// Mullvad is a VPN provider.
Mullvad models.VPNProvider = "mullvad"
// Windscribe is a VPN provider
// Windscribe is a VPN provider.
Windscribe models.VPNProvider = "windscribe"
// Surfshark is a VPN provider
// Surfshark is a VPN provider.
Surfshark models.VPNProvider = "surfshark"
// Cyberghost is a VPN provider
// Cyberghost is a VPN provider.
Cyberghost models.VPNProvider = "cyberghost"
// Vyprvpn is a VPN provider
// Vyprvpn is a VPN provider.
Vyprvpn models.VPNProvider = "vyprvpn"
// NordVPN is a VPN provider
// NordVPN is a VPN provider.
Nordvpn models.VPNProvider = "nordvpn"
// PureVPN is a VPN provider
// PureVPN is a VPN provider.
Purevpn models.VPNProvider = "purevpn"
)
const (
// TCP is a network protocol (reliable and slower than UDP)
// TCP is a network protocol (reliable and slower than UDP).
TCP models.NetworkProtocol = "tcp"
// UDP is a network protocol (unreliable and faster than TCP)
// UDP is a network protocol (unreliable and faster than TCP).
UDP models.NetworkProtocol = "udp"
)
+1
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
VyprvpnCertificate = "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"
)
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
//nolint:lll
const (
WindscribeCertificate = "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"
WindscribeOpenvpnStaticKeyV1 = "5801926a57ac2ce27e3dfd1dd6ef82042d82bd4f3f0021296f57734f6f1ea714a6623845541c4b0c3dea0a050fe6746cb66dfab14cda27e5ae09d7c155aa554f399fa4a863f0e8c1af787e5c602a801d3a2ec41e395a978d56729457fe6102d7d9e9119aa83643210b33c678f9d4109e3154ac9c759e490cb309b319cf708cae83ddadc3060a7a26564d1a24411cd552fe6620ea16b755697a4fc5e6e9d0cfc0c5c4a1874685429046a424c026db672e4c2c492898052ba59128d46200b40f880027a8b6610a4d559bdc9346d33a0a6b08e75c7fd43192b162bfd0aef0c716b31584827693f676f9a5047123466f0654eade34972586b31c6ce7e395f4b478cb"
@@ -20,7 +21,7 @@ func WindscribeRegionChoices() (choices []string) {
return choices
}
//nolint:dupl
//nolint:lll
func WindscribeServers() []models.WindscribeServer {
return []models.WindscribeServer{
{Region: "Albania", IPs: []net.IP{{31, 171, 152, 179}}},
+4 -2
View File
@@ -9,7 +9,8 @@ import (
"github.com/qdm12/gluetun/internal/constants"
)
func (c *configurator) Start(ctx context.Context, verbosityDetailsLevel uint8) (stdout io.ReadCloser, waitFn func() error, err error) {
func (c *configurator) Start(ctx context.Context, verbosityDetailsLevel uint8) (
stdout io.ReadCloser, waitFn func() error, err error) {
c.logger.Info("starting unbound")
args := []string{"-d", "-c", string(constants.UnboundConf)}
if verbosityDetailsLevel > 0 {
@@ -28,7 +29,8 @@ func (c *configurator) Version(ctx context.Context) (version string, err error)
for _, line := range strings.Split(output, "\n") {
if strings.Contains(line, "Version ") {
words := strings.Fields(line)
if len(words) < 2 {
const minWords = 2
if len(words) < minWords {
continue
}
version = words[1]
+1 -2
View File
@@ -6,12 +6,11 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/golibs/command/mock_command"
"github.com/qdm12/golibs/logging/mock_logging"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/qdm12/gluetun/internal/constants"
)
func Test_Start(t *testing.T) {
+5 -3
View File
@@ -24,11 +24,13 @@ func (c *configurator) MakeUnboundConf(ctx context.Context, settings settings.DN
string(constants.UnboundConf),
lines,
files.Ownership(uid, gid),
files.Permissions(0400))
files.Permissions(constants.UserReadPermission))
}
// MakeUnboundConf generates an Unbound configuration from the user provided settings
func generateUnboundConf(ctx context.Context, settings settings.DNS, client network.Client, logger logging.Logger) (lines []string, warnings []error) {
// MakeUnboundConf generates an Unbound configuration from the user provided settings.
func generateUnboundConf(ctx context.Context, settings settings.DNS,
client network.Client, logger logging.Logger) (
lines []string, warnings []error) {
doIPv6 := "no"
if settings.IPv6 {
doIPv6 = "yes"
+9 -3
View File
@@ -92,9 +92,15 @@ func (l *looper) setEnabled(enabled bool) {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Warn(err)
l.logger.Info("attempting restart in 10 seconds")
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
<-ctx.Done()
const waitDuration = 10 * time.Second
timer := time.NewTimer(waitDuration)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
func (l *looper) waitForFirstStart(ctx context.Context, signalDNSReady func()) {
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/qdm12/gluetun/internal/constants"
)
// UseDNSInternally is to change the Go program DNS only
// UseDNSInternally is to change the Go program DNS only.
func (c *configurator) UseDNSInternally(ip net.IP) {
c.logger.Info("using DNS address %s internally", ip.String())
net.DefaultResolver = &net.Resolver{
@@ -20,7 +20,7 @@ func (c *configurator) UseDNSInternally(ip net.IP) {
}
}
// UseDNSSystemWide changes the nameserver to use for DNS system wide
// UseDNSSystemWide changes the nameserver to use for DNS system wide.
func (c *configurator) UseDNSSystemWide(ip net.IP, keepNameserver bool) error {
c.logger.Info("using DNS address %s system wide", ip.String())
data, err := c.fileManager.ReadFile(string(constants.ResolvConf))
+2 -2
View File
@@ -21,7 +21,7 @@ func (c *configurator) DownloadRootHints(ctx context.Context, uid, gid int) erro
string(constants.RootHints),
content,
files.Ownership(uid, gid),
files.Permissions(0400))
files.Permissions(constants.UserReadPermission))
}
func (c *configurator) DownloadRootKey(ctx context.Context, uid, gid int) error {
@@ -36,5 +36,5 @@ func (c *configurator) DownloadRootKey(ctx context.Context, uid, gid int) error
string(constants.RootKey),
content,
files.Ownership(uid, gid),
files.Permissions(0400))
files.Permissions(constants.UserReadPermission))
}
+3 -4
View File
@@ -7,14 +7,13 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/golibs/files"
"github.com/qdm12/golibs/files/mock_files"
"github.com/qdm12/golibs/logging/mock_logging"
"github.com/qdm12/golibs/network/mock_network"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/qdm12/gluetun/internal/constants"
)
func Test_DownloadRootHints(t *testing.T) { //nolint:dupl
@@ -31,7 +30,7 @@ func Test_DownloadRootHints(t *testing.T) { //nolint:dupl
},
"bad status": {
status: http.StatusBadRequest,
err: fmt.Errorf("HTTP status code is 400 for https://raw.githubusercontent.com/qdm12/files/master/named.root.updated"),
err: fmt.Errorf("HTTP status code is 400 for https://raw.githubusercontent.com/qdm12/files/master/named.root.updated"), //nolint:lll
},
"client error": {
clientErr: fmt.Errorf("error"),
@@ -94,7 +93,7 @@ func Test_DownloadRootKey(t *testing.T) { //nolint:dupl
},
"bad status": {
status: http.StatusBadRequest,
err: fmt.Errorf("HTTP status code is 400 for https://raw.githubusercontent.com/qdm12/files/master/root.key.updated"),
err: fmt.Errorf("HTTP status code is 400 for https://raw.githubusercontent.com/qdm12/files/master/root.key.updated"), //nolint:lll
},
"client error": {
clientErr: fmt.Errorf("error"),
+12 -5
View File
@@ -6,16 +6,23 @@ import (
)
func (c *configurator) WaitForUnbound() (err error) {
const maxTries = 10
const hostToResolve = "github.com"
time.Sleep(300 * time.Millisecond)
for try := 1; try <= maxTries; try++ {
waitDurations := [...]time.Duration{
300 * time.Millisecond,
100 * time.Millisecond,
300 * time.Millisecond,
500 * time.Millisecond,
time.Second,
2 * time.Second,
}
maxTries := len(waitDurations)
for i, waitDuration := range waitDurations {
time.Sleep(waitDuration)
_, err := c.lookupIP(hostToResolve)
if err == nil {
return nil
}
c.logger.Warn("could not resolve %s (try %d of %d): %s", hostToResolve, try, maxTries, err)
time.Sleep(maxTries * 50 * time.Millisecond)
c.logger.Warn("could not resolve %s (try %d of %d): %s", hostToResolve, i+1, maxTries, err)
}
return fmt.Errorf("Unbound does not seem to be working after %d tries", maxTries)
}
+2 -2
View File
@@ -51,7 +51,7 @@ func (c *configurator) disable(ctx context.Context) (err error) {
return nil
}
// To use in defered call when enabling the firewall
// To use in defered call when enabling the firewall.
func (c *configurator) fallbackToDisabled(ctx context.Context) {
if ctx.Err() != nil {
return
@@ -61,7 +61,7 @@ func (c *configurator) fallbackToDisabled(ctx context.Context) {
}
}
func (c *configurator) enable(ctx context.Context) (err error) { //nolint:gocognit
func (c *configurator) enable(ctx context.Context) (err error) {
if err = c.setAllPolicies(ctx, "DROP"); err != nil {
return fmt.Errorf("cannot enable firewall: %w", err)
}
+2 -2
View File
@@ -12,7 +12,7 @@ import (
"github.com/qdm12/golibs/logging"
)
// Configurator allows to change firewall rules and modify network routes
// Configurator allows to change firewall rules and modify network routes.
type Configurator interface {
Version(ctx context.Context) (string, error)
SetEnabled(ctx context.Context, enabled bool) (err error)
@@ -45,7 +45,7 @@ type configurator struct { //nolint:maligned
stateMutex sync.Mutex
}
// NewConfigurator creates a new Configurator instance
// NewConfigurator creates a new Configurator instance.
func NewConfigurator(logger logging.Logger, routing routing.Routing, fileManager files.FileManager) Configurator {
return &configurator{
commander: command.NewCommander(),
+15 -9
View File
@@ -32,14 +32,15 @@ func flipRule(rule string) string {
return rule
}
// Version obtains the version of the installed iptables
// Version obtains the version of the installed iptables.
func (c *configurator) Version(ctx context.Context) (string, error) {
output, err := c.commander.Run(ctx, "iptables", "--version")
if err != nil {
return "", err
}
words := strings.Fields(output)
if len(words) < 2 {
const minWords = 2
if len(words) < minWords {
return "", fmt.Errorf("iptables --version: output is too short: %q", output)
}
return words[1], nil
@@ -106,34 +107,39 @@ func (c *configurator) acceptEstablishedRelatedTraffic(ctx context.Context, remo
})
}
func (c *configurator) acceptOutputTrafficToVPN(ctx context.Context, defaultInterface string, connection models.OpenVPNConnection, remove bool) error {
func (c *configurator) acceptOutputTrafficToVPN(ctx context.Context,
defaultInterface string, connection models.OpenVPNConnection, remove bool) error {
return c.runIptablesInstruction(ctx,
fmt.Sprintf("%s OUTPUT -d %s -o %s -p %s -m %s --dport %d -j ACCEPT",
appendOrDelete(remove), connection.IP, defaultInterface, connection.Protocol, connection.Protocol, connection.Port))
}
func (c *configurator) acceptInputFromSubnetToSubnet(ctx context.Context, intf string, sourceSubnet, destinationSubnet net.IPNet, remove bool) error {
func (c *configurator) acceptInputFromSubnetToSubnet(ctx context.Context,
intf string, sourceSubnet, destinationSubnet net.IPNet, remove bool) error {
interfaceFlag := "-i " + intf
if intf == "*" { // all interfaces
interfaceFlag = ""
}
return c.runIptablesInstruction(ctx, fmt.Sprintf(
"%s INPUT %s -s %s -d %s -j ACCEPT", appendOrDelete(remove), interfaceFlag, sourceSubnet.String(), destinationSubnet.String(),
"%s INPUT %s -s %s -d %s -j ACCEPT",
appendOrDelete(remove), interfaceFlag, sourceSubnet.String(), destinationSubnet.String(),
))
}
// Thanks to @npawelek
func (c *configurator) acceptOutputFromSubnetToSubnet(ctx context.Context, intf string, sourceSubnet, destinationSubnet net.IPNet, remove bool) error {
// Thanks to @npawelek.
func (c *configurator) acceptOutputFromSubnetToSubnet(ctx context.Context,
intf string, sourceSubnet, destinationSubnet net.IPNet, remove bool) error {
interfaceFlag := "-o " + intf
if intf == "*" { // all interfaces
interfaceFlag = ""
}
return c.runIptablesInstruction(ctx, fmt.Sprintf(
"%s OUTPUT %s -s %s -d %s -j ACCEPT", appendOrDelete(remove), interfaceFlag, sourceSubnet.String(), destinationSubnet.String(),
"%s OUTPUT %s -s %s -d %s -j ACCEPT",
appendOrDelete(remove), interfaceFlag, sourceSubnet.String(), destinationSubnet.String(),
))
}
// Used for port forwarding, with intf set to tun
// Used for port forwarding, with intf set to tun.
func (c *configurator) acceptInputToPort(ctx context.Context, intf string, port uint16, remove bool) error {
interfaceFlag := "-i " + intf
if intf == "*" { // all interfaces
+1 -1
View File
@@ -124,7 +124,7 @@ func (c *configurator) addSubnets(ctx context.Context, subnets []net.IPNet, defa
return nil
}
// updateSubnetRoutes does not return an error in order to try to run as many route commands as possible
// updateSubnetRoutes does not return an error in order to try to run as many route commands as possible.
func (c *configurator) updateSubnetRoutes(ctx context.Context, oldSubnets, newSubnets []net.IPNet) {
subnetsToAdd := findSubnetsToAdd(oldSubnets, newSubnets)
subnetsToRemove := findSubnetsToRemove(oldSubnets, newSubnets)
+4 -2
View File
@@ -9,7 +9,8 @@ func FormatDuration(duration time.Duration) string {
switch {
case duration < time.Minute:
seconds := int(duration.Round(time.Second).Seconds())
if seconds < 2 {
const two = 2
if seconds < two {
return fmt.Sprintf("%d second", seconds)
}
return fmt.Sprintf("%d seconds", seconds)
@@ -23,7 +24,8 @@ func FormatDuration(duration time.Duration) string {
hours := int(duration.Truncate(time.Hour).Hours())
return fmt.Sprintf("%d hours", hours)
default:
days := int(duration.Truncate(time.Hour).Hours() / 24)
const hoursInDay = 24
days := int(duration.Truncate(time.Hour).Hours() / hoursInDay)
return fmt.Sprintf("%d days", days)
}
}
+1
View File
@@ -10,6 +10,7 @@ import (
"github.com/qdm12/golibs/logging"
)
//nolint:lll
var regularExpressions = struct { //nolint:gochecknoglobals
unboundPrefix *regexp.Regexp
shadowsocksPrefix *regexp.Regexp
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"github.com/qdm12/gluetun/internal/constants"
)
// Splash returns the welcome spash message
// Splash returns the welcome spash message.
func Splash(version, commit, buildDate string) string {
lines := title()
lines = append(lines, "")
+8 -8
View File
@@ -6,21 +6,21 @@ import (
)
type (
// VPNDevice is the device name used to tunnel using Openvpn
// VPNDevice is the device name used to tunnel using Openvpn.
VPNDevice string
// DNSProvider is a DNS over TLS server provider name
// DNSProvider is a DNS over TLS server provider name.
DNSProvider string
// DNSHost is the DNS host to use for TLS validation
// DNSHost is the DNS host to use for TLS validation.
DNSHost string
// URL is an HTTP(s) URL address
// URL is an HTTP(s) URL address.
URL string
// Filepath is a local filesytem file path
// Filepath is a local filesytem file path.
Filepath string
// TinyProxyLogLevel is the log level for TinyProxy
// TinyProxyLogLevel is the log level for TinyProxy.
TinyProxyLogLevel string
// VPNProvider is the name of the VPN provider to be used
// VPNProvider is the name of the VPN provider to be used.
VPNProvider string
// NetworkProtocol contains the network protocol to be used to communicate with the VPN servers
// NetworkProtocol contains the network protocol to be used to communicate with the VPN servers.
NetworkProtocol string
)
+1 -1
View File
@@ -2,7 +2,7 @@ package models
import "net"
// DNSProviderData contains information for a DNS provider
// DNSProviderData contains information for a DNS provider.
type DNSProviderData struct {
IPs []net.IP
SupportsTLS bool
+3 -3
View File
@@ -6,7 +6,7 @@ import (
"strings"
)
// ProviderSettings contains settings specific to a VPN provider
// ProviderSettings contains settings specific to a VPN provider.
type ProviderSettings struct {
Name VPNProvider `json:"name"`
ServerSelection ServerSelection `json:"serverSelection"`
@@ -14,7 +14,7 @@ type ProviderSettings struct {
PortForwarding PortForwarding `json:"portForwarding"`
}
type ServerSelection struct { //nolint:maligned
type ServerSelection struct {
// Common
Protocol NetworkProtocol `json:"networkProtocol"`
TargetIP net.IP `json:"targetIP,omitempty"`
@@ -49,7 +49,7 @@ type ExtraConfigOptions struct {
OpenVPNIPv6 bool `json:"openvpnIPv6"` // Mullvad
}
// PortForwarding contains settings for port forwarding
// PortForwarding contains settings for port forwarding.
type PortForwarding struct {
Enabled bool `json:"enabled"`
Filepath Filepath `json:"filepath"`
+2
View File
@@ -47,6 +47,7 @@ func Test_MullvadServer_String(t *testing.T) {
ISP: "not spying on you",
Owned: true,
},
//nolint:lll
s: `{Country: "That Country", City: "That City", ISP: "not spying on you", Owned: true, IPs: []net.IP{{1, 1, 1, 1}}, IPsV6: []net.IP{{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1}}}`,
},
}
@@ -127,6 +128,7 @@ func Test_stringifyIPs(t *testing.T) {
{0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1},
{0, 0, 0, 0},
},
//nolint:lll
s: "[]net.IP{{10, 16, 54, 25}, {0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1}, {}}",
},
}
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"github.com/qdm12/golibs/files"
)
// WriteAuthFile writes the OpenVPN auth file to disk with the right permissions
// WriteAuthFile writes the OpenVPN auth file to disk with the right permissions.
func (c *configurator) WriteAuthFile(user, password string, uid, gid int) error {
exists, err := c.fileManager.FileExists(string(constants.OpenVPNAuthConf))
if err != nil {
@@ -27,5 +27,5 @@ func (c *configurator) WriteAuthFile(user, password string, uid, gid int) error
string(constants.OpenVPNAuthConf),
[]string{user, password},
files.Ownership(uid, gid),
files.Permissions(0400))
files.Permissions(constants.UserReadPermission))
}
+2 -1
View File
@@ -22,7 +22,8 @@ func (c *configurator) Version(ctx context.Context) (string, error) {
}
firstLine := strings.Split(output, "\n")[0]
words := strings.Fields(firstLine)
if len(words) < 2 {
const minWords = 2
if len(words) < minWords {
return "", fmt.Errorf("openvpn --version: first line is too short: %q", firstLine)
}
return words[1], nil
+13 -6
View File
@@ -131,7 +131,8 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
settings.Auth,
settings.Provider.ExtraConfigOptions,
)
if err := l.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(l.uid, l.gid), files.Permissions(0400)); err != nil {
if err := l.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines,
files.Ownership(l.uid, l.gid), files.Permissions(constants.UserReadPermission)); err != nil {
l.logger.Error(err)
l.cancel()
return
@@ -200,14 +201,20 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Error(err)
l.logger.Info("retrying in 30 seconds")
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel() // just for the linter
<-ctx.Done()
const waitTime = 30 * time.Second
l.logger.Info("retrying in %s", waitTime)
timer := time.NewTimer(waitTime)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
// portForward is a blocking operation which may or may not be infinite.
// You should therefore always call it in a goroutine
// You should therefore always call it in a goroutine.
func (l *looper) portForward(ctx context.Context, wg *sync.WaitGroup,
providerConf provider.Provider, client *http.Client, gateway net.IP) {
defer wg.Done()
+6 -2
View File
@@ -8,7 +8,7 @@ import (
"golang.org/x/sys/unix"
)
// CheckTUN checks the tunnel device is present and accessible
// CheckTUN checks the tunnel device is present and accessible.
func (c *configurator) CheckTUN() error {
c.logger.Info("checking for device %s", constants.TunnelDevice)
f, err := c.openFile(string(constants.TunnelDevice), os.O_RDWR, 0)
@@ -26,7 +26,11 @@ func (c *configurator) CreateTUN() error {
if err := c.fileManager.CreateDir("/dev/net"); err != nil {
return err
}
dev := c.mkDev(10, 200)
const (
major = 10
minor = 200
)
dev := c.mkDev(major, minor)
if err := c.mkNod(string(constants.TunnelDevice), unix.S_IFCHR, int(dev)); err != nil {
return err
}
+5 -4
View File
@@ -8,21 +8,22 @@ import (
)
// GetCyberghostGroup obtains the server group for the Cyberghost server from the
// environment variable CYBERGHOST_GROUP
// environment variable CYBERGHOST_GROUP.
func (p *reader) GetCyberghostGroup() (group string, err error) {
s, err := p.envParams.GetValueIfInside("CYBERGHOST_GROUP", constants.CyberghostGroupChoices(), libparams.Default("Premium UDP Europe"))
s, err := p.envParams.GetValueIfInside("CYBERGHOST_GROUP",
constants.CyberghostGroupChoices(), libparams.Default("Premium UDP Europe"))
return s, err
}
// GetCyberghostRegions obtains the country names for the Cyberghost servers from the
// environment variable REGION
// environment variable REGION.
func (p *reader) GetCyberghostRegions() (regions []string, err error) {
choices := append(constants.CyberghostRegionChoices(), "")
return p.envParams.GetCSVInPossibilities("REGION", choices)
}
// GetCyberghostClientKey obtains the one line client key to use for openvpn from the
// environment variable CLIENT_KEY
// environment variable CLIENT_KEY.
func (p *reader) GetCyberghostClientKey() (clientKey string, err error) {
clientKey, err = p.envParams.GetEnv("CLIENT_KEY", libparams.CaseSensitiveValue())
if err != nil {
+19 -17
View File
@@ -12,13 +12,13 @@ import (
)
// GetDNSOverTLS obtains if the DNS over TLS should be enabled
// from the environment variable DOT
// from the environment variable DOT.
func (r *reader) GetDNSOverTLS() (DNSOverTLS bool, err error) { //nolint:gocritic
return r.envParams.GetOnOff("DOT", libparams.Default("on"))
}
// GetDNSOverTLSProviders obtains the DNS over TLS providers to use
// from the environment variable DOT_PROVIDERS
// from the environment variable DOT_PROVIDERS.
func (r *reader) GetDNSOverTLSProviders() (providers []models.DNSProvider, err error) {
s, err := r.envParams.GetEnv("DOT_PROVIDERS", libparams.Default("cloudflare"))
if err != nil {
@@ -27,7 +27,9 @@ func (r *reader) GetDNSOverTLSProviders() (providers []models.DNSProvider, err e
for _, word := range strings.Split(s, ",") {
provider := models.DNSProvider(word)
switch provider {
case constants.Cloudflare, constants.Google, constants.Quad9, constants.Quadrant, constants.CleanBrowsing, constants.SecureDNS, constants.LibreDNS:
case constants.Cloudflare, constants.Google, constants.Quad9,
constants.Quadrant, constants.CleanBrowsing, constants.SecureDNS,
constants.LibreDNS:
providers = append(providers, provider)
default:
return nil, fmt.Errorf("DNS over TLS provider %q is not valid", provider)
@@ -37,55 +39,55 @@ func (r *reader) GetDNSOverTLSProviders() (providers []models.DNSProvider, err e
}
// GetDNSOverTLSVerbosity obtains the verbosity level to use for Unbound
// from the environment variable DOT_VERBOSITY
// from the environment variable DOT_VERBOSITY.
func (r *reader) GetDNSOverTLSVerbosity() (verbosityLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VERBOSITY", 0, 5, libparams.Default("1"))
return uint8(n), err
}
// GetDNSOverTLSVerbosityDetails obtains the log level to use for Unbound
// from the environment variable DOT_VERBOSITY_DETAILS
// from the environment variable DOT_VERBOSITY_DETAILS.
func (r *reader) GetDNSOverTLSVerbosityDetails() (verbosityDetailsLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VERBOSITY_DETAILS", 0, 4, libparams.Default("0"))
return uint8(n), err
}
// GetDNSOverTLSValidationLogLevel obtains the log level to use for Unbound DOT validation
// from the environment variable DOT_VALIDATION_LOGLEVEL
// from the environment variable DOT_VALIDATION_LOGLEVEL.
func (r *reader) GetDNSOverTLSValidationLogLevel() (validationLogLevel uint8, err error) {
n, err := r.envParams.GetEnvIntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, libparams.Default("0"))
return uint8(n), err
}
// GetDNSMaliciousBlocking obtains if malicious hostnames/IPs should be blocked
// from being resolved by Unbound, using the environment variable BLOCK_MALICIOUS
// from being resolved by Unbound, using the environment variable BLOCK_MALICIOUS.
func (r *reader) GetDNSMaliciousBlocking() (blocking bool, err error) {
return r.envParams.GetOnOff("BLOCK_MALICIOUS", libparams.Default("on"))
}
// GetDNSSurveillanceBlocking obtains if surveillance hostnames/IPs should be blocked
// from being resolved by Unbound, using the environment variable BLOCK_SURVEILLANCE
// and BLOCK_NSA for retrocompatibility
// and BLOCK_NSA for retrocompatibility.
func (r *reader) GetDNSSurveillanceBlocking() (blocking bool, err error) {
// Retro-compatibility
s, err := r.envParams.GetEnv("BLOCK_NSA")
if err != nil {
return false, err
} else if len(s) != 0 {
r.logger.Warn("You are using the old environment variable BLOCK_NSA, please consider changing it to BLOCK_SURVEILLANCE")
r.logger.Warn("You are using the old environment variable BLOCK_NSA, please consider changing it to BLOCK_SURVEILLANCE") //nolint:lll
return r.envParams.GetOnOff("BLOCK_NSA", libparams.Compulsory())
}
return r.envParams.GetOnOff("BLOCK_SURVEILLANCE", libparams.Default("off"))
}
// GetDNSAdsBlocking obtains if ads hostnames/IPs should be blocked
// from being resolved by Unbound, using the environment variable BLOCK_ADS
// from being resolved by Unbound, using the environment variable BLOCK_ADS.
func (r *reader) GetDNSAdsBlocking() (blocking bool, err error) {
return r.envParams.GetOnOff("BLOCK_ADS", libparams.Default("off"))
}
// GetDNSUnblockedHostnames obtains a list of hostnames to unblock from block lists
// from the comma separated list for the environment variable UNBLOCK
// from the comma separated list for the environment variable UNBLOCK.
func (r *reader) GetDNSUnblockedHostnames() (hostnames []string, err error) {
s, err := r.envParams.GetEnv("UNBLOCK")
if err != nil {
@@ -103,13 +105,13 @@ func (r *reader) GetDNSUnblockedHostnames() (hostnames []string, err error) {
}
// GetDNSOverTLSCaching obtains if Unbound caching should be enable or not
// from the environment variable DOT_CACHING
// from the environment variable DOT_CACHING.
func (r *reader) GetDNSOverTLSCaching() (caching bool, err error) {
return r.envParams.GetOnOff("DOT_CACHING")
}
// GetDNSOverTLSPrivateAddresses obtains if Unbound caching should be enable or not
// from the environment variable DOT_PRIVATE_ADDRESS
// from the environment variable DOT_PRIVATE_ADDRESS.
func (r *reader) GetDNSOverTLSPrivateAddresses() (privateAddresses []string, err error) {
s, err := r.envParams.GetEnv("DOT_PRIVATE_ADDRESS")
if err != nil {
@@ -129,13 +131,13 @@ func (r *reader) GetDNSOverTLSPrivateAddresses() (privateAddresses []string, err
}
// GetDNSOverTLSIPv6 obtains if Unbound should resolve ipv6 addresses using ipv6 DNS over TLS
// servers from the environment variable DOT_IPV6
// servers from the environment variable DOT_IPV6.
func (r *reader) GetDNSOverTLSIPv6() (ipv6 bool, err error) {
return r.envParams.GetOnOff("DOT_IPV6", libparams.Default("off"))
}
// GetDNSUpdatePeriod obtains the period to use to update the block lists and cryptographic files
// and restart Unbound from the environment variable DNS_UPDATE_PERIOD
// and restart Unbound from the environment variable DNS_UPDATE_PERIOD.
func (r *reader) GetDNSUpdatePeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("DNS_UPDATE_PERIOD", libparams.Default("24h"))
if err != nil {
@@ -145,7 +147,7 @@ func (r *reader) GetDNSUpdatePeriod() (period time.Duration, err error) {
}
// GetDNSPlaintext obtains the plaintext DNS address to use if DNS over TLS is disabled
// from the environment variable DNS_PLAINTEXT_ADDRESS
// from the environment variable DNS_PLAINTEXT_ADDRESS.
func (r *reader) GetDNSPlaintext() (ip net.IP, err error) {
s, err := r.envParams.GetEnv("DNS_PLAINTEXT_ADDRESS", libparams.Default("1.1.1.1"))
if err != nil {
@@ -159,7 +161,7 @@ func (r *reader) GetDNSPlaintext() (ip net.IP, err error) {
}
// GetDNSKeepNameserver obtains if the nameserver present in /etc/resolv.conf
// should be kept instead of overridden, from the environment variable DNS_KEEP_NAMESERVER
// should be kept instead of overridden, from the environment variable DNS_KEEP_NAMESERVER.
func (r *reader) GetDNSKeepNameserver() (on bool, err error) {
return r.envParams.GetOnOff("DNS_KEEP_NAMESERVER", libparams.Default("off"))
}
+6 -5
View File
@@ -9,13 +9,13 @@ import (
libparams "github.com/qdm12/golibs/params"
)
// GetFirewall obtains if the firewall should be enabled from the environment variable FIREWALL
// GetFirewall obtains if the firewall should be enabled from the environment variable FIREWALL.
func (r *reader) GetFirewall() (enabled bool, err error) {
return r.envParams.GetOnOff("FIREWALL", libparams.Default("on"))
}
// GetExtraSubnets obtains the CIDR subnets from the comma separated list of the
// environment variable EXTRA_SUBNETS
// environment variable EXTRA_SUBNETS.
func (r *reader) GetExtraSubnets() (extraSubnets []net.IPNet, err error) {
s, err := r.envParams.GetEnv("EXTRA_SUBNETS")
if err != nil {
@@ -37,7 +37,7 @@ func (r *reader) GetExtraSubnets() (extraSubnets []net.IPNet, err error) {
}
// GetAllowedVPNInputPorts obtains a list of input ports to allow from the
// VPN server side in the firewall, from the environment variable FIREWALL_VPN_INPUT_PORTS
// VPN server side in the firewall, from the environment variable FIREWALL_VPN_INPUT_PORTS.
func (r *reader) GetVPNInputPorts() (ports []uint16, err error) {
s, err := r.envParams.GetEnv("FIREWALL_VPN_INPUT_PORTS", libparams.Default(""))
if err != nil {
@@ -61,7 +61,7 @@ func (r *reader) GetVPNInputPorts() (ports []uint16, err error) {
}
// GetInputPorts obtains a list of input ports to allow through the
// default interface in the firewall, from the environment variable FIREWALL_INPUT_PORTS
// default interface in the firewall, from the environment variable FIREWALL_INPUT_PORTS.
func (r *reader) GetInputPorts() (ports []uint16, err error) {
s, err := r.envParams.GetEnv("FIREWALL_INPUT_PORTS", libparams.Default(""))
if err != nil {
@@ -84,7 +84,8 @@ func (r *reader) GetInputPorts() (ports []uint16, err error) {
return ports, nil
}
// GetFirewallDebug obtains if the firewall should run in debug verbose mode from the environment variable FIREWALL_DEBUG
// GetFirewallDebug obtains if the firewall should run in debug verbose mode
// from the environment variable FIREWALL_DEBUG.
func (r *reader) GetFirewallDebug() (debug bool, err error) {
return r.envParams.GetOnOff("FIREWALL_DEBUG", libparams.Default("off"))
}
+5 -5
View File
@@ -6,35 +6,35 @@ import (
)
// GetMullvadCountries obtains the countries for the Mullvad servers from the
// environment variable COUNTRY
// environment variable COUNTRY.
func (r *reader) GetMullvadCountries() (countries []string, err error) {
choices := append(constants.MullvadCountryChoices(), "")
return r.envParams.GetCSVInPossibilities("COUNTRY", choices)
}
// GetMullvadCity obtains the cities for the Mullvad servers from the
// environment variable CITY
// environment variable CITY.
func (r *reader) GetMullvadCities() (cities []string, err error) {
choices := append(constants.MullvadCityChoices(), "")
return r.envParams.GetCSVInPossibilities("CITY", choices)
}
// GetMullvadISPs obtains the ISPs for the Mullvad servers from the
// environment variable ISP
// environment variable ISP.
func (r *reader) GetMullvadISPs() (isps []string, err error) {
choices := append(constants.MullvadISPChoices(), "")
return r.envParams.GetCSVInPossibilities("ISP", choices)
}
// GetMullvadPort obtains the port to reach the Mullvad server on from the
// environment variable PORT
// environment variable PORT.
func (r *reader) GetMullvadPort() (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
return uint16(n), err
}
// GetMullvadOwned obtains if the server should be owned by Mullvad or not from the
// environment variable OWNED
// environment variable OWNED.
func (r *reader) GetMullvadOwned() (owned bool, err error) {
return r.envParams.GetYesNo("OWNED", libparams.Default("no"))
}
+2 -2
View File
@@ -8,14 +8,14 @@ import (
)
// GetNordvpnRegions obtains the regions (countries) for the NordVPN server from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetNordvpnRegions() (regions []string, err error) {
choices := append(constants.NordvpnRegionChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
}
// GetNordvpnRegion obtains the server numbers (optional) for the NordVPN servers from the
// environment variable SERVER_NUMBER
// environment variable SERVER_NUMBER.
func (r *reader) GetNordvpnNumbers() (numbers []uint16, err error) {
possibilities := make([]string, 65536)
for i := range possibilities {
+9 -9
View File
@@ -8,7 +8,7 @@ import (
libparams "github.com/qdm12/golibs/params"
)
// GetUser obtains the user to use to connect to the VPN servers
// GetUser obtains the user to use to connect to the VPN servers.
func (r *reader) GetUser() (s string, err error) {
defer func() {
unsetenvErr := r.unsetEnv("USER")
@@ -19,7 +19,7 @@ func (r *reader) GetUser() (s string, err error) {
return r.envParams.GetEnv("USER", libparams.CaseSensitiveValue(), libparams.Compulsory())
}
// GetPassword obtains the password to use to connect to the VPN servers
// GetPassword obtains the password to use to connect to the VPN servers.
func (r *reader) GetPassword(required bool) (s string, err error) {
defer func() {
unsetenvErr := r.unsetEnv("PASSWORD")
@@ -35,26 +35,26 @@ func (r *reader) GetPassword(required bool) (s string, err error) {
}
// GetNetworkProtocol obtains the network protocol to use to connect to the
// VPN servers from the environment variable PROTOCOL
// VPN servers from the environment variable PROTOCOL.
func (r *reader) GetNetworkProtocol() (protocol models.NetworkProtocol, err error) {
s, err := r.envParams.GetValueIfInside("PROTOCOL", []string{"tcp", "udp"}, libparams.Default("udp"))
return models.NetworkProtocol(s), err
}
// GetOpenVPNVerbosity obtains the verbosity level for verbosity between 0 and 6
// from the environment variable OPENVPN_VERBOSITY
// from the environment variable OPENVPN_VERBOSITY.
func (r *reader) GetOpenVPNVerbosity() (verbosity int, err error) {
return r.envParams.GetEnvIntRange("OPENVPN_VERBOSITY", 0, 6, libparams.Default("1"))
}
// GetOpenVPNRoot obtains if openvpn should be run as root
// from the environment variable OPENVPN_ROOT
// from the environment variable OPENVPN_ROOT.
func (r *reader) GetOpenVPNRoot() (root bool, err error) {
return r.envParams.GetYesNo("OPENVPN_ROOT", libparams.Default("no"))
}
// GetTargetIP obtains the IP address to override over the list of IP addresses filtered
// from the environment variable OPENVPN_TARGET_IP
// from the environment variable OPENVPN_TARGET_IP.
func (r *reader) GetTargetIP() (ip net.IP, err error) {
s, err := r.envParams.GetEnv("OPENVPN_TARGET_IP")
if len(s) == 0 {
@@ -70,19 +70,19 @@ func (r *reader) GetTargetIP() (ip net.IP, err error) {
}
// GetOpenVPNCipher obtains a custom cipher to use with OpenVPN
// from the environment variable OPENVPN_CIPHER
// from the environment variable OPENVPN_CIPHER.
func (r *reader) GetOpenVPNCipher() (cipher string, err error) {
return r.envParams.GetEnv("OPENVPN_CIPHER")
}
// GetOpenVPNAuth obtains a custom auth algorithm to use with OpenVPN
// from the environment variable OPENVPN_AUTH
// from the environment variable OPENVPN_AUTH.
func (r *reader) GetOpenVPNAuth() (auth string, err error) {
return r.envParams.GetEnv("OPENVPN_AUTH")
}
// GetOpenVPNIPv6 obtains if ipv6 should be tunneled through the
// openvpn tunnel from the environment variable OPENVPN_IPV6
// openvpn tunnel from the environment variable OPENVPN_IPV6.
func (r *reader) GetOpenVPNIPv6() (ipv6 bool, err error) {
return r.envParams.GetOnOff("OPENVPN_IPV6", libparams.Default("off"))
}
+10 -4
View File
@@ -12,7 +12,7 @@ import (
"github.com/qdm12/golibs/verification"
)
// Reader contains methods to obtain parameters
// Reader contains methods to obtain parameters.
type Reader interface {
GetVPNSP() (vpnServiceProvider models.VPNProvider, err error)
@@ -130,7 +130,7 @@ type reader struct {
}
// Newreader returns a paramsReadeer object to read parameters from
// environment variables
// environment variables.
func NewReader(logger logging.Logger, fileManager files.FileManager) Reader {
return &reader{
envParams: libparams.NewEnvParams(),
@@ -141,9 +141,15 @@ func NewReader(logger logging.Logger, fileManager files.FileManager) Reader {
}
}
// GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP
// GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP.
func (r *reader) GetVPNSP() (vpnServiceProvider models.VPNProvider, err error) {
s, err := r.envParams.GetValueIfInside("VPNSP", []string{"pia", "private internet access", "private internet access old", "mullvad", "windscribe", "surfshark", "cyberghost", "vyprvpn", "nordvpn", "purevpn"})
s, err := r.envParams.GetValueIfInside(
"VPNSP",
[]string{
"pia", "private internet access", "private internet access old",
"mullvad", "windscribe", "surfshark", "cyberghost",
"vyprvpn", "nordvpn", "purevpn",
})
if s == "pia" {
s = "private internet access"
}
+9 -6
View File
@@ -10,7 +10,7 @@ import (
// GetPortForwarding obtains if port forwarding on the VPN provider server
// side is enabled or not from the environment variable PORT_FORWARDING
// Only valid for older PIA servers for now
// Only valid for older PIA servers for now.
func (r *reader) GetPortForwarding() (activated bool, err error) {
s, err := r.envParams.GetEnv("PORT_FORWARDING", libparams.Default("off"))
if err != nil {
@@ -26,15 +26,18 @@ func (r *reader) GetPortForwarding() (activated bool, err error) {
}
// GetPortForwardingStatusFilepath obtains the port forwarding status file path
// from the environment variable PORT_FORWARDING_STATUS_FILE
// from the environment variable PORT_FORWARDING_STATUS_FILE.
func (r *reader) GetPortForwardingStatusFilepath() (filepath models.Filepath, err error) {
filepathStr, err := r.envParams.GetPath("PORT_FORWARDING_STATUS_FILE", libparams.Default("/tmp/gluetun/forwarded_port"), libparams.CaseSensitiveValue())
filepathStr, err := r.envParams.GetPath(
"PORT_FORWARDING_STATUS_FILE",
libparams.Default("/tmp/gluetun/forwarded_port"),
libparams.CaseSensitiveValue())
return models.Filepath(filepathStr), err
}
// GetPIAEncryptionPreset obtains the encryption level for the PIA connection
// from the environment variable PIA_ENCRYPTION, and using ENCRYPTION for
// retro compatibility
// retro compatibility.
func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
// Retro-compatibility
s, err := r.envParams.GetValueIfInside("ENCRYPTION", []string{
@@ -57,14 +60,14 @@ func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
}
// GetPIARegions obtains the regions for the PIA servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetPIARegions() (regions []string, err error) {
choices := append(constants.PIAGeoChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
}
// GetPIAOldRegions obtains the regions for the PIA servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetPIAOldRegions() (regions []string, err error) {
choices := append(constants.PIAOldGeoChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
+1 -1
View File
@@ -7,7 +7,7 @@ import (
)
// GetPublicIPPeriod obtains the period to fetch the IP address periodically.
// Set to 0 to disable
// Set to 0 to disable.
func (r *reader) GetPublicIPPeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("PUBLICIP_PERIOD", libparams.Default("12h"))
if err != nil {
+3 -3
View File
@@ -5,21 +5,21 @@ import (
)
// GetPurevpnRegions obtains the regions (continents) for the PureVPN servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetPurevpnRegions() (regions []string, err error) {
choices := append(constants.PurevpnRegionChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
}
// GetPurevpnCountries obtains the countries for the PureVPN servers from the
// environment variable COUNTRY
// environment variable COUNTRY.
func (r *reader) GetPurevpnCountries() (countries []string, err error) {
choices := append(constants.PurevpnCountryChoices(), "")
return r.envParams.GetCSVInPossibilities("COUNTRY", choices)
}
// GetPurevpnCities obtains the cities for the PureVPN servers from the
// environment variable CITY
// environment variable CITY.
func (r *reader) GetPurevpnCities() (cities []string, err error) {
choices := append(constants.PurevpnCityChoices(), "")
return r.envParams.GetCSVInPossibilities("CITY", choices)
+5 -5
View File
@@ -7,19 +7,19 @@ import (
)
// GetShadowSocks obtains if ShadowSocks is on from the environment variable
// SHADOWSOCKS
// SHADOWSOCKS.
func (r *reader) GetShadowSocks() (activated bool, err error) {
return r.envParams.GetOnOff("SHADOWSOCKS", libparams.Default("off"))
}
// GetShadowSocksLog obtains the ShadowSocks log level from the environment variable
// SHADOWSOCKS_LOG
// SHADOWSOCKS_LOG.
func (r *reader) GetShadowSocksLog() (activated bool, err error) {
return r.envParams.GetOnOff("SHADOWSOCKS_LOG", libparams.Default("off"))
}
// GetShadowSocksPort obtains the ShadowSocks listening port from the environment variable
// SHADOWSOCKS_PORT
// SHADOWSOCKS_PORT.
func (r *reader) GetShadowSocksPort() (port uint16, err error) {
portStr, err := r.envParams.GetEnv("SHADOWSOCKS_PORT", libparams.Default("8388"))
if err != nil {
@@ -33,7 +33,7 @@ func (r *reader) GetShadowSocksPort() (port uint16, err error) {
}
// GetShadowSocksPassword obtains the ShadowSocks server password from the environment variable
// SHADOWSOCKS_PASSWORD
// SHADOWSOCKS_PASSWORD.
func (r *reader) GetShadowSocksPassword() (password string, err error) {
defer func() {
unsetErr := r.unsetEnv("SHADOWSOCKS_PASSWORD")
@@ -45,7 +45,7 @@ func (r *reader) GetShadowSocksPassword() (password string, err error) {
}
// GetShadowSocksMethod obtains the ShadowSocks method to use from the environment variable
// SHADOWSOCKS_METHOD
// SHADOWSOCKS_METHOD.
func (r *reader) GetShadowSocksMethod() (method string, err error) {
return r.envParams.GetEnv("SHADOWSOCKS_METHOD", libparams.Default("chacha20-ietf-poly1305"))
}
+1 -1
View File
@@ -5,7 +5,7 @@ import (
)
// GetSurfsharkRegions obtains the regions for the Surfshark servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetSurfsharkRegions() (regions []string, err error) {
choices := append(constants.SurfsharkRegionChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
+6 -5
View File
@@ -5,24 +5,25 @@ import (
libparams "github.com/qdm12/golibs/params"
)
// GetUID obtains the user ID to use from the environment variable UID
// GetUID obtains the user ID to use from the environment variable UID.
func (r *reader) GetUID() (uid int, err error) {
return r.envParams.GetEnvIntRange("UID", 0, 65535, libparams.Default("1000"))
}
// GetGID obtains the group ID to use from the environment variable GID
// GetGID obtains the group ID to use from the environment variable GID.
func (r *reader) GetGID() (gid int, err error) {
return r.envParams.GetEnvIntRange("GID", 0, 65535, libparams.Default("1000"))
}
// GetTZ obtains the timezone from the environment variable TZ
// GetTZ obtains the timezone from the environment variable TZ.
func (r *reader) GetTimezone() (timezone string, err error) {
return r.envParams.GetEnv("TZ")
}
// GetIPStatusFilepath obtains the IP status file path
// from the environment variable IP_STATUS_FILE
// from the environment variable IP_STATUS_FILE.
func (r *reader) GetIPStatusFilepath() (filepath models.Filepath, err error) {
filepathStr, err := r.envParams.GetPath("IP_STATUS_FILE", libparams.Default("/tmp/gluetun/ip"), libparams.CaseSensitiveValue())
filepathStr, err := r.envParams.GetPath("IP_STATUS_FILE",
libparams.Default("/tmp/gluetun/ip"), libparams.CaseSensitiveValue())
return models.Filepath(filepathStr), err
}
+13 -9
View File
@@ -8,7 +8,7 @@ import (
)
// GetTinyProxy obtains if TinyProxy is on from the environment variable
// TINYPROXY, and using PROXY as a retro-compatibility name
// TINYPROXY, and using PROXY as a retro-compatibility name.
func (r *reader) GetTinyProxy() (activated bool, err error) {
// Retro-compatibility
s, err := r.envParams.GetEnv("PROXY")
@@ -22,23 +22,27 @@ func (r *reader) GetTinyProxy() (activated bool, err error) {
}
// GetTinyProxyLog obtains the TinyProxy log level from the environment variable
// TINYPROXY_LOG, and using PROXY_LOG_LEVEL as a retro-compatibility name
// TINYPROXY_LOG, and using PROXY_LOG_LEVEL as a retro-compatibility name.
func (r *reader) GetTinyProxyLog() (models.TinyProxyLogLevel, error) {
// Retro-compatibility
s, err := r.envParams.GetEnv("PROXY_LOG_LEVEL")
if err != nil {
return models.TinyProxyLogLevel(s), err
} else if len(s) != 0 {
r.logger.Warn("You are using the old environment variable PROXY_LOG_LEVEL, please consider changing it to TINYPROXY_LOG")
s, err = r.envParams.GetValueIfInside("PROXY_LOG_LEVEL", []string{"Info", "Connect", "Notice", "Warning", "Error", "Critical"}, libparams.Compulsory())
r.logger.Warn("You are using the old environment variable PROXY_LOG_LEVEL, please consider changing it to TINYPROXY_LOG") //nolint:lll
s, err = r.envParams.GetValueIfInside("PROXY_LOG_LEVEL",
[]string{"Info", "Connect", "Notice", "Warning", "Error", "Critical"},
libparams.Compulsory())
return models.TinyProxyLogLevel(s), err
}
s, err = r.envParams.GetValueIfInside("TINYPROXY_LOG", []string{"Info", "Connect", "Notice", "Warning", "Error", "Critical"}, libparams.Default("Connect"))
s, err = r.envParams.GetValueIfInside("TINYPROXY_LOG",
[]string{"Info", "Connect", "Notice", "Warning", "Error", "Critical"},
libparams.Default("Connect"))
return models.TinyProxyLogLevel(s), err
}
// GetTinyProxyPort obtains the TinyProxy listening port from the environment variable
// TINYPROXY_PORT, and using PROXY_PORT as a retro-compatibility name
// TINYPROXY_PORT, and using PROXY_PORT as a retro-compatibility name.
func (r *reader) GetTinyProxyPort() (port uint16, err error) {
// Retro-compatibility
portStr, err := r.envParams.GetEnv("PROXY_PORT")
@@ -61,7 +65,7 @@ func (r *reader) GetTinyProxyPort() (port uint16, err error) {
}
// GetTinyProxyUser obtains the TinyProxy server user from the environment variable
// TINYPROXY_USER, and using PROXY_USER as a retro-compatibility name
// TINYPROXY_USER, and using PROXY_USER as a retro-compatibility name.
func (r *reader) GetTinyProxyUser() (user string, err error) {
defer func() {
unsetErr := r.unsetEnv("PROXY_USER")
@@ -88,7 +92,7 @@ func (r *reader) GetTinyProxyUser() (user string, err error) {
}
// GetTinyProxyPassword obtains the TinyProxy server password from the environment variable
// TINYPROXY_PASSWORD, and using PROXY_PASSWORD as a retro-compatibility name
// TINYPROXY_PASSWORD, and using PROXY_PASSWORD as a retro-compatibility name.
func (r *reader) GetTinyProxyPassword() (password string, err error) {
defer func() {
unsetErr := r.unsetEnv("PROXY_PASSWORD")
@@ -109,7 +113,7 @@ func (r *reader) GetTinyProxyPassword() (password string, err error) {
return password, err
}
if len(password) != 0 {
r.logger.Warn("You are using the old environment variable PROXY_PASSWORD, please consider changing it to TINYPROXY_PASSWORD")
r.logger.Warn("You are using the old environment variable PROXY_PASSWORD, please consider changing it to TINYPROXY_PASSWORD") //nolint:lll
return password, nil
}
return r.envParams.GetEnv("TINYPROXY_PASSWORD", libparams.CaseSensitiveValue())
+1 -1
View File
@@ -7,7 +7,7 @@ import (
)
// GetUpdaterPeriod obtains the period to fetch the servers information when the tunnel is up.
// Set to 0 to disable
// Set to 0 to disable.
func (r *reader) GetUpdaterPeriod() (period time.Duration, err error) {
s, err := r.envParams.GetEnv("UPDATER_PERIOD", libparams.Default("0"))
if err != nil {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
)
// GetVyprvpnRegions obtains the regions for the Vyprvpn servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetVyprvpnRegions() (regions []string, err error) {
choices := append(constants.VyprvpnRegionChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
+3 -2
View File
@@ -9,14 +9,15 @@ import (
)
// GetWindscribeRegions obtains the regions for the Windscribe servers from the
// environment variable REGION
// environment variable REGION.
func (r *reader) GetWindscribeRegions() (regions []string, err error) {
choices := append(constants.WindscribeRegionChoices(), "")
return r.envParams.GetCSVInPossibilities("REGION", choices)
}
// GetMullvadPort obtains the port to reach the Mullvad server on from the
// environment variable PORT
// environment variable PORT.
//nolint:gomnd
func (r *reader) GetWindscribePort(protocol models.NetworkProtocol) (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
if err != nil {
+9 -5
View File
@@ -39,27 +39,31 @@ func (c *cyberghost) filterServers(regions []string, group string) (servers []mo
return servers
}
func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
const httpsPort = 443
if selection.TargetIP != nil {
return models.OpenVPNConnection{IP: selection.TargetIP, Port: 443, Protocol: selection.Protocol}, nil
return models.OpenVPNConnection{IP: selection.TargetIP, Port: httpsPort, Protocol: selection.Protocol}, nil
}
servers := c.filterServers(selection.Regions, selection.Group)
if len(servers) == 0 {
return connection, fmt.Errorf("no server found for regions %s and group %q", commaJoin(selection.Regions), selection.Group)
return connection,
fmt.Errorf("no server found for regions %s and group %q", commaJoin(selection.Regions), selection.Group)
}
var connections []models.OpenVPNConnection
for _, server := range servers {
for _, IP := range server.IPs {
connections = append(connections, models.OpenVPNConnection{IP: IP, Port: 443, Protocol: selection.Protocol})
connections = append(connections, models.OpenVPNConnection{IP: IP, Port: httpsPort, Protocol: selection.Protocol})
}
}
return pickRandomConnection(connections, c.randSource), nil
}
func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (c *cyberghost) BuildConf(connection models.OpenVPNConnection, verbosity,
uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+4 -2
View File
@@ -41,7 +41,8 @@ func (m *mullvad) filterServers(countries, cities, isps []string, owned bool) (s
return servers
}
func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var defaultPort uint16 = 1194
if selection.Protocol == constants.TCP {
defaultPort = 443
@@ -71,7 +72,8 @@ func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (connec
return pickRandomConnection(connections, m.randSource), nil
}
func (m *mullvad) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (m *mullvad) BuildConf(connection models.OpenVPNConnection,
verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+10 -5
View File
@@ -26,7 +26,8 @@ func newNordvpn(servers []models.NordvpnServer, timeNow timeNowFunc) *nordvpn {
}
}
func (n *nordvpn) filterServers(regions []string, protocol models.NetworkProtocol, numbers []uint16) (servers []models.NordvpnServer) {
func (n *nordvpn) filterServers(regions []string, protocol models.NetworkProtocol, numbers []uint16) (
servers []models.NordvpnServer) {
numbersStr := make([]string, len(numbers))
for i := range numbers {
numbersStr[i] = fmt.Sprintf("%d", numbers[i])
@@ -46,7 +47,8 @@ func (n *nordvpn) filterServers(regions []string, protocol models.NetworkProtoco
return servers
}
func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl
func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch {
case selection.Protocol == constants.UDP:
@@ -63,18 +65,21 @@ func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
servers := n.filterServers(selection.Regions, selection.Protocol, selection.Numbers)
if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %s, protocol %s and numbers %v", commaJoin(selection.Regions), selection.Protocol, selection.Numbers)
return connection, fmt.Errorf("no server found for region %s, protocol %s and numbers %v",
commaJoin(selection.Regions), selection.Protocol, selection.Numbers)
}
connections := make([]models.OpenVPNConnection, len(servers))
for i := range servers {
connections = append(connections, models.OpenVPNConnection{IP: servers[i].IP, Port: port, Protocol: selection.Protocol})
connection := models.OpenVPNConnection{IP: servers[i].IP, Port: port, Protocol: selection.Protocol}
connections = append(connections, connection)
}
return pickRandomConnection(connections, n.randSource), nil
}
func (n *nordvpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) { //nolint:dupl
func (n *nordvpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+13 -13
View File
@@ -8,27 +8,27 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
func buildPIAConf(connection models.OpenVPNConnection, verbosity int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func buildPIAConf(connection models.OpenVPNConnection, verbosity int, root bool, cipher, auth string,
extras models.ExtraConfigOptions) (lines []string) {
var X509CRL, certificate string
var defaultCipher, defaultAuth string
if extras.EncryptionPreset == constants.PIAEncryptionPresetNormal {
if len(cipher) == 0 {
cipher = "aes-128-cbc"
}
if len(auth) == 0 {
auth = "sha1"
}
defaultCipher = "aes-128-cbc"
defaultAuth = "sha1"
X509CRL = constants.PiaX509CRLNormal
certificate = constants.PIACertificateNormal
} else { // strong encryption
if len(cipher) == 0 {
cipher = aes256cbc
}
if len(auth) == 0 {
auth = "sha256"
}
defaultCipher = aes256cbc
defaultAuth = "sha256"
X509CRL = constants.PiaX509CRLStrong
certificate = constants.PIACertificateStrong
}
if len(cipher) == 0 {
cipher = defaultCipher
}
if len(auth) == 0 {
auth = defaultAuth
}
lines = []string{
"client",
"dev tun",
+15 -10
View File
@@ -30,7 +30,8 @@ func newPrivateInternetAccessV3(servers []models.PIAOldServer, timeNow timeNowFu
}
}
func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch selection.Protocol {
case constants.TCP:
@@ -49,7 +50,9 @@ func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connecti
}
}
if port == 0 {
return connection, fmt.Errorf("combination of protocol %q and encryption %q does not yield any port number", selection.Protocol, selection.EncryptionPreset)
return connection, fmt.Errorf(
"combination of protocol %q and encryption %q does not yield any port number",
selection.Protocol, selection.EncryptionPreset)
}
if selection.TargetIP != nil {
@@ -71,20 +74,22 @@ func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connecti
return pickRandomConnection(connections, p.randSource), nil
}
func (p *piaV3) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (p *piaV3) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
return buildPIAConf(connection, verbosity, root, cipher, auth, extras)
}
func (p *piaV3) PortForward(ctx context.Context, client *http.Client,
fileManager files.FileManager, pfLogger logging.Logger, gateway net.IP, fw firewall.Configurator,
syncState func(port uint16) (pfFilepath models.Filepath)) {
b := make([]byte, 32)
const uuidLength = 32
b := make([]byte, uuidLength)
n, err := rand.New(p.randSource).Read(b) //nolint:gosec
if err != nil {
pfLogger.Error(err)
return
} else if n != 32 {
pfLogger.Error("only read %d bytes instead of 32", n)
} else if n != uuidLength {
pfLogger.Error("only read %d bytes instead of %d", n, uuidLength)
return
}
clientID := hex.EncodeToString(b)
@@ -96,7 +101,7 @@ func (p *piaV3) PortForward(ctx context.Context, client *http.Client,
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
pfLogger.Error(fmt.Errorf("%s for %s; does your PIA server support port forwarding?", response.Status, url))
pfLogger.Error("%s for %s; does your PIA server support port forwarding?", response.Status, url)
return
}
b, err = ioutil.ReadAll(response.Body)
@@ -104,14 +109,14 @@ func (p *piaV3) PortForward(ctx context.Context, client *http.Client,
pfLogger.Error(err)
return
} else if len(b) == 0 {
pfLogger.Error(fmt.Errorf("port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding"))
pfLogger.Error("port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding") //nolint:lll
return
}
body := struct {
Port uint16 `json:"port"`
}{}
if err := json.Unmarshal(b, &body); err != nil {
pfLogger.Error(fmt.Errorf("port forwarding response: %w", err))
pfLogger.Error("port forwarding response: %s", err)
return
}
port := body.Port
@@ -120,7 +125,7 @@ func (p *piaV3) PortForward(ctx context.Context, client *http.Client,
pfLogger.Info("Writing port to %s", filepath)
if err := fileManager.WriteToFile(
string(filepath), []byte(fmt.Sprintf("%d", port)),
files.Permissions(0666),
files.Permissions(constants.AllReadWritePermissions),
); err != nil {
pfLogger.Error(err)
}
+19 -11
View File
@@ -40,7 +40,8 @@ func newPrivateInternetAccessV4(servers []models.PIAServer, timeNow timeNowFunc)
}
}
func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch selection.Protocol {
case constants.TCP:
@@ -59,7 +60,9 @@ func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connecti
}
}
if port == 0 {
return connection, fmt.Errorf("combination of protocol %q and encryption %q does not yield any port number", selection.Protocol, selection.EncryptionPreset)
return connection, fmt.Errorf(
"combination of protocol %q and encryption %q does not yield any port number",
selection.Protocol, selection.EncryptionPreset)
}
if selection.TargetIP != nil {
@@ -107,7 +110,8 @@ func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connecti
return connection, nil
}
func (p *piaV4) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (p *piaV4) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
return buildPIAConf(connection, verbosity, root, cipher, auth, extras)
}
@@ -174,7 +178,7 @@ func (p *piaV4) PortForward(ctx context.Context, client *http.Client,
pfLogger.Info("Writing port to %s", filepath)
if err := fileManager.WriteToFile(
string(filepath), []byte(fmt.Sprintf("%d", data.Port)),
files.Permissions(0666),
files.Permissions(constants.AllReadWritePermissions),
); err != nil {
pfLogger.Error(err)
}
@@ -230,7 +234,7 @@ func (p *piaV4) PortForward(ctx context.Context, client *http.Client,
pfLogger.Info("Writing port to %s", filepath)
if err := fileManager.WriteToFile(
string(filepath), []byte(fmt.Sprintf("%d", data.Port)),
files.Permissions(0666),
files.Permissions(constants.AllReadWritePermissions),
); err != nil {
pfLogger.Error(err)
}
@@ -274,6 +278,7 @@ func newPIAv4HTTPClient(serverName string) (client *http.Client, err error) {
MinVersion: tls.VersionTLS12,
ServerName: serverName,
}
//nolint:gomnd
transport := http.Transport{
TLSClientConfig: TLSClientConfig,
Proxy: http.ProxyFromEnvironment,
@@ -293,8 +298,9 @@ func newPIAv4HTTPClient(serverName string) (client *http.Client, err error) {
return client, nil
}
func refreshPIAPortForwardData(ctx context.Context, client *http.Client, gateway net.IP, fileManager files.FileManager) (data piaPortForwardData, err error) {
data.Token, err = fetchPIAToken(fileManager, client)
func refreshPIAPortForwardData(ctx context.Context, client *http.Client,
gateway net.IP, fileManager files.FileManager) (data piaPortForwardData, err error) {
data.Token, err = fetchPIAToken(ctx, fileManager, client)
if err != nil {
return data, fmt.Errorf("cannot obtain token: %w", err)
}
@@ -377,7 +383,7 @@ func packPIAPayload(port uint16, token string, expiration time.Time) (payload st
return payload, nil
}
func fetchPIAToken(fileManager files.FileManager, client *http.Client) (token string, err error) {
func fetchPIAToken(ctx context.Context, fileManager files.FileManager, client *http.Client) (token string, err error) {
username, password, err := getOpenvpnCredentials(fileManager)
if err != nil {
return "", fmt.Errorf("cannot get Openvpn credentials: %w", err)
@@ -388,7 +394,7 @@ func fetchPIAToken(fileManager files.FileManager, client *http.Client) (token st
Host: "185.216.33.146",
Path: "/authv3/generateToken",
}
request, err := http.NewRequest(http.MethodGet, url.String(), nil)
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil)
if err != nil {
return "", err
}
@@ -423,14 +429,16 @@ func getOpenvpnCredentials(fileManager files.FileManager) (username, password st
return "", "", fmt.Errorf("cannot read openvpn auth file: %w", err)
}
lines := strings.Split(string(authData), "\n")
if len(lines) < 2 {
const minLines = 2
if len(lines) < minLines {
return "", "", fmt.Errorf("not enough lines (%d) in openvpn auth file", len(lines))
}
username, password = lines[0], lines[1]
return username, password, nil
}
func fetchPIAPortForwardData(ctx context.Context, client *http.Client, gateway net.IP, token string) (port uint16, signature string, expiration time.Time, err error) {
func fetchPIAPortForwardData(ctx context.Context, client *http.Client, gateway net.IP, token string) (
port uint16, signature string, expiration time.Time, err error) {
queryParams := url.Values{}
queryParams.Add("token", token)
url := url.URL{
+3 -2
View File
@@ -12,10 +12,11 @@ import (
"github.com/qdm12/golibs/logging"
)
// Provider contains methods to read and modify the openvpn configuration to connect as a client
// Provider contains methods to read and modify the openvpn configuration to connect as a client.
type Provider interface {
GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error)
BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string)
BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string)
PortForward(ctx context.Context, client *http.Client,
fileManager files.FileManager, pfLogger logging.Logger, gateway net.IP, fw firewall.Configurator,
syncState func(port uint16) (pfFilepath models.Filepath))
+4 -2
View File
@@ -40,7 +40,8 @@ func (p *purevpn) filterServers(regions, countries, cities []string) (servers []
return servers
}
func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl
func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch {
case selection.Protocol == constants.UDP:
@@ -71,7 +72,8 @@ func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
return pickRandomConnection(connections, p.randSource), nil
}
func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) { //nolint:dupl
func (p *purevpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+4 -2
View File
@@ -38,7 +38,8 @@ func (s *surfshark) filterServers(regions []string) (servers []models.SurfsharkS
return servers
}
func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl
func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch {
case selection.Protocol == constants.TCP:
@@ -72,7 +73,8 @@ func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (conn
return pickRandomConnection(connections, s.randSource), nil
}
func (s *surfshark) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) { //nolint:dupl
func (s *surfshark) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool,
cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+5 -3
View File
@@ -38,7 +38,8 @@ func (v *vyprvpn) filterServers(regions []string) (servers []models.VyprvpnServe
return servers
}
func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (
connection models.OpenVPNConnection, err error) {
var port uint16
switch {
case selection.Protocol == constants.TCP:
@@ -68,7 +69,8 @@ func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
return pickRandomConnection(connections, v.randSource), nil
}
func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
@@ -86,7 +88,7 @@ func (v *vyprvpn) BuildConf(connection models.OpenVPNConnection, verbosity, uid,
"comp-lzo",
"keepalive 10 60",
// "verify-x509-name lu1.vyprvpn.com name",
"tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
"tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
// Added constant values
"auth-nocache",
+3 -1
View File
@@ -39,6 +39,7 @@ func (w *windscribe) filterServers(regions []string) (servers []models.Windscrib
return servers
}
//nolint:lll
func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
var port uint16
switch {
@@ -71,7 +72,8 @@ func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (con
return pickRandomConnection(connections, w.randSource), nil
}
func (w *windscribe) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
func (w *windscribe) BuildConf(connection models.OpenVPNConnection, verbosity, uid, gid int,
root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 {
cipher = aes256cbc
}
+12 -5
View File
@@ -72,10 +72,16 @@ func (l *looper) SetPeriod(period time.Duration) {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Error(err)
l.logger.Info("retrying in 5 seconds")
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel() // just for the linter
<-ctx.Done()
const waitTime = 5 * time.Second
l.logger.Info("retrying in %s", waitTime)
timer := time.NewTimer(waitTime)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
@@ -110,11 +116,12 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
continue
}
l.logger.Info("Public IP address is %s", ip)
const userReadWritePermissions = 0600
err = l.fileManager.WriteLinesToFile(
string(l.ipStatusFilepath),
[]string{ip.String()},
files.Ownership(l.uid, l.gid),
files.Permissions(0600))
files.Permissions(userReadWritePermissions))
if err != nil {
l.logAndWait(ctx, err)
continue
+8 -6
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"net"
"strconv"
"strings"
)
@@ -28,7 +27,8 @@ func parseRoutingEntry(s string) (r routingEntry, err error) {
return fmt.Errorf("line %q: %w", s, err)
}
fields := strings.Fields(s)
if len(fields) < 11 {
const minFields = 11
if len(fields) < minFields {
return r, wrapError(fmt.Errorf("not enough fields"))
}
r.iface = fields[0]
@@ -74,20 +74,22 @@ func parseRoutingEntry(s string) (r routingEntry, err error) {
func reversedHexToIPv4(reversedHex string) (ip net.IP, err error) {
bytes, err := hex.DecodeString(reversedHex)
const nBytesRequired = 4
if err != nil {
return nil, fmt.Errorf("cannot parse reversed IP hex %q: %s", reversedHex, err)
} else if len(bytes) != 4 {
return nil, fmt.Errorf("hex string contains %d bytes instead of 4", len(bytes))
} else if L := len(bytes); L != nBytesRequired {
return nil, fmt.Errorf("hex string contains %d bytes instead of %d", L, nBytesRequired)
}
return []byte{bytes[3], bytes[2], bytes[1], bytes[0]}, nil
}
func hexToIPv4Mask(hexString string) (mask net.IPMask, err error) {
bytes, err := hex.DecodeString(hexString)
const nBytesRequired = 4
if err != nil {
return nil, fmt.Errorf("cannot parse hex mask %q: %s", hexString, err)
} else if len(bytes) != 4 {
return nil, fmt.Errorf("hex string contains %d bytes instead of 4", len(bytes))
} else if L := len(bytes); L != nBytesRequired {
return nil, fmt.Errorf("hex string contains %d bytes instead of %d", L, nBytesRequired)
}
return []byte{bytes[3], bytes[2], bytes[1], bytes[0]}, nil
}
+1
View File
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
)
//nolint:lll
func Test_parseRoutingEntry(t *testing.T) {
t.Parallel()
tests := map[string]struct {
+7 -5
View File
@@ -2,12 +2,12 @@ package routing
import (
"context"
"net"
"fmt"
"net"
)
func (r *routing) AddRouteVia(ctx context.Context, subnet net.IPNet, defaultGateway net.IP, defaultInterface string) error {
func (r *routing) AddRouteVia(ctx context.Context,
subnet net.IPNet, defaultGateway net.IP, defaultInterface string) error {
subnetStr := subnet.String()
r.logger.Info("adding %s as route via %s %s", subnetStr, defaultGateway, defaultInterface)
exists, err := r.routeExists(subnet)
@@ -19,9 +19,11 @@ func (r *routing) AddRouteVia(ctx context.Context, subnet net.IPNet, defaultGate
if r.debug {
fmt.Printf("ip route add %s via %s dev %s\n", subnetStr, defaultGateway, defaultInterface)
}
output, err := r.commander.Run(ctx, "ip", "route", "add", subnetStr, "via", defaultGateway.String(), "dev", defaultInterface)
output, err := r.commander.Run(ctx,
"ip", "route", "add", subnetStr, "via", defaultGateway.String(), "dev", defaultInterface)
if err != nil {
return fmt.Errorf("cannot add route for %s via %s %s %s: %s: %w", subnetStr, defaultGateway, "dev", defaultInterface, output, err)
return fmt.Errorf("cannot add route for %s via %s %s %s: %s: %w",
subnetStr, defaultGateway, "dev", defaultInterface, output, err)
}
return nil
}
+1
View File
@@ -63,6 +63,7 @@ func Test_DeleteRouteVia(t *testing.T) {
commander.EXPECT().Run(ctx, "ip", "route", "del", subnetStr).
Return(tc.runOutput, tc.runErr).Times(1)
fileManager := mock_files.NewMockFileManager(mockCtrl)
//nolint:lll
routesData := []byte(`Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
eth0 0002A8C0 0100000A 0003 0 0 0 00FFFFFF 0 0 0
`)
+5 -4
View File
@@ -2,9 +2,8 @@ package routing
import (
"bytes"
"net"
"fmt"
"net"
"strings"
"github.com/qdm12/gluetun/internal/constants"
@@ -37,7 +36,8 @@ func (r *routing) DefaultRoute() (defaultInterface string, defaultGateway net.IP
if err != nil {
return "", nil, err
}
if len(entries) < 2 {
const minEntries = 2
if len(entries) < minEntries {
return "", nil, fmt.Errorf("not enough entries (%d) found in %s", len(entries), constants.NetRoute)
}
var defaultRouteEntry routingEntry
@@ -61,7 +61,8 @@ func (r *routing) LocalSubnet() (defaultSubnet net.IPNet, err error) {
if err != nil {
return defaultSubnet, err
}
if len(entries) < 2 {
const minEntries = 2
if len(entries) < minEntries {
return defaultSubnet, fmt.Errorf("not enough entries (%d) found in %s", len(entries), constants.NetRoute)
}
var localSubnetEntry routingEntry
+8 -3
View File
@@ -6,14 +6,14 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/golibs/files/mock_files"
"github.com/qdm12/golibs/logging/mock_logging"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
//nolint:lll
const exampleRouteData = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
tun0 00000000 050A030A 0003 0 0 0 00000080 0 0 0
eth0 00000000 010011AC 0003 0 0 0 00000000 0 0 0
@@ -24,6 +24,7 @@ tun0 00000080 050A030A 0003 0 0 0 00000080
eth0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
`
//nolint:lll
func Test_parseRoutingTable(t *testing.T) {
t.Parallel()
tests := map[string]struct {
@@ -96,6 +97,7 @@ eth0 x 0100000A 0003 0 0 0 00FFFFFF 0 0 0
}
}
//nolint:lll
func Test_DefaultRoute(t *testing.T) {
t.Parallel()
tests := map[string]struct {
@@ -164,6 +166,7 @@ eth0 000011AC 00000000 0001 0 0 0 0000FFFF
}
}
//nolint:lll
func Test_LocalSubnet(t *testing.T) {
t.Parallel()
tests := map[string]struct {
@@ -229,6 +232,7 @@ eth0 000011AC 10000000 0001 0 0 0 0000FFFF
}
}
//nolint:lll
func Test_routeExists(t *testing.T) {
t.Parallel()
tests := map[string]struct {
@@ -291,6 +295,7 @@ eth0 0002A8C0 0100000A 0003 0 0 0 00FFFFFF
}
}
//nolint:lll
func Test_VPNDestinationIP(t *testing.T) {
t.Parallel()
tests := map[string]struct {
+1 -1
View File
@@ -26,7 +26,7 @@ type routing struct {
debug bool
}
// NewConfigurator creates a new Configurator instance
// NewConfigurator creates a new Configurator instance.
func NewRouting(logger logging.Logger, fileManager files.FileManager) Routing {
return &routing{
commander: command.NewCommander(),
+4 -2
View File
@@ -28,7 +28,8 @@ type server struct {
lookupIP func(host string) ([]net.IP, error)
}
func New(address string, logging bool, logger logging.Logger, openvpnLooper openvpn.Looper, unboundLooper dns.Looper, updaterLooper updater.Looper) Server {
func New(address string, logging bool, logger logging.Logger,
openvpnLooper openvpn.Looper, unboundLooper dns.Looper, updaterLooper updater.Looper) Server {
return &server{
address: address,
logging: logging,
@@ -47,7 +48,8 @@ func (s *server) Run(ctx context.Context, wg *sync.WaitGroup) {
<-ctx.Done()
s.logger.Warn("context canceled: exiting loop")
defer s.logger.Warn("loop exited")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
const shutdownGraceDuration = 2 * time.Second
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownGraceDuration)
defer cancel()
if err := server.Shutdown(shutdownCtx); err != nil {
s.logger.Error("failed shutting down: %s", err)
+1 -1
View File
@@ -11,7 +11,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// DNS contains settings to configure Unbound for DNS over TLS operation
// DNS contains settings to configure Unbound for DNS over TLS operation.
type DNS struct {
Enabled bool
KeepNameserver bool
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// Firewall contains settings to customize the firewall operation
// Firewall contains settings to customize the firewall operation.
type Firewall struct {
AllowedSubnets []net.IPNet
VPNInputPorts []uint16
+2 -2
View File
@@ -9,7 +9,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// OpenVPN contains settings to configure the OpenVPN client
// OpenVPN contains settings to configure the OpenVPN client.
type OpenVPN struct {
User string `json:"user"`
Password string `json:"-"`
@@ -20,7 +20,7 @@ type OpenVPN struct {
Provider models.ProviderSettings `json:"provider"`
}
// GetOpenVPNSettings obtains the OpenVPN settings using the params functions
// GetOpenVPNSettings obtains the OpenVPN settings using the params functions.
func GetOpenVPNSettings(paramsReader params.Reader, vpnProvider models.VPNProvider) (settings OpenVPN, err error) {
settings.User, err = paramsReader.GetUser()
if err != nil {
+1
View File
@@ -19,6 +19,7 @@ func Test_OpenVPN_JSON(t *testing.T) {
}
data, err := json.Marshal(in)
require.NoError(t, err)
//nolint:lll
assert.Equal(t, `{"user":"","verbosity":0,"runAsRoot":true,"cipher":"","auth":"","provider":{"name":"name","serverSelection":{"networkProtocol":"","regions":null,"group":"","countries":null,"cities":null,"isps":null,"owned":false,"customPort":0,"numbers":null,"encryptionPreset":""},"extraConfig":{"encryptionPreset":"","openvpnIPv6":false},"portForwarding":{"enabled":false,"filepath":""}}}`, string(data))
var out OpenVPN
err = json.Unmarshal(data, &out)
+4 -3
View File
@@ -13,7 +13,8 @@ func GetPIASettings(paramsReader params.Reader) (settings models.ProviderSetting
return getPIASettings(paramsReader, constants.PrivateInternetAccess)
}
// GetPIAOldSettings obtains PIA settings for the older PIA servers (pre summer 2020) from environment variables using the params package.
// GetPIAOldSettings obtains PIA settings for the older PIA servers (pre summer 2020)
// from environment variables using the params package.
func GetPIAOldSettings(paramsReader params.Reader) (settings models.ProviderSettings, err error) {
return getPIASettings(paramsReader, constants.PrivateInternetAccessOld)
}
@@ -80,13 +81,13 @@ func GetMullvadSettings(paramsReader params.Reader) (settings models.ProviderSet
}
if settings.ServerSelection.Protocol == constants.TCP {
switch settings.ServerSelection.CustomPort {
case 0, 80, 443, 1401:
case 0, 80, 443, 1401: //nolint:gomnd
default:
return settings, fmt.Errorf("port %d is not valid for TCP protocol", settings.ServerSelection.CustomPort)
}
} else {
switch settings.ServerSelection.CustomPort {
case 0, 53, 1194, 1195, 1196, 1197, 1300, 1301, 1302, 1303, 1400:
case 0, 53, 1194, 1195, 1196, 1197, 1300, 1301, 1302, 1303, 1400: //nolint:gomnd
default:
return settings, fmt.Errorf("port %d is not valid for UDP protocol", settings.ServerSelection.CustomPort)
}
+3 -2
View File
@@ -7,7 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// ControlServer contains settings to customize the control server operation
// ControlServer contains settings to customize the control server operation.
type ControlServer struct {
Port uint16
Log bool
@@ -22,7 +22,8 @@ func (c *ControlServer) String() string {
return strings.Join(settingsList, "\n |--")
}
// GetControlServerSettings obtains the HTTP control server settings from environment variables using the params package.
// GetControlServerSettings obtains the HTTP control server settings from
// environment variables using the params package.
func GetControlServerSettings(paramsReader params.Reader) (settings ControlServer, err error) {
settings.Port, err = paramsReader.GetControlServerPort()
if err != nil {
+1 -1
View File
@@ -14,7 +14,7 @@ const (
disabled = "disabled"
)
// Settings contains all settings for the program to run
// Settings contains all settings for the program to run.
type Settings struct {
VPNSP models.VPNProvider
OpenVPN OpenVPN
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// ShadowSocks contains settings to configure the Shadowsocks server
// ShadowSocks contains settings to configure the Shadowsocks server.
type ShadowSocks struct {
Method string
Password string
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// System contains settings to configure system related elements
// System contains settings to configure system related elements.
type System struct {
UID int
GID int
@@ -16,7 +16,7 @@ type System struct {
IPStatusFilepath models.Filepath
}
// GetSystemSettings obtains the System settings using the params functions
// GetSystemSettings obtains the System settings using the params functions.
func GetSystemSettings(paramsReader params.Reader) (settings System, err error) {
settings.UID, err = paramsReader.GetUID()
if err != nil {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/qdm12/gluetun/internal/params"
)
// TinyProxy contains settings to configure TinyProxy
// TinyProxy contains settings to configure TinyProxy.
type TinyProxy struct {
User string
Password string
+10 -4
View File
@@ -34,10 +34,16 @@ type looper struct {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Error(err)
l.logger.Info("retrying in 1 minute")
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel() // just for the linter
<-ctx.Done()
const waitTime = time.Minute
l.logger.Info("retrying in %s", waitTime)
timer := time.NewTimer(waitTime)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
func NewLooper(firewallConf firewall.Configurator, settings settings.ShadowSocks,
+2 -1
View File
@@ -25,7 +25,8 @@ func countServers(allServers models.AllServers) int {
len(allServers.Windscribe.Servers)
}
func (s *storage) SyncServers(hardcodedServers models.AllServers, write bool) (allServers models.AllServers, err error) {
func (s *storage) SyncServers(hardcodedServers models.AllServers, write bool) (
allServers models.AllServers, err error) {
// Eventually read file
var serversOnFile models.AllServers
_, err = s.osStat(jsonFilepath)
+3 -2
View File
@@ -13,14 +13,15 @@ func (c *configurator) Start(ctx context.Context) (stdout io.ReadCloser, waitFn
return stdout, waitFn, err
}
// Version obtains the version of the installed Tinyproxy server
// Version obtains the version of the installed Tinyproxy server.
func (c *configurator) Version(ctx context.Context) (string, error) {
output, err := c.commander.Run(ctx, "tinyproxy", "-v")
if err != nil {
return "", err
}
words := strings.Fields(output)
if len(words) < 2 {
const minWords = 2
if len(words) < minWords {
return "", fmt.Errorf("tinyproxy -v: output is too short: %q", output)
}
return words[1], nil
+5 -3
View File
@@ -9,16 +9,18 @@ import (
"github.com/qdm12/golibs/files"
)
func (c *configurator) MakeConf(logLevel models.TinyProxyLogLevel, port uint16, user, password string, uid, gid int) error {
func (c *configurator) MakeConf(logLevel models.TinyProxyLogLevel,
port uint16, user, password string, uid, gid int) error {
c.logger.Info("generating tinyproxy configuration file")
lines := generateConf(logLevel, port, user, password, uid, gid)
return c.fileManager.WriteLinesToFile(string(constants.TinyProxyConf),
lines,
files.Ownership(uid, gid),
files.Permissions(0400))
files.Permissions(constants.UserReadPermission))
}
func generateConf(logLevel models.TinyProxyLogLevel, port uint16, user, password string, uid, gid int) (lines []string) {
func generateConf(logLevel models.TinyProxyLogLevel, port uint16, user, password string, uid, gid int) (
lines []string) {
confMapping := map[string]string{
"User": fmt.Sprintf("%d", uid),
"Group": fmt.Sprintf("%d", gid),
+10 -4
View File
@@ -37,10 +37,16 @@ type looper struct {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Error(err)
l.logger.Info("retrying in 1 minute")
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel() // just for the linter
<-ctx.Done()
const waitTime = time.Minute
l.logger.Info("retrying in %s", waitTime)
timer := time.NewTimer(waitTime)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
func NewLooper(conf Configurator, firewallConf firewall.Configurator, settings settings.TinyProxy,
-2
View File
@@ -3,10 +3,8 @@ package updater
import (
"context"
"net"
"net/http"
)
type (
httpGetFunc func(url string) (r *http.Response, err error)
lookupIPFunc func(ctx context.Context, host string) (ips []net.IP, err error)
)
+10 -4
View File
@@ -70,10 +70,16 @@ func (l *looper) SetPeriod(period time.Duration) {
func (l *looper) logAndWait(ctx context.Context, err error) {
l.logger.Error(err)
l.logger.Info("retrying in 5 minutes")
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel() // just for the linter
<-ctx.Done()
const waitTime = 5 * time.Minute
l.logger.Info("retrying in %s", waitTime)
timer := time.NewTimer(waitTime)
select {
case <-timer.C:
case <-ctx.Done():
if !timer.Stop() {
<-timer.C
}
}
}
func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
+8 -13
View File
@@ -1,18 +1,19 @@
package updater
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"sort"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/golibs/network"
)
func (u *updater) updateMullvad() (err error) {
servers, err := findMullvadServers(u.httpGet)
func (u *updater) updateMullvad(ctx context.Context) (err error) {
servers, err := findMullvadServers(ctx, u.client)
if err != nil {
return fmt.Errorf("cannot update Mullvad servers: %w", err)
}
@@ -24,19 +25,14 @@ func (u *updater) updateMullvad() (err error) {
return nil
}
func findMullvadServers(httpGet httpGetFunc) (servers []models.MullvadServer, err error) {
func findMullvadServers(ctx context.Context, client network.Client) (servers []models.MullvadServer, err error) {
const url = "https://api.mullvad.net/www/relays/openvpn/"
response, err := httpGet(url)
bytes, status, err := client.Get(ctx, url)
if err != nil {
return nil, err
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf(response.Status)
}
bytes, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
if status != http.StatusOK {
return nil, fmt.Errorf("HTTP status code %d", status)
}
var data []struct {
Country string `json:"country_name"`
@@ -89,7 +85,6 @@ func findMullvadServers(httpGet httpGetFunc) (servers []models.MullvadServer, er
return servers, nil
}
//nolint:goconst
func stringifyMullvadServers(servers []models.MullvadServer) (s string) {
s = "func MullvadServers() []models.MullvadServer {\n"
s += " return []models.MullvadServer{\n"
+1
View File
@@ -18,6 +18,7 @@ func Test_stringifyMullvadServers(t *testing.T) {
IPs: []net.IP{{1, 1, 1, 1}},
IPsV6: []net.IP{{1, 1, 1, 1}},
}}
//nolint:lll
expected := `
func MullvadServers() []models.MullvadServer {
return []models.MullvadServer{
+12 -14
View File
@@ -1,9 +1,9 @@
package updater
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"sort"
@@ -11,10 +11,11 @@ import (
"strings"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/golibs/network"
)
func (u *updater) updateNordvpn() (err error) {
servers, warnings, err := findNordvpnServers(u.httpGet)
func (u *updater) updateNordvpn(ctx context.Context) (err error) {
servers, warnings, err := findNordvpnServers(ctx, u.client)
if u.options.CLI {
for _, warning := range warnings {
u.logger.Warn("Nordvpn: %s", warning)
@@ -31,19 +32,15 @@ func (u *updater) updateNordvpn() (err error) {
return nil
}
func findNordvpnServers(httpGet httpGetFunc) (servers []models.NordvpnServer, warnings []string, err error) {
func findNordvpnServers(ctx context.Context, client network.Client) (
servers []models.NordvpnServer, warnings []string, err error) {
const url = "https://nordvpn.com/api/server"
response, err := httpGet(url)
bytes, status, err := client.Get(ctx, url)
if err != nil {
return nil, nil, err
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, nil, fmt.Errorf(response.Status)
}
bytes, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, nil, err
if status != http.StatusOK {
return nil, nil, fmt.Errorf("HTTP status code %d", status)
}
var data []struct {
IPAddress string `json:"ip_address"`
@@ -71,7 +68,9 @@ func findNordvpnServers(httpGet httpGetFunc) (servers []models.NordvpnServer, wa
}
ip := net.ParseIP(jsonServer.IPAddress)
if ip == nil || ip.To4() == nil {
return nil, nil, fmt.Errorf("IP address %q is not a valid IPv4 address for server %q", jsonServer.IPAddress, jsonServer.Name)
return nil, nil,
fmt.Errorf("IP address %q is not a valid IPv4 address for server %q",
jsonServer.IPAddress, jsonServer.Name)
}
i := strings.IndexRune(jsonServer.Name, '#')
if i < 0 {
@@ -94,7 +93,6 @@ func findNordvpnServers(httpGet httpGetFunc) (servers []models.NordvpnServer, wa
return servers, warnings, nil
}
//nolint:goconst
func stringifyNordvpnServers(servers []models.NordvpnServer) (s string) {
s = "func NordvpnServers() []models.NordvpnServer {\n"
s += " return []models.NordvpnServer{\n"

Some files were not shown because too many files have changed in this diff Show More