OPENVPN_CIPHER variable (#100), refers to #94 and #59

This commit is contained in:
Quentin McGaw
2020-03-26 20:29:32 -04:00
committed by GitHub
parent d534f92432
commit 15a549be11
9 changed files with 37 additions and 11 deletions

View File

@@ -162,6 +162,7 @@ docker run --rm --network=container:pia alpine:3.11 wget -qO- https://ipinfo.io
| `OPENVPN_VERBOSITY` | `1` | Openvpn verbosity level from 0 to 6 | | `OPENVPN_VERBOSITY` | `1` | Openvpn verbosity level from 0 to 6 |
| `OPENVPN_ROOT` | `no` | Run OpenVPN as root, `yes` or `no` | | `OPENVPN_ROOT` | `no` | Run OpenVPN as root, `yes` or `no` |
| `OPENVPN_TARGET_IP` | | Specify a target VPN server IP address to use, valid for Mullvad and Private Internet Access | | `OPENVPN_TARGET_IP` | | Specify a target VPN server IP address to use, valid for Mullvad and Private Internet Access |
| `OPENVPN_CIPHER` | | Specify a custom cipher to use, use at your own risk. It will also set `ncp-disable` if using AES GCM for PIA |
## Connect to it ## Connect to it

View File

@@ -132,12 +132,12 @@ func main() {
case "pia": case "pia":
connections, err = piaConf.GetOpenVPNConnections(allSettings.PIA.Region, allSettings.OpenVPN.NetworkProtocol, allSettings.PIA.Encryption, allSettings.OpenVPN.TargetIP) connections, err = piaConf.GetOpenVPNConnections(allSettings.PIA.Region, allSettings.OpenVPN.NetworkProtocol, allSettings.PIA.Encryption, allSettings.OpenVPN.TargetIP)
e.FatalOnError(err) e.FatalOnError(err)
err = piaConf.BuildConf(connections, allSettings.PIA.Encryption, allSettings.OpenVPN.Verbosity, uid, gid, allSettings.OpenVPN.Root) err = piaConf.BuildConf(connections, allSettings.PIA.Encryption, allSettings.OpenVPN.Verbosity, uid, gid, allSettings.OpenVPN.Root, allSettings.OpenVPN.Cipher)
e.FatalOnError(err) e.FatalOnError(err)
case "mullvad": case "mullvad":
connections, err = mullvadConf.GetOpenVPNConnections(allSettings.Mullvad.Country, allSettings.Mullvad.City, allSettings.Mullvad.ISP, allSettings.OpenVPN.NetworkProtocol, allSettings.Mullvad.Port, allSettings.OpenVPN.TargetIP) connections, err = mullvadConf.GetOpenVPNConnections(allSettings.Mullvad.Country, allSettings.Mullvad.City, allSettings.Mullvad.ISP, allSettings.OpenVPN.NetworkProtocol, allSettings.Mullvad.Port, allSettings.OpenVPN.TargetIP)
e.FatalOnError(err) e.FatalOnError(err)
err = mullvadConf.BuildConf(connections, allSettings.OpenVPN.Verbosity, uid, gid, allSettings.OpenVPN.Root) err = mullvadConf.BuildConf(connections, allSettings.OpenVPN.Verbosity, uid, gid, allSettings.OpenVPN.Root, allSettings.OpenVPN.Cipher)
e.FatalOnError(err) e.FatalOnError(err)
} }

View File

