chore(internal/providers): simplify OpenVPN config building

This commit is contained in:
Quentin McGaw
2022-04-25 07:57:45 +00:00
parent 4bde50fb3a
commit 7ff14a356c
27 changed files with 596 additions and 1438 deletions

View File

@@ -41,10 +41,8 @@ func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) e
if err != nil {
return err
}
lines, err := providerConf.BuildConf(connection, allSettings.VPN.OpenVPN)
if err != nil {
return err
}
lines := providerConf.BuildConf(connection, allSettings.VPN.OpenVPN)
fmt.Println(strings.Join(lines, "\n"))
return nil

View File

@@ -1,7 +1,6 @@
package models
import (
"fmt"
"net"
)
@@ -28,14 +27,6 @@ func (c *Connection) Equal(other Connection) bool {
c.PubKey == other.PubKey
}
func (c Connection) OpenVPNRemoteLine() (line string) {
return "remote " + c.IP.String() + " " + fmt.Sprint(c.Port)
}
func (c Connection) OpenVPNProtoLine() (line string) {
return "proto " + c.Protocol
}
// UpdateEmptyWith updates each field of the connection where the
// value is not set using the value given as arguments.
func (c *Connection) UpdateEmptyWith(ip net.IP, port uint16, protocol string) {

View File

@@ -15,8 +15,8 @@ import (
var ErrExtractData = errors.New("failed extracting information from custom configuration file")
func (p *Provider) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
lines, _, err = p.extractor.Data(*settings.ConfFile)
settings settings.OpenVPN) (lines []string) {
lines, _, err := p.extractor.Data(*settings.ConfFile)
if err != nil {
// Configuration file is already validated in settings validation in
// internal/configuration/settings/openvpn.go in `validateOpenVPNConfigFilepath`.
@@ -26,7 +26,7 @@ func (p *Provider) BuildConf(connection models.Connection,
lines = modifyConfig(lines, connection, settings)
return lines, nil
return lines
}
func modifyConfig(lines []string, connection models.Connection,
@@ -66,8 +66,8 @@ func modifyConfig(lines []string, connection models.Connection,
}
// Add values
modified = append(modified, connection.OpenVPNProtoLine())
modified = append(modified, connection.OpenVPNRemoteLine())
modified = append(modified, "proto "+connection.Protocol)
modified = append(modified, fmt.Sprintf("remote %s %d", connection.IP, connection.Port))
modified = append(modified, "dev "+settings.Interface)
modified = append(modified, "mute-replay-warnings")
modified = append(modified, "auth-nocache")

View File

@@ -1,93 +1,26 @@
package cyberghost
import (
"fmt"
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/openvpn/parse"
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (c *Cyberghost) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
constants.AES256cbc,
constants.AES128gcm,
}
},
Auth: constants.SHA256,
Ping: 10,
CA: constants.CyberghostCA,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Cyberghost specific
"ping 10",
"remote-cert-tls server",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.CyberghostCA)...)
certData, err := parse.ExtractCert([]byte(*settings.ClientCrt))
if err != nil {
return nil, fmt.Errorf("client cert is not valid: %w", err)
}
lines = append(lines, utils.WrapOpenvpnCert(certData)...)
keyData, err := parse.ExtractPrivateKey([]byte(*settings.ClientKey))
if err != nil {
return nil, fmt.Errorf("client key is not valid: %w", err)
}
lines = append(lines, utils.WrapOpenvpnKey(keyData)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package expressvpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,79 +8,28 @@ import (
)
func (p *Provider) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Auth: constants.SHA512,
CA: constants.ExpressvpnCA,
Cert: constants.ExpressvpnCert,
RSAKey: constants.ExpressvpnRSAKey,
TLSAuth: constants.ExpressvpnTLSAuth,
MssFix: 1200,
FastIO: true,
Fragment: 1300,
SndBuf: 524288,
RcvBuf: 524288,
KeyDirection: "1",
VerifyX509Type: "name-prefix",
// Always verify against `Server` x509 name prefix, security hole I guess?
VerifyX509Name: "Server",
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
mssFix := *settings.MSSFix
if mssFix == 0 {
const defaultMSSFix = 1200
mssFix = defaultMSSFix
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Expressvpn specific
"fast-io",
"fragment 1300",
"mssfix " + strconv.Itoa(int(mssFix)),
"sndbuf 524288",
"rcvbuf 524288",
"verify-x509-name Server name-prefix", // security hole I guess?
"remote-cert-tls server", // updated name of ns-cert-type
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"mute-replay-warnings",
"auth-nocache",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Modified variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCert(
constants.ExpressvpnCert)...)
lines = append(lines, utils.WrapOpenvpnRSAKey(
constants.ExpressvpnRSAKey)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.ExpressvpnTLSAuth)...)
lines = append(lines, utils.WrapOpenvpnCA(
constants.ExpressvpnCA)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package fastestvpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,74 +8,28 @@ import (
)
func (f *Fastestvpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
MssFix: 1450,
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
AuthToken: true,
KeyDirection: "1",
RenegDisabled: true,
CA: constants.FastestvpnCA,
TLSAuth: constants.FastestvpnTLSAuth,
UDPLines: []string{
"tun-mtu 1500",
"tun-mtu-extra 32",
"ping 15",
},
ExtraLines: []string{
"comp-lzo",
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
mssFix := *settings.MSSFix
if mssFix == 0 {
mssFix = 1450
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Fastestvpn specific
"mssfix " + strconv.Itoa(int(mssFix)), // defaults to 1450
"tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
"comp-lzo",
"reneg-sec 0",
// Added constant values
"auth-nocache",
"mute-replay-warnings",
// "pull-filter ignore \"auth-token\"", // needed for FastestVPN
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
lines = append(lines, "tun-mtu 1500") // FastestVPN specific
lines = append(lines, "tun-mtu-extra 32") // FastestVPN specific
lines = append(lines, "ping 15") // FastestVPN specific
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.FastestvpnCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.FastestvpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package hidemyass
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,68 +8,18 @@ import (
)
func (h *HideMyAss) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
RemoteCertTLS: true,
CA: constants.HideMyAssCA,
Cert: constants.HideMyAssCert,
RSAKey: constants.HideMyAssRSAKey,
Ping: 5,
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// HideMyAss specific
"ping 5",
"remote-cert-tls server", // updated name of ns-cert-type
"auth-user-pass " + constants.OpenVPNAuthConf,
// Added constant values
"mute-replay-warnings",
"auth-nocache",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if *settings.Auth != "" {
lines = append(lines, "auth "+*settings.Auth)
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.HideMyAssCA)...)
lines = append(lines, utils.WrapOpenvpnCert(
constants.HideMyAssCert)...)
lines = append(lines, utils.WrapOpenvpnRSAKey(
constants.HideMyAssRSAKey)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package ipvanish
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,64 +8,16 @@ import (
)
func (i *Ipvanish) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Auth: constants.SHA256,
VerifyX509Type: "name",
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
CA: constants.IpvanishCA,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Ipvanish specific
"verify-x509-name " + connection.Hostname + " name",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"mute-replay-warnings",
"auth-nocache",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(constants.IpvanishCA)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,9 +1,6 @@
package ivpn
import (
"strconv"
"strings"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -11,71 +8,22 @@ import (
)
func (i *Ivpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Ping: 5,
RemoteCertTLS: true,
VerifyX509Type: "name-prefix",
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
CA: constants.IvpnCA,
TLSAuth: constants.IvpnTLSAuth,
ExtraLines: []string{
"key-direction 1",
},
}
namePrefix := strings.Split(connection.Hostname, ".")[0]
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// IVPN specific
"ping 5",
"remote-cert-tls server", // updated name of ns-cert-type
"key-direction 1",
"verify-x509-name " + namePrefix + " name-prefix",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
"auth-user-pass " + constants.OpenVPNAuthConf,
// Added constant values
"mute-replay-warnings",
"auth-nocache",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if *settings.Auth != "" {
lines = append(lines, "auth "+*settings.Auth)
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.IvpnCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.IvpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package mullvad
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,73 +8,21 @@ import (
)
func (m *Mullvad) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc, constants.AES128gcm}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
constants.AES128gcm,
},
Ping: 10,
RemoteCertTLS: true,
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
SndBuf: 524288,
RcvBuf: 524288,
CA: constants.MullvadCA,
UDPLines: []string{"fast-io"},
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
"auth-user-pass " + constants.OpenVPNAuthConf,
// Mullvad specific
"ping 10",
"remote-cert-tls server",
"sndbuf 524288",
"rcvbuf 524288",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if *settings.Auth != "" {
lines = append(lines, "auth "+*settings.Auth)
}
if connection.Protocol == constants.UDP {
lines = append(lines, "fast-io")
lines = append(lines, "explicit-exit-notify")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.MullvadCA)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package nordvpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,75 +8,29 @@ import (
)
func (n *Nordvpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc, constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
constants.AES256gcm,
},
Auth: constants.SHA512,
Ping: 15,
RemoteCertTLS: true,
MssFix: 1450,
CA: constants.NordvpnCA,
TLSAuth: constants.NordvpnTLSAuth,
TunMTUExtra: 32,
RenegDisabled: true,
KeyDirection: "1",
UDPLines: []string{
"fast-io",
},
ExtraLines: []string{
"comp-lzo no", // Explicitly disable compression
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
mssFix := *settings.MSSFix
if mssFix == 0 {
mssFix = 1450
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Nordvpn specific
"tun-mtu-extra 32",
"mssfix " + strconv.Itoa(int(mssFix)),
"ping 15",
"remote-cert-tls server",
"reneg-sec 0",
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
"comp-lzo no", // Explicitly disable compression
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "fast-io")
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.NordvpnCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.NordvpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package perfectprivacy
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,81 +8,30 @@ import (
)
func (p *Perfectprivacy) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc, constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
constants.AES256gcm,
},
Auth: constants.SHA512,
MssFix: 1450,
Ping: 5,
CA: constants.PerfectprivacyCA,
Cert: constants.PerfectprivacyCert,
Key: constants.PerfectprivacyKey,
TLSCrypt: constants.PerfectprivacyTLSCrypt,
TLSCipher: "TLS_CHACHA20_POLY1305_SHA256:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS_AES_256_GCM_SHA384:TLS-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
TunMTU: 1500,
TunMTUExtra: 32,
RenegSec: 3600,
KeyDirection: "1",
IPv6Lines: []string{
"redirect-gateway def1",
`pull-filter ignore "redirect-gateway def1 ipv6"`,
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
mssFix := *settings.MSSFix
if mssFix == 0 {
mssFix = 1450
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Perfect Privacy specific
"ping 5",
"tun-mtu 1500",
"tun-mtu-extra 32",
"mssfix " + strconv.Itoa(int(mssFix)),
"reneg-sec 3600",
"key-direction 1",
"tls-cipher TLS_CHACHA20_POLY1305_SHA256:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS_AES_256_GCM_SHA384:TLS-RSA-WITH-AES-256-CBC-SHA", //nolint:lll
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Modified variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
// Perfect Privacy specific IPv6
lines = append(lines, "redirect-gateway def1")
lines = append(lines, `pull-filter ignore "redirect-gateway def1 ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.PerfectprivacyCA)...)
lines = append(lines, utils.WrapOpenvpnCert(
constants.PerfectprivacyCert)...)
lines = append(lines, utils.WrapOpenvpnKey(
constants.PerfectprivacyKey)...)
lines = append(lines, utils.WrapOpenvpnTLSCrypt(
constants.PerfectprivacyTLSCrypt)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package privado
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,67 +8,18 @@ import (
)
func (p *Privado) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Auth: constants.SHA256,
Ping: 10,
TLSCipher: "TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
VerifyX509Type: "name",
CA: constants.PrivadoCA,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Privado specific
"ping 10",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
"verify-x509-name " + connection.Hostname + " name",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.PrivadoCA)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package privateinternetaccess
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,87 +8,30 @@ import (
)
func (p *PIA) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
var defaultCipher, defaultAuth, X509CRL, certificate string
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
RenegDisabled: true,
AuthUserPass: true,
}
switch *settings.PIAEncPreset {
case constants.PIAEncryptionPresetNormal:
defaultCipher = constants.AES128cbc
defaultAuth = constants.SHA1
X509CRL = constants.PiaX509CRLNormal
certificate = constants.PiaCANormal
providerSettings.Ciphers = []string{constants.AES128cbc}
providerSettings.Auth = constants.SHA1
providerSettings.CRLVerify = constants.PiaX509CRLNormal
providerSettings.CA = constants.PiaCANormal
case constants.PIAEncryptionPresetNone:
defaultCipher = "none"
defaultAuth = "none"
X509CRL = constants.PiaX509CRLNormal
certificate = constants.PiaCANormal
providerSettings.Ciphers = []string{"none"}
providerSettings.Auth = "none"
providerSettings.CRLVerify = constants.PiaX509CRLNormal
providerSettings.CA = constants.PiaCANormal
default: // strong
defaultCipher = constants.AES256cbc
defaultAuth = constants.SHA256
X509CRL = constants.PiaX509CRLStrong
certificate = constants.PiaCAStrong
providerSettings.Ciphers = []string{constants.AES256cbc}
providerSettings.Auth = constants.SHA256
providerSettings.CRLVerify = constants.PiaX509CRLStrong
providerSettings.CA = constants.PiaCAStrong
}
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{defaultCipher}
}
auth := *settings.Auth
if auth == "" {
auth = defaultAuth
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// PIA specific
"remote-cert-tls server",
"reneg-sec 0",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
if len(settings.Ciphers) > 0 {
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(certificate)...)
lines = append(lines, utils.WrapOpenvpnCRLVerify(X509CRL)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package privatevpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,68 +8,19 @@ import (
)
func (p *Privatevpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES128gcm}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES128gcm,
},
Auth: constants.SHA256,
CA: constants.PrivatevpnCA,
TLSAuth: constants.PrivatevpnTLSAuth,
UDPLines: []string{
"key-direction 1",
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Privatevpn specific
"remote-cert-tls server",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "key-direction 1")
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.PrivatevpnCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.PrivatevpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package protonvpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,74 +8,24 @@ import (
)
func (p *Protonvpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
//nolint:gomnd
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Auth: constants.SHA512,
MssFix: 1450,
TunMTUExtra: 32,
RenegDisabled: true,
KeyDirection: "1",
CA: constants.ProtonvpnCA,
TLSAuth: constants.ProtonvpnTLSAuth,
UDPLines: []string{
"fast-io",
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
mssFix := *settings.MSSFix
if mssFix == 0 {
const defaultMSSFix = 1450
mssFix = defaultMSSFix
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Protonvpn specific
"remote-cert-tls server",
"tun-mtu-extra 32",
"mssfix " + strconv.Itoa(int(mssFix)),
"reneg-sec 0",
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "fast-io")
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.ProtonvpnCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.ProtonvpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -38,7 +38,7 @@ import (
// Provider contains methods to read and modify the openvpn configuration to connect as a client.
type Provider interface {
GetConnection(selection settings.ServerSelection) (connection models.Connection, err error)
BuildConf(connection models.Connection, settings settings.OpenVPN) (lines []string, err error)
BuildConf(connection models.Connection, settings settings.OpenVPN) (lines []string)
PortForwarder
}

View File

@@ -1,8 +1,6 @@
package purevpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,71 +8,18 @@ import (
)
func (p *Purevpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
},
Ping: 10, //nolint:gomnd
CA: constants.PurevpnCA,
Cert: constants.PurevpnCert,
Key: constants.PurevpnKey,
TLSAuth: constants.PurevpnTLSAuth,
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Purevpn specific
"ping 10",
"remote-cert-tls server",
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if *settings.Auth != "" {
lines = append(lines, "auth "+*settings.Auth)
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.PurevpnCA)...)
lines = append(lines, utils.WrapOpenvpnCert(
constants.PurevpnCert)...)
lines = append(lines, utils.WrapOpenvpnKey(
constants.PurevpnKey)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.PurevpnTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package surfshark
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,74 +8,21 @@ import (
)
func (s *Surfshark) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
},
Auth: constants.SHA512,
RenegDisabled: true,
KeyDirection: "1",
Ping: 15, //nolint:gomnd
MssFix: 1450, //nolint:gomnd
TunMTUExtra: 32, //nolint:gomnd
CA: constants.SurfsharkCA,
TLSAuth: constants.SurfsharkTLSAuth,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
mssFix := *settings.MSSFix
if mssFix == 0 {
const defaultMSSFix = 1450
mssFix = defaultMSSFix
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Surfshark specific
"tun-mtu-extra 32",
"mssfix " + strconv.Itoa(int(mssFix)),
"ping 15",
"remote-cert-tls server",
"reneg-sec 0",
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.SurfsharkCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.SurfsharkTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package torguard
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,77 +8,23 @@ import (
)
func (t *Torguard) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
},
Auth: constants.SHA256,
MssFix: 1450, //nolint:gomnd
TunMTUExtra: 32, //nolint:gomnd
SndBuf: 393216, //nolint:gomnd
RcvBuf: 393216, //nolint:gomnd
Ping: 5, //nolint:gomnd
RenegDisabled: true,
KeyDirection: "1",
CA: constants.TorguardCA,
TLSAuth: constants.TorguardTLSAuth,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
mssFix := *settings.MSSFix
if mssFix == 0 {
const defaultMSSFix = 1450
mssFix = defaultMSSFix
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Torguard specific
"tun-mtu-extra 32",
"mssfix " + strconv.Itoa(int(mssFix)),
"sndbuf 393216",
"rcvbuf 393216",
"ping 5",
"remote-cert-tls server",
"reneg-sec 0",
"key-direction 1",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if connection.Protocol == constants.UDP {
lines = append(lines, "fast-io")
lines = append(lines, "explicit-exit-notify")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.TorguardCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.TorguardTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -7,6 +7,10 @@ import (
)
func CipherLines(ciphers []string, version string) (lines []string) {
if len(ciphers) == 0 {
return nil
}
switch version {
case constants.Openvpn24:
return []string{

View File

@@ -1,5 +1,254 @@
package utils
import (
"fmt"
"strings"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/openvpn/parse"
)
type OpenVPNProviderSettings struct {
Ping int
RemoteCertTLS bool
Ciphers []string
Auth string
CA string
CRLVerify string
Cert string
Key string
RSAKey string
TLSAuth string
TLSCrypt string
MssFix uint16
FastIO bool
AuthUserPass bool
AuthToken bool
Fragment uint16
SndBuf uint32
RcvBuf uint32
// VerifyX509Name can be set to a custom name to verify against.
// Note VerifyX509Type has to be set for it to be verified.
// If it is left unset, the code will deduce a name to verify against
// using the connection hostname and according to VerifyX509Type.
VerifyX509Name string
// VerifyX509Type can be "name-prefix", "name"
VerifyX509Type string
TLSCipher string
TunMTU uint16
TunMTUExtra uint16
RenegDisabled bool
RenegSec uint16
KeyDirection string
ExtraLines []string
UDPLines []string
IPv6Lines []string
}
//nolint:gocognit,gocyclo
func OpenVPNConfig(provider OpenVPNProviderSettings,
connection models.Connection,
settings settings.OpenVPN) []string {
var lines openvpnConfigLines
lines.add("client")
lines.add("nobind")
lines.add("tls-exit") // exit OpenVPN on a TLS error
lines.add("auth-nocache") // do not cache auth credentials
lines.add("mute-replay-warnings") // these are often ignored by some VPN providers
lines.add("auth-retry", "nointeract") // retry authenticating without interaction
lines.add("suppress-timestamps") // do not log timestamps, the Gluetun logger takes care of it
lines.add("dev", settings.Interface)
lines.add("verb", fmt.Sprint(*settings.Verbosity))
lines.add("auth-user-pass", constants.OpenVPNAuthConf)
lines.add("proto", connection.Protocol)
lines.add("remote", connection.IP.String(), fmt.Sprint(connection.Port))
if !provider.AuthToken {
lines.add("pull-filter", "ignore", `"auth-token"`) // prevent auth failed loops
}
if provider.KeyDirection != "" {
lines.add("key-direction", provider.KeyDirection)
}
if provider.Ping > 0 {
lines.add("ping", fmt.Sprint(provider.Ping))
}
if provider.RenegDisabled {
lines.add("reneg-sec", "0")
} else if provider.RenegSec > 0 {
lines.add("reneg-sec", fmt.Sprint(provider.RenegSec))
}
if provider.RemoteCertTLS {
// equivalent to older 'ns-cert-type' option
lines.add("remote-cert-tls server")
}
x509Type := provider.VerifyX509Type
if x509Type != "" {
x509Name := provider.VerifyX509Name
if x509Name == "" {
// find name from connection hostname depending on type
switch x509Type {
case "name":
x509Name = connection.Hostname
case "name-prefix":
x509Name = strings.Split(connection.Hostname, ".")[0]
default:
panic(fmt.Sprintf("verify-x509-name type not supported: %q", x509Type))
}
}
lines.add("verify-x509-name", x509Name, x509Type)
}
if provider.TLSCipher != "" {
lines.add("tls-cipher", provider.TLSCipher)
}
if provider.FastIO {
lines.add("fast-io")
}
ciphers := defaultStringSlice(settings.Ciphers, provider.Ciphers)
cipherLines := CipherLines(ciphers, settings.Version)
lines.addLines(cipherLines)
auth := defaultString(*settings.Auth, provider.Auth)
if auth != "" {
lines.add("auth", auth)
}
if provider.TunMTU > 0 {
lines.add("tun-mtu", fmt.Sprint(provider.TunMTU))
}
if provider.TunMTUExtra > 0 {
lines.add("tun-mtu-extra", fmt.Sprint(provider.TunMTUExtra))
}
mssFix := defaultUint16(*settings.MSSFix, provider.MssFix)
if mssFix > 0 {
lines.add("mssfix", fmt.Sprint(mssFix))
}
if provider.SndBuf > 0 {
lines.add("sndbuf", fmt.Sprint(provider.SndBuf))
}
if provider.RcvBuf > 0 {
lines.add("rcvbuf", fmt.Sprint(provider.RcvBuf))
}
if connection.Protocol == constants.UDP {
lines.add("explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines.add("user", settings.ProcessUser)
lines.add("persist-tun")
lines.add("persist-key")
}
if *settings.IPv6 {
lines.add("tun-ipv6")
} else {
lines.add("pull-filter", "ignore", `"route-ipv6"`)
lines.add("pull-filter", "ignore", `"ifconfig-ipv6"`)
lines.addLines(provider.IPv6Lines)
}
if provider.CA != "" {
lines.addLines(WrapOpenvpnCA(provider.CA))
}
if provider.CRLVerify != "" {
lines.addLines(WrapOpenvpnCRLVerify(provider.CRLVerify))
}
if provider.Cert != "" {
lines.addLines(WrapOpenvpnCert(provider.Cert))
}
if provider.Key != "" {
lines.addLines(WrapOpenvpnKey(provider.Key))
}
if provider.RSAKey != "" {
lines.addLines(WrapOpenvpnRSAKey(provider.RSAKey))
}
if provider.TLSAuth != "" {
lines.addLines(WrapOpenvpnTLSAuth(provider.TLSAuth))
}
if provider.TLSCrypt != "" {
lines.addLines(WrapOpenvpnTLSCrypt(provider.TLSCrypt))
}
if *settings.ClientCrt != "" {
certData, err := parse.ExtractCert([]byte(*settings.ClientCrt))
panicOnError(err, "cannot extract client crt")
lines.addLines(WrapOpenvpnCert(certData))
}
if *settings.ClientKey != "" {
keyData, err := parse.ExtractPrivateKey([]byte(*settings.ClientKey))
panicOnError(err, "cannot extract client private key")
lines.addLines(WrapOpenvpnKey(keyData))
}
lines.addLines(provider.ExtraLines)
// Add a trailing empty line
lines.add("")
return lines
}
type openvpnConfigLines []string
func (o *openvpnConfigLines) add(words ...string) {
*o = append(*o, strings.Join(words, " "))
}
func (o *openvpnConfigLines) addLines(lines []string) {
for _, line := range lines {
o.add(line)
}
}
func defaultString(value, defaultValue string) string {
if value == "" {
return defaultValue
}
return value
}
func defaultUint16(value, defaultValue uint16) uint16 {
if value == 0 {
return defaultValue
}
return value
}
func defaultStringSlice(value, defaultValue []string) (
result []string) {
if len(value) > 0 {
result = make([]string, len(value))
copy(result, value)
return result
}
result = make([]string, len(defaultValue))
copy(result, defaultValue)
return result
}
func panicOnError(err error, context string) {
if err == nil {
return
}
panicMessage := fmt.Sprintf("%s: %s", context, err)
panic(panicMessage)
}
func WrapOpenvpnCA(certificate string) (lines []string) {
return []string{
"<ca>",

View File

@@ -1,86 +1,23 @@
package vpnunlimited
import (
"fmt"
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/openvpn/parse"
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// VPNUnlimited specific
"ping 5",
"remote-cert-tls server",
"reneg-sec 0",
"route-metric 1",
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: false,
Ping: 5, //nolint:gomnd
RenegDisabled: true,
CA: constants.VPNUnlimitedCA,
ExtraLines: []string{
"route-metric 1",
},
}
if len(settings.Ciphers) > 0 {
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
}
if *settings.Auth != "" {
lines = append(lines, "auth "+*settings.Auth)
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.VPNUnlimitedCA)...)
certData, err := parse.ExtractCert([]byte(*settings.ClientCrt))
if err != nil {
return nil, fmt.Errorf("client cert is not valid: %w", err)
}
lines = append(lines, utils.WrapOpenvpnCert(certData)...)
keyData, err := parse.ExtractPrivateKey([]byte(*settings.ClientKey))
if err != nil {
return nil, fmt.Errorf("client key is not valid: %w", err)
}
lines = append(lines, utils.WrapOpenvpnKey(keyData)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package vyprvpn
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,64 +8,21 @@ import (
)
func (v *Vyprvpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256cbc}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256cbc,
},
Auth: constants.SHA256,
Ping: 10, //nolint:gomnd
CA: constants.VyprvpnCA,
TLSCipher: "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
ExtraLines: []string{
"comp-lzo",
},
// VerifyX509Name: []string{"lu1.vyprvpn.com","name"},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA256
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Vyprvpn specific
"ping 10",
"remote-cert-tls server",
// "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", //nolint:lll
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
"comp-lzo",
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.VyprvpnCA)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,91 +1,29 @@
package wevpn
import (
"fmt"
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/openvpn/parse"
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (w *Wevpn) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{constants.AES256gcm}
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
},
Auth: constants.SHA512,
Ping: 30, //nolint:gomnd
RenegDisabled: true,
CA: constants.WevpnCA,
Cert: constants.WevpnCert,
TLSCrypt: constants.WevpnTLSCrypt,
ExtraLines: []string{
"redirect-gateway def1 bypass-dhcp",
},
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Wevpn specific
"ping 30",
"remote-cert-tls server",
"redirect-gateway def1 bypass-dhcp",
"reneg-sec 0",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Modified variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if *settings.IPv6 {
lines = append(lines, "tun-ipv6")
} else {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
keyData, err := parse.ExtractPrivateKey([]byte(*settings.ClientKey))
if err != nil {
return nil, fmt.Errorf("client key is not valid: %w", err)
}
lines = append(lines, utils.WrapOpenvpnKey(keyData)...)
lines = append(lines, utils.WrapOpenvpnCA(
constants.WevpnCA)...)
lines = append(lines, utils.WrapOpenvpnCert(
constants.WevpnCert)...)
lines = append(lines, utils.WrapOpenvpnTLSCrypt(
constants.WevpnTLSCrypt)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -1,8 +1,6 @@
package windscribe
import (
"strconv"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
@@ -10,75 +8,22 @@ import (
)
func (w *Windscribe) BuildConf(connection models.Connection,
settings settings.OpenVPN) (lines []string, err error) {
if len(settings.Ciphers) == 0 {
settings.Ciphers = []string{
settings settings.OpenVPN) (lines []string) {
providerSettings := utils.OpenVPNProviderSettings{
RemoteCertTLS: true,
AuthUserPass: true,
Ciphers: []string{
constants.AES256gcm,
constants.AES256cbc,
constants.AES128gcm,
}
},
Auth: constants.SHA512,
Ping: 10, //nolint:gomnd
VerifyX509Type: "name",
KeyDirection: "1",
RenegDisabled: true,
CA: constants.WindscribeCA,
TLSAuth: constants.WindscribeTLSAuth,
}
auth := *settings.Auth
if auth == "" {
auth = constants.SHA512
}
lines = []string{
"client",
"nobind",
"tls-exit",
"dev " + settings.Interface,
"verb " + strconv.Itoa(*settings.Verbosity),
// Windscribe specific
"ping 10",
"remote-cert-tls server",
"verify-x509-name " + connection.Hostname + " name",
"key-direction 1",
"reneg-sec 0",
"auth-user-pass " + constants.OpenVPNAuthConf,
"auth " + auth,
// Added constant values
"auth-nocache",
"mute-replay-warnings",
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
"auth-retry nointeract",
"suppress-timestamps",
// Connection variables
connection.OpenVPNProtoLine(),
connection.OpenVPNRemoteLine(),
}
lines = append(lines, utils.CipherLines(settings.Ciphers, settings.Version)...)
if connection.Protocol == constants.UDP {
lines = append(lines, "explicit-exit-notify")
}
if settings.ProcessUser != "root" {
lines = append(lines, "user "+settings.ProcessUser)
lines = append(lines, "persist-tun")
lines = append(lines, "persist-key")
}
if *settings.MSSFix > 0 {
lines = append(lines, "mssfix "+strconv.Itoa(int(*settings.MSSFix)))
}
if !*settings.IPv6 {
lines = append(lines, `pull-filter ignore "route-ipv6"`)
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
}
lines = append(lines, utils.WrapOpenvpnCA(
constants.WindscribeCA)...)
lines = append(lines, utils.WrapOpenvpnTLSAuth(
constants.WindscribeTLSAuth)...)
lines = append(lines, "")
return lines, nil
return utils.OpenVPNConfig(providerSettings, connection, settings)
}

View File

@@ -22,10 +22,7 @@ func setupOpenVPN(ctx context.Context, fw firewall.VPNConnectionSetter,
return nil, "", fmt.Errorf("failed finding a valid server connection: %w", err)
}
lines, err := providerConf.BuildConf(connection, settings.OpenVPN)
if err != nil {
return nil, "", fmt.Errorf("failed building configuration: %w", err)
}
lines := providerConf.BuildConf(connection, settings.OpenVPN)
if err := openvpnConf.WriteConfig(lines); err != nil {
return nil, "", fmt.Errorf("failed writing configuration to file: %w", err)