From 9b9ae6940499e816a5798fc160115a8f3ddd5947 Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Mon, 12 Oct 2020 20:21:26 +0000 Subject: [PATCH] Repurpose OPENVPN_TARGET_IP for #229 --- README.md | 2 +- internal/params/openvpn.go | 5 ++--- internal/provider/cyberghost.go | 16 +++++----------- internal/provider/mullvad.go | 34 ++++++++++++++------------------- internal/provider/nordvpn.go | 26 ++++++++++--------------- internal/provider/piav3.go | 26 ++++++++++--------------- internal/provider/piav4.go | 26 ++++++++++--------------- internal/provider/purevpn.go | 26 ++++++++++--------------- internal/provider/surfshark.go | 22 ++++++++++----------- internal/provider/vyprvpn.go | 26 ++++++++++--------------- internal/provider/windscribe.go | 26 ++++++++++--------------- 11 files changed, 92 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index eae9bdd4..e03010ee 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ docker run --rm --network=container:gluetun alpine:3.12 wget -qO- https://ipinfo | `PROTOCOL` | `udp` | `udp` or `tcp` | Network protocol to use | | `OPENVPN_VERBOSITY` | `1` | `0` to `6` | Openvpn verbosity level | | `OPENVPN_ROOT` | `no` | `yes` or `no` | Run OpenVPN as root | -| `OPENVPN_TARGET_IP` | | Valid IP address | Specify a target VPN server (or gateway) IP address to use | +| `OPENVPN_TARGET_IP` | | Valid IP address | Specify a target VPN IP address to use | | `OPENVPN_CIPHER` | | i.e. `aes-256-gcm` | Specify a custom cipher to use. It will also set `ncp-disable` if using AES GCM for PIA | | `OPENVPN_AUTH` | | i.e. `sha256` | Specify a custom auth algorithm to use | | `OPENVPN_IPV6` | `off` | `on`, `off` | Enable tunneling of IPv6 (only for Mullvad) | diff --git a/internal/params/openvpn.go b/internal/params/openvpn.go index 61e5403a..8271ec83 100644 --- a/internal/params/openvpn.go +++ b/internal/params/openvpn.go @@ -53,9 +53,8 @@ func (r *reader) GetOpenVPNRoot() (root bool, err error) { return r.envParams.GetYesNo("OPENVPN_ROOT", libparams.Default("no")) } -// GetTargetIP obtains the IP address to choose from the list of IP addresses -// available for a particular region, from the environment variable -// OPENVPN_TARGET_IP +// GetTargetIP obtains the IP address to override over the list of IP addresses filtered +// 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 { diff --git a/internal/provider/cyberghost.go b/internal/provider/cyberghost.go index c069f5bc..bbd3dd52 100644 --- a/internal/provider/cyberghost.go +++ b/internal/provider/cyberghost.go @@ -43,6 +43,10 @@ func (c *cyberghost) filterServers(region, group string) (servers []models.Cyber } func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: 443, Protocol: selection.Protocol}, nil + } + servers := c.filterServers(selection.Region, selection.Group) if len(servers) == 0 { return connection, fmt.Errorf("no server found for region %q and group %q", selection.Region, selection.Group) @@ -51,20 +55,10 @@ func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (con var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: 443, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: 443, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: 443, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, c.randSource), nil } diff --git a/internal/provider/mullvad.go b/internal/provider/mullvad.go index 5aa48a59..c23ed7cf 100644 --- a/internal/provider/mullvad.go +++ b/internal/provider/mullvad.go @@ -48,37 +48,31 @@ func (m *mullvad) filterServers(country, city, isp string) (servers []models.Mul } func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { + var defaultPort uint16 = 1194 + if selection.Protocol == constants.TCP { + defaultPort = 443 + } + port := defaultPort + if selection.CustomPort > 0 { + port = selection.CustomPort + } + + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + servers := m.filterServers(selection.Country, selection.City, selection.ISP) if len(servers) == 0 { return connection, fmt.Errorf("no server found for country %q, city %q and ISP %q", selection.Country, selection.City, selection.ISP) } - var defaultPort uint16 = 1194 - if selection.Protocol == constants.TCP { - defaultPort = 443 - } - var connections []models.OpenVPNConnection for _, server := range servers { - port := defaultPort - if selection.CustomPort > 0 { - port = selection.CustomPort - } for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP address %q not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, m.randSource), nil } diff --git a/internal/provider/nordvpn.go b/internal/provider/nordvpn.go index b44a64c3..332f9ad2 100644 --- a/internal/provider/nordvpn.go +++ b/internal/provider/nordvpn.go @@ -49,11 +49,6 @@ func (n *nordvpn) filterServers(region string, protocol models.NetworkProtocol, } func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl - servers := n.filterServers(selection.Region, selection.Protocol, selection.Number) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q, protocol %s and number %d", selection.Region, selection.Protocol, selection.Number) - } - var port uint16 switch { case selection.Protocol == constants.UDP: @@ -64,19 +59,18 @@ func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec return connection, fmt.Errorf("protocol %q is unknown", selection.Protocol) } - var connections []models.OpenVPNConnection - for _, server := range servers { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(server.IP) { - return models.OpenVPNConnection{IP: server.IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: server.IP, Port: port, Protocol: selection.Protocol}) - } + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) + servers := n.filterServers(selection.Region, selection.Protocol, selection.Number) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q, protocol %s and number %d", selection.Region, selection.Protocol, selection.Number) + } + + connections := make([]models.OpenVPNConnection, len(servers)) + for i := range servers { + connections = append(connections, models.OpenVPNConnection{IP: servers[i].IP, Port: port, Protocol: selection.Protocol}) } return pickRandomConnection(connections, n.randSource), nil diff --git a/internal/provider/piav3.go b/internal/provider/piav3.go index dff93681..84cf851c 100644 --- a/internal/provider/piav3.go +++ b/internal/provider/piav3.go @@ -31,11 +31,6 @@ func newPrivateInternetAccessV3(servers []models.PIAOldServer, timeNow timeNowFu } func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { - servers := filterPIAOldServers(p.servers, selection.Region) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q", selection.Region) - } - var port uint16 switch selection.Protocol { case constants.TCP: @@ -57,23 +52,22 @@ func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connecti 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 { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := filterPIAOldServers(p.servers, selection.Region) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q", selection.Region) + } + var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, p.randSource), nil } diff --git a/internal/provider/piav4.go b/internal/provider/piav4.go index 429158d8..bce9352f 100644 --- a/internal/provider/piav4.go +++ b/internal/provider/piav4.go @@ -38,11 +38,6 @@ func newPrivateInternetAccessV4(servers []models.PIAServer, timeNow timeNowFunc) } func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { - servers := filterPIAServers(p.servers, selection.Region) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q", selection.Region) - } - var port uint16 switch selection.Protocol { case constants.TCP: @@ -64,6 +59,15 @@ func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connecti 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 { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := filterPIAServers(p.servers, selection.Region) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q", selection.Region) + } + var connections []models.OpenVPNConnection for _, server := range servers { IPs := server.OpenvpnUDP.IPs @@ -71,20 +75,10 @@ func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connecti IPs = server.OpenvpnTCP.IPs } for _, IP := range IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, p.randSource), nil } diff --git a/internal/provider/purevpn.go b/internal/provider/purevpn.go index 544c0ef2..187cae2c 100644 --- a/internal/provider/purevpn.go +++ b/internal/provider/purevpn.go @@ -48,11 +48,6 @@ func (p *purevpn) filterServers(region, country, city string) (servers []models. } func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl - servers := p.filterServers(selection.Region, selection.Country, selection.City) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q, country %q and city %q", selection.Region, selection.Country, selection.City) - } - var port uint16 switch { case selection.Protocol == constants.UDP: @@ -63,23 +58,22 @@ func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (connec return connection, fmt.Errorf("protocol %q is unknown", selection.Protocol) } + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := p.filterServers(selection.Region, selection.Country, selection.City) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q, country %q and city %q", selection.Region, selection.Country, selection.City) + } + var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if IP.Equal(selection.TargetIP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP address %q not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, p.randSource), nil } diff --git a/internal/provider/surfshark.go b/internal/provider/surfshark.go index 072f767f..520aa8a4 100644 --- a/internal/provider/surfshark.go +++ b/internal/provider/surfshark.go @@ -40,11 +40,6 @@ func (s *surfshark) filterServers(region string) (servers []models.SurfsharkServ } func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl - servers := s.filterServers(selection.Region) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q", selection.Region) - } - var port uint16 switch { case selection.Protocol == constants.TCP: @@ -55,16 +50,19 @@ func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (conn return connection, fmt.Errorf("protocol %q is unknown", selection.Protocol) } + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := s.filterServers(selection.Region) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q", selection.Region) + } + var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } diff --git a/internal/provider/vyprvpn.go b/internal/provider/vyprvpn.go index de190b5f..d063d170 100644 --- a/internal/provider/vyprvpn.go +++ b/internal/provider/vyprvpn.go @@ -40,11 +40,6 @@ func (v *vyprvpn) filterServers(region string) (servers []models.VyprvpnServer) } func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { - servers := v.filterServers(selection.Region) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q", selection.Region) - } - var port uint16 switch { case selection.Protocol == constants.TCP: @@ -55,23 +50,22 @@ func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec return connection, fmt.Errorf("protocol %q is unknown", selection.Protocol) } + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := v.filterServers(selection.Region) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q", selection.Region) + } + var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, v.randSource), nil } diff --git a/internal/provider/windscribe.go b/internal/provider/windscribe.go index 3075e380..f366b0cf 100644 --- a/internal/provider/windscribe.go +++ b/internal/provider/windscribe.go @@ -40,11 +40,6 @@ func (w *windscribe) filterServers(region string) (servers []models.WindscribeSe } func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { - servers := w.filterServers(selection.Region) - if len(servers) == 0 { - return connection, fmt.Errorf("no server found for region %q", selection.Region) - } - var port uint16 switch { case selection.CustomPort > 0: @@ -57,23 +52,22 @@ func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (con return connection, fmt.Errorf("protocol %q is unknown", selection.Protocol) } + if selection.TargetIP != nil { + return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil + } + + servers := w.filterServers(selection.Region) + if len(servers) == 0 { + return connection, fmt.Errorf("no server found for region %q", selection.Region) + } + var connections []models.OpenVPNConnection for _, server := range servers { for _, IP := range server.IPs { - if selection.TargetIP != nil { - if selection.TargetIP.Equal(IP) { - return models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}, nil - } - } else { - connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) - } + connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: selection.Protocol}) } } - if selection.TargetIP != nil { - return connection, fmt.Errorf("target IP %s not found in IP addresses", selection.TargetIP) - } - return pickRandomConnection(connections, w.randSource), nil }