@@ -35,10 +35,13 @@ func (c *configurator) GetOpenVPNConnections(country models.MullvadCountry, city
return connections, nil return connections, nil
} }
func (c *configurator) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool) (err error) { func (c *configurator) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher string) (err error) {
if len(connections) == 0 { if len(connections) == 0 {
return fmt.Errorf("at least one connection string is expected") return fmt.Errorf("at least one connection string is expected")
} }
if len(cipher) == 0 {
cipher = "AES-256-CBC"
}
lines := []string{ lines := []string{
"client", "client",
"dev tun", "dev tun",
@@ -53,7 +56,6 @@ func (c *configurator) BuildConf(connections []models.OpenVPNConnection, verbosi
// Mullvad specific // Mullvad specific
"sndbuf 524288", "sndbuf 524288",
"rcvbuf 524288", "rcvbuf 524288",
"cipher AES-256-CBC",
"tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA", "tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
// Added constant values // Added constant values
@@ -67,6 +69,7 @@ func (c *configurator) BuildConf(connections []models.OpenVPNConnection, verbosi
fmt.Sprintf("verb %d", verbosity), fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf), fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", string(connections[0].Protocol)), fmt.Sprintf("proto %s", string(connections[0].Protocol)),
fmt.Sprintf("cipher %s", cipher),
} }
if !root { if !root {
lines = append(lines, "user nonrootuser") lines = append(lines, "user nonrootuser")

View File

@@ -13,7 +13,7 @@ const logPrefix = "Mullvad configurator"
// Configurator contains methods to download, read and modify the openvpn configuration to connect as a client // Configurator contains methods to download, read and modify the openvpn configuration to connect as a client
type Configurator interface { type Configurator interface {
GetOpenVPNConnections(country models.MullvadCountry, city models.MullvadCity, provider models.MullvadProvider, protocol models.NetworkProtocol, customPort uint16, targetIP net.IP) (connections []models.OpenVPNConnection, err error) GetOpenVPNConnections(country models.MullvadCountry, city models.MullvadCity, provider models.MullvadProvider, protocol models.NetworkProtocol, customPort uint16, targetIP net.IP) (connections []models.OpenVPNConnection, err error)
BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool) (err error) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher string) (err error)
} }
type configurator struct { type configurator struct {

View File

@@ -3,6 +3,7 @@ package params
import ( import (
"fmt" "fmt"
"net" "net"
"strings"
libparams "github.com/qdm12/golibs/params" libparams "github.com/qdm12/golibs/params"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
@@ -63,3 +64,10 @@ func (p *paramsReader) GetTargetIP() (ip net.IP, err error) {
} }
return ip, nil return ip, nil
} }
// GetOpenVPNCipher obtains a custom cipher to use with OpenVPN
// from the environment variable OPENVPN_CIPHER
func (p *paramsReader) GetOpenVPNCipher() (cipher string, err error) {
cipher, err = p.envParams.GetEnv("OPENVPN_CIPHER")
return strings.ToLower(cipher), err
}

View File

@@ -38,6 +38,7 @@ type ParamsReader interface {
GetOpenVPNVerbosity() (verbosity int, err error) GetOpenVPNVerbosity() (verbosity int, err error)
GetOpenVPNRoot() (root bool, err error) GetOpenVPNRoot() (root bool, err error)
GetTargetIP() (ip net.IP, err error) GetTargetIP() (ip net.IP, err error)
GetOpenVPNCipher() (cipher string, err error)
// PIA getters // PIA getters
GetPortForwarding() (activated bool, err error) GetPortForwarding() (activated bool, err error)

View File

@@ -66,15 +66,19 @@ func (c *configurator) GetOpenVPNConnections(region models.PIARegion, protocol m
return connections, nil return connections, nil
} }
func (c *configurator) BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, verbosity, uid, gid int, root bool) (err error) { func (c *configurator) BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, verbosity, uid, gid int, root bool, cipher string) (err error) {
var X509CRL, certificate, cipherAlgo, authAlgo string var X509CRL, certificate, authAlgo string
if encryption == constants.PIAEncryptionNormal { if encryption == constants.PIAEncryptionNormal {
cipherAlgo = "aes-128-cbc" if len(cipher) == 0 {
cipher = "aes-128-cbc"
}
authAlgo = "sha1" authAlgo = "sha1"
X509CRL = constants.PIAX509CRL_NORMAL X509CRL = constants.PIAX509CRL_NORMAL
certificate = constants.PIACertificate_NORMAL certificate = constants.PIACertificate_NORMAL
} else { // strong encryption } else { // strong encryption
cipherAlgo = "aes-256-cbc" if len(cipher) == 0 {
cipher = "aes-256-cbc"
}
authAlgo = "sha256" authAlgo = "sha256"
X509CRL = constants.PIAX509CRL_STRONG X509CRL = constants.PIAX509CRL_STRONG
certificate = constants.PIACertificate_STRONG certificate = constants.PIACertificate_STRONG
@@ -104,9 +108,12 @@ func (c *configurator) BuildConf(connections []models.OpenVPNConnection, encrypt
fmt.Sprintf("verb %d", verbosity), fmt.Sprintf("verb %d", verbosity),
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf), fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", string(connections[0].Protocol)), fmt.Sprintf("proto %s", string(connections[0].Protocol)),
fmt.Sprintf("cipher %s", cipherAlgo), fmt.Sprintf("cipher %s", cipher),
fmt.Sprintf("auth %s", authAlgo), fmt.Sprintf("auth %s", authAlgo),
} }
if strings.HasSuffix(cipher, "-gcm") {
lines = append(lines, "ncp-disable")
}
if !root { if !root {
lines = append(lines, "user nonrootuser") lines = append(lines, "user nonrootuser")
} }

View File

@@ -18,7 +18,7 @@ const logPrefix = "PIA configurator"
type Configurator interface { type Configurator interface {
GetOpenVPNConnections(region models.PIARegion, protocol models.NetworkProtocol, GetOpenVPNConnections(region models.PIARegion, protocol models.NetworkProtocol,
encryption models.PIAEncryption, targetIP net.IP) (connections []models.OpenVPNConnection, err error) encryption models.PIAEncryption, targetIP net.IP) (connections []models.OpenVPNConnection, err error)
BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, verbosity, uid, gid int, root bool) (err error) BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, verbosity, uid, gid int, root bool, cipher string) (err error)
GetPortForward() (port uint16, err error) GetPortForward() (port uint16, err error)
WritePortForward(filepath models.Filepath, port uint16) (err error) WritePortForward(filepath models.Filepath, port uint16) (err error)
AllowPortForwardFirewall(device models.VPNDevice, port uint16) (err error) AllowPortForwardFirewall(device models.VPNDevice, port uint16) (err error)

View File

@@ -15,6 +15,7 @@ type OpenVPN struct {
Verbosity int Verbosity int
Root bool Root bool
TargetIP net.IP TargetIP net.IP
Cipher string
} }
// GetOpenVPNSettings obtains the OpenVPN settings using the params functions // GetOpenVPNSettings obtains the OpenVPN settings using the params functions
@@ -35,6 +36,10 @@ func GetOpenVPNSettings(params params.ParamsReader) (settings OpenVPN, err error
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.Cipher, err = params.GetOpenVPNCipher()
if err != nil {
return settings, err
}
return settings, nil return settings, nil
} }
@@ -49,6 +54,7 @@ func (o *OpenVPN) String() string {
"Verbosity level: " + fmt.Sprintf("%d", o.Verbosity), "Verbosity level: " + fmt.Sprintf("%d", o.Verbosity),
"Run as root: " + runAsRoot, "Run as root: " + runAsRoot,
"Target IP address: " + o.TargetIP.String(), "Target IP address: " + o.TargetIP.String(),
"Custom cipher: " + o.Cipher,
} }
return strings.Join(settingsList, "\n|--") return strings.Join(settingsList, "\n|--")
} }