Using struct for VPN connection settings

This commit is contained in:
Quentin McGaw (desktop)
2020-02-16 19:50:21 +00:00
parent f6b91bd74f
commit ce11745f6f
6 changed files with 63 additions and 40 deletions

View File

@@ -115,7 +115,9 @@ func main() {
e.FatalOnError(err)
}
VPNIPs, port, err := piaConf.BuildConf(allSettings.PIA.Region, allSettings.OpenVPN.NetworkProtocol, allSettings.PIA.Encryption, uid, gid)
connections, err := piaConf.GetOpenVPNConnections(allSettings.PIA.Region, allSettings.OpenVPN.NetworkProtocol, allSettings.PIA.Encryption)
e.FatalOnError(err)
err = piaConf.BuildConf(connections, allSettings.PIA.Encryption, uid, gid)
e.FatalOnError(err)
defaultInterface, defaultGateway, defaultSubnet, err := firewallConf.GetDefaultRoute()
@@ -128,7 +130,7 @@ func main() {
e.FatalOnError(err)
err = firewallConf.CreateGeneralRules()
e.FatalOnError(err)
err = firewallConf.CreateVPNRules(constants.TUN, VPNIPs, defaultInterface, port, allSettings.OpenVPN.NetworkProtocol)
err = firewallConf.CreateVPNRules(constants.TUN, defaultInterface, connections)
e.FatalOnError(err)
err = firewallConf.CreateLocalSubnetsRules(defaultSubnet, allSettings.Firewall.AllowedSubnets, defaultInterface)
e.FatalOnError(err)

View File

@@ -18,8 +18,7 @@ type Configurator interface {
Clear() error
BlockAll() error
CreateGeneralRules() error
CreateVPNRules(dev models.VPNDevice, serverIPs []net.IP, defaultInterface string,
port uint16, protocol models.NetworkProtocol) error
CreateVPNRules(dev models.VPNDevice, defaultInterface string, connections []models.OpenVPNConnection) error
CreateLocalSubnetsRules(subnet net.IPNet, extraSubnets []net.IPNet, defaultInterface string) error
AddRoutesVia(subnets []net.IPNet, defaultGateway net.IP, defaultInterface string) error
GetDefaultRoute() (defaultInterface string, defaultGateway net.IP, defaultSubnet net.IPNet, err error)

View File

@@ -77,14 +77,13 @@ func (c *configurator) CreateGeneralRules() error {
})
}
func (c *configurator) CreateVPNRules(dev models.VPNDevice, serverIPs []net.IP,
defaultInterface string, port uint16, protocol models.NetworkProtocol) error {
for _, serverIP := range serverIPs {
func (c *configurator) CreateVPNRules(dev models.VPNDevice, defaultInterface string, connections []models.OpenVPNConnection) error {
for _, connection := range connections {
c.logger.Info("%s: allowing output traffic to VPN server %s through %s on port %s %d",
logPrefix, serverIP, defaultInterface, protocol, port)
logPrefix, connection.IP, defaultInterface, connection.Protocol, connection.Port)
if err := c.runIptablesInstruction(
fmt.Sprintf("-A OUTPUT -d %s -o %s -p %s -m %s --dport %d -j ACCEPT",
serverIP, defaultInterface, protocol, protocol, port)); err != nil {
connection.IP, defaultInterface, connection.Protocol, connection.Protocol, connection.Port)); err != nil {
return err
}
}

View File

@@ -0,0 +1,9 @@
package models
import "net"
type OpenVPNConnection struct {
IP net.IP
Port uint16
Protocol NetworkProtocol
}

View File

@@ -2,45 +2,59 @@ package pia
import (
"fmt"
"net"
"github.com/qdm12/golibs/files"
"github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models"
)
func (c *configurator) BuildConf(region models.PIARegion, protocol models.NetworkProtocol,
encryption models.PIAEncryption, uid, gid int) (IPs []net.IP, port uint16, err error) {
var X509CRL, certificate string // depends on encryption
var cipherAlgo, authAlgo string // depends on encryption
func (c *configurator) GetOpenVPNConnections(region models.PIARegion, protocol models.NetworkProtocol, encryption models.PIAEncryption) (connections []models.OpenVPNConnection, err error) {
subdomain, err := constants.PIAGeoToSubdomainMapping(region)
if err != nil {
return nil, err
}
IPs, err := c.lookupIP(subdomain + ".privateinternetaccess.com")
if err != nil {
return nil, err
}
var port uint16
switch protocol {
case constants.TCP:
switch encryption {
case constants.PIAEncryptionNormal:
port = 502
case constants.PIAEncryptionStrong:
port = 501
}
case constants.UDP:
switch encryption {
case constants.PIAEncryptionNormal:
port = 1198
case constants.PIAEncryptionStrong:
port = 1197
}
}
if port == 0 {
return nil, fmt.Errorf("combination of protocol %q and encryption %q does not yield any port number", protocol, encryption)
}
for _, IP := range IPs {
connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port})
}
return connections, nil
}
func (c *configurator) BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, uid, gid int) (err error) {
var X509CRL, certificate, cipherAlgo, authAlgo string
if encryption == constants.PIAEncryptionNormal {
cipherAlgo = "aes-128-cbc"
authAlgo = "sha1"
X509CRL = constants.PIAX509CRL_NORMAL
certificate = constants.PIACertificate_NORMAL
if protocol == constants.UDP {
port = 1198
} else {
port = 502
}
} else { // strong
} else { // strong encryption
cipherAlgo = "aes-256-cbc"
authAlgo = "sha256"
X509CRL = constants.PIAX509CRL_STRONG
certificate = constants.PIACertificate_STRONG
if protocol == constants.UDP {
port = 1197
} else {
port = 501
}
}
subdomain, err := constants.PIAGeoToSubdomainMapping(region)
if err != nil {
return nil, 0, err
}
IPs, err = c.lookupIP(subdomain + ".privateinternetaccess.com")
if err != nil {
return nil, 0, err
}
lines := []string{
"client",
@@ -63,12 +77,12 @@ func (c *configurator) BuildConf(region models.PIARegion, protocol models.Networ
// Modified variables
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
fmt.Sprintf("proto %s", string(protocol)),
fmt.Sprintf("proto %s", string(connections[0].Protocol)),
fmt.Sprintf("cipher %s", cipherAlgo),
fmt.Sprintf("auth %s", authAlgo),
}
for _, IP := range IPs {
lines = append(lines, fmt.Sprintf("remote %s %d", IP.String(), port))
for _, connection := range connections {
lines = append(lines, fmt.Sprintf("remote %s %d", connection.IP.String(), connection.Port))
}
lines = append(lines, []string{
"<crl-verify>",
@@ -85,6 +99,5 @@ func (c *configurator) BuildConf(region models.PIARegion, protocol models.Networ
"</ca>",
"",
}...)
err = c.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400))
return IPs, port, err
return c.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400))
}

View File

@@ -16,8 +16,9 @@ const logPrefix = "PIA configurator"
// Configurator contains methods to download, read and modify the openvpn configuration to connect as a client
type Configurator interface {
BuildConf(region models.PIARegion, protocol models.NetworkProtocol,
encryption models.PIAEncryption, uid, gid int) (IPs []net.IP, port uint16, err error)
GetOpenVPNConnections(region models.PIARegion, protocol models.NetworkProtocol,
encryption models.PIAEncryption) (connections []models.OpenVPNConnection, err error)
BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, uid, gid int) (err error)
GetPortForward() (port uint16, err error)
WritePortForward(filepath models.Filepath, port uint16) (err error)
AllowPortForwardFirewall(device models.VPNDevice, port uint16) (err error)