New PIA servers support (#227)

* Adapt storage: SyncServers write to file option, export FlushToFile
* CLI built-in updater for old and new PIA servers
* Update hardcoded IP addresses for PIA old and new servers
* Add PIA old to allServers struct and update timestamps
* Adapt code to work with new and old PIA servers
* Remove PIA subdomains (unneeded) from resolver tool
This commit is contained in:
Quentin McGaw
2020-08-28 08:17:04 -04:00
committed by GitHub
parent 99ba56f574
commit d463e4cb69
24 changed files with 518 additions and 174 deletions

View File

@@ -4,7 +4,7 @@
Mullvad, Windscribe, Surfshark Cyberghost, VyprVPN, NordVPN and PureVPN VPN servers, using Go, OpenVPN, Mullvad, Windscribe, Surfshark Cyberghost, VyprVPN, NordVPN and PureVPN VPN servers, using Go, OpenVPN,
iptables, DNS over TLS, ShadowSocks and Tinyproxy* iptables, DNS over TLS, ShadowSocks and Tinyproxy*
**ANNOUNCEMENT**: *[Video of the Git history of Gluetun](https://youtu.be/khipOYJtGJ0)* **ANNOUNCEMENT**: *Support for newer Private Internet Access servers*
<img height="250" src="https://raw.githubusercontent.com/qdm12/gluetun/master/title.svg?sanitize=true"> <img height="250" src="https://raw.githubusercontent.com/qdm12/gluetun/master/title.svg?sanitize=true">
@@ -23,7 +23,7 @@ iptables, DNS over TLS, ShadowSocks and Tinyproxy*
## Features ## Features
- Based on Alpine 3.12 for a small Docker image of 52MB - Based on Alpine 3.12 for a small Docker image of 52MB
- Supports **Private Internet Access**, **Mullvad**, **Windscribe**, **Surfshark**, **Cyberghost**, **Vyprvpn**, **NordVPN** and **PureVPN** servers - Supports **Private Internet Access** (new and old), **Mullvad**, **Windscribe**, **Surfshark**, **Cyberghost**, **Vyprvpn**, **NordVPN** and **PureVPN** servers
- Supports Openvpn only for now - Supports Openvpn only for now
- DNS over TLS baked in with service provider(s) of your choice - DNS over TLS baked in with service provider(s) of your choice
- DNS fine blocking of malicious/ads/surveillance hostnames and IP addresses, with live update every 24 hours - DNS fine blocking of malicious/ads/surveillance hostnames and IP addresses, with live update every 24 hours
@@ -91,7 +91,7 @@ Want more testing? ▶ [see the Wiki](https://github.com/qdm12/gluetun/wiki/Test
| Variable | Default | Choices | Description | | Variable | Default | Choices | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| 🏁 `VPNSP` | `private internet access` | `private internet access`, `mullvad`, `windscribe`, `surfshark`, `vyprvpn`, `nordvpn`, `purevpn` | VPN Service Provider | | 🏁 `VPNSP` | `private internet access` | `private internet access`, `private internet access old`, `mullvad`, `windscribe`, `surfshark`, `vyprvpn`, `nordvpn`, `purevpn` | VPN Service Provider |
| `IP_STATUS_FILE` | `/tmp/gluetun/ip` | Any filepath | Filepath to store the public IP address assigned | | `IP_STATUS_FILE` | `/tmp/gluetun/ip` | Any filepath | Filepath to store the public IP address assigned |
| `PROTOCOL` | `udp` | `udp` or `tcp` | Network protocol to use | | `PROTOCOL` | `udp` | `udp` or `tcp` | Network protocol to use |
| `OPENVPN_VERBOSITY` | `1` | `0` to `6` | Openvpn verbosity level | | `OPENVPN_VERBOSITY` | `1` | `0` to `6` | Openvpn verbosity level |
@@ -110,8 +110,8 @@ Want more testing? ▶ [see the Wiki](https://github.com/qdm12/gluetun/wiki/Test
| 🏁 `PASSWORD` | | | Your password | | 🏁 `PASSWORD` | | | Your password |
| `REGION` | | One of the [PIA regions](https://www.privateinternetaccess.com/pages/network/) | VPN server region | | `REGION` | | One of the [PIA regions](https://www.privateinternetaccess.com/pages/network/) | VPN server region |
| `PIA_ENCRYPTION` | `strong` | `normal`, `strong` | Encryption preset | | `PIA_ENCRYPTION` | `strong` | `normal`, `strong` | Encryption preset |
| `PORT_FORWARDING` | `off` | `on`, `off` | Enable port forwarding on the VPN server | | `PORT_FORWARDING` | `off` | `on`, `off` | Enable port forwarding on the VPN server **for old only** |
| `PORT_FORWARDING_STATUS_FILE` | `/tmp/gluetun/forwarded_port` | Any filepath | Filepath to store the forwarded port number | | `PORT_FORWARDING_STATUS_FILE` | `/tmp/gluetun/forwarded_port` | Any filepath | Filepath to store the forwarded port number **for old only** |
- Mullvad - Mullvad

View File

@@ -46,6 +46,8 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
err = cli.ClientKey(args[2:]) err = cli.ClientKey(args[2:])
case "openvpnconfig": case "openvpnconfig":
err = cli.OpenvpnConfig() err = cli.OpenvpnConfig()
case "update":
err = cli.Update(args[2:])
default: default:
err = fmt.Errorf("command %q is unknown", args[1]) err = fmt.Errorf("command %q is unknown", args[1])
} }
@@ -92,7 +94,8 @@ func _main(background context.Context, args []string) int { //nolint:gocognit,go
// TODO run this in a loop or in openvpn to reload from file without restarting // TODO run this in a loop or in openvpn to reload from file without restarting
storage := storage.New(logger) storage := storage.New(logger)
allServers, err := storage.SyncServers(constants.GetAllServers()) const updateServerFile = true
allServers, err := storage.SyncServers(constants.GetAllServers(), updateServerFile)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
return 1 return 1

View File

@@ -28,12 +28,6 @@ func _main(ctx context.Context) int {
var domain string var domain string
var servers []server var servers []server
switch *provider { switch *provider {
case "pia":
domain = "privateinternetaccess.com"
servers = piaServers()
case "pia-nextgen":
domain = "privacy.network"
servers = piaNextgenServers()
case "windscribe": case "windscribe":
domain = "windscribe.com" domain = "windscribe.com"
servers = windscribeServers() servers = windscribeServers()
@@ -212,108 +206,6 @@ type server struct {
city string // only for purevpn city string // only for purevpn
} }
func piaServers() []server {
return []server{
{subdomain: "au-melbourne", region: "AU Melbourne"},
{subdomain: "au-perth", region: "AU Perth"},
{subdomain: "au-sydney", region: "AU Sydney"},
{subdomain: "austria", region: "Austria"},
{subdomain: "belgium", region: "Belgium"},
{subdomain: "ca-montreal", region: "CA Montreal"},
{subdomain: "ca-toronto", region: "CA Toronto"},
{subdomain: "ca-vancouver", region: "CA Vancouver"},
{subdomain: "czech", region: "Czech Republic"},
{subdomain: "de-berlin", region: "DE Berlin"},
{subdomain: "de-frankfurt", region: "DE Frankfurt"},
{subdomain: "denmark", region: "Denmark"},
{subdomain: "fi", region: "Finlan"},
{subdomain: "france", region: "France"},
{subdomain: "hungary", region: "Hungary"},
{subdomain: "in", region: "India"},
{subdomain: "ireland", region: "Ireland"},
{subdomain: "israel", region: "Israel"},
{subdomain: "italy", region: "Italy"},
{subdomain: "japan", region: "Japan"},
{subdomain: "lu", region: "Luxembourg"},
{subdomain: "mexico", region: "Mexico"},
{subdomain: "nl", region: "Netherlands"},
{subdomain: "nz", region: "New Zealand"},
{subdomain: "no", region: "Norway"},
{subdomain: "poland", region: "Poland"},
{subdomain: "ro", region: "Romania"},
{subdomain: "sg", region: "Singapore"},
{subdomain: "spain", region: "Spain"},
{subdomain: "sweden", region: "Sweden"},
{subdomain: "swiss", region: "Switzerland"},
{subdomain: "ae", region: "UAE"},
{subdomain: "uk-london", region: "UK London"},
{subdomain: "uk-manchester", region: "UK Manchester"},
{subdomain: "uk-southampton", region: "UK Southampton"},
{subdomain: "us-atlanta", region: "US Atlanta"},
{subdomain: "us-california", region: "US California"},
{subdomain: "us-chicago", region: "US Chicago"},
{subdomain: "us-dallas", region: "US Dallas"},
{subdomain: "us-denver", region: "US Denver"},
{subdomain: "us-east", region: "US East"},
{subdomain: "us-florida", region: "US Florida"},
{subdomain: "us-houston", region: "US Houston"},
{subdomain: "us-lasvegas", region: "US Las Vegas"},
{subdomain: "us-newyorkcity", region: "US New York City"},
{subdomain: "us-seattle", region: "US Seattle"},
{subdomain: "us-siliconvalley", region: "US Silicon Valley"},
{subdomain: "us-washingtondc", region: "US Washington DC"},
{subdomain: "us-west", region: "US West"},
}
}
func piaNextgenServers() []server {
return []server{
{subdomain: "aus-melbourne", region: "AU Melbourne"},
{subdomain: "aus-perth", region: "AU Perth"},
{subdomain: "au-sydney", region: "AU Sydney"},
{subdomain: "austria", region: "Austria"},
{subdomain: "brussels", region: "Belgium"},
{subdomain: "ca-montreal", region: "CA Montreal"},
{subdomain: "ca-toronto", region: "CA Toronto"},
{subdomain: "czech", region: "Czech Republic"},
{subdomain: "de-berlin", region: "DE Berlin"},
{subdomain: "de-frankfurt", region: "DE Frankfurt"},
{subdomain: "denmark", region: "Denmark"},
{subdomain: "fi", region: "Finland"},
{subdomain: "france", region: "France"},
{subdomain: "hungary", region: "Hungary"},
{subdomain: "in", region: "India"},
{subdomain: "ireland", region: "Ireland"},
{subdomain: "israel", region: "Israel"},
{subdomain: "italy", region: "Italy"},
{subdomain: "japan", region: "Japan"},
{subdomain: "lu", region: "Luxembourg"},
{subdomain: "mexico", region: "Mexico"},
{subdomain: "nl-amsterdam", region: "Netherlands"},
{subdomain: "nz", region: "New Zealand"},
{subdomain: "no", region: "Norway"},
{subdomain: "poland", region: "Poland"},
{subdomain: "ro", region: "Romania"},
{subdomain: "sg", region: "Singapore"},
{subdomain: "spain", region: "Spain"},
{subdomain: "sweden", region: "Sweden"},
{subdomain: "swiss", region: "Switzerland"},
{subdomain: "ae", region: "UAE"},
{subdomain: "uk-london", region: "UK London"},
{subdomain: "uk-manchester", region: "UK Manchester"},
{subdomain: "us-atlanta", region: "US Atlanta"},
{subdomain: "us-california", region: "US California"},
{subdomain: "us-chicago", region: "US Chicago"},
{subdomain: "us-denver", region: "US Denver"},
{subdomain: "us-florida", region: "US Florida"},
{subdomain: "us-houston", region: "US Houston"},
{subdomain: "us-seattle", region: "US Seattle"},
{subdomain: "us-siliconvalley", region: "US Silicon Valley"},
{subdomain: "us-washingtondc", region: "US Washington DC"},
{subdomain: "us3", region: "US West"},
}
}
func windscribeServers() []server { func windscribeServers() []server {
return []server{ return []server{
{subdomain: "al", region: "Albania"}, {subdomain: "al", region: "Albania"},

View File

@@ -12,6 +12,7 @@ import (
"github.com/qdm12/gluetun/internal/provider" "github.com/qdm12/gluetun/internal/provider"
"github.com/qdm12/gluetun/internal/settings" "github.com/qdm12/gluetun/internal/settings"
"github.com/qdm12/gluetun/internal/storage" "github.com/qdm12/gluetun/internal/storage"
"github.com/qdm12/gluetun/internal/updater"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/files"
"github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/logging"
) )
@@ -56,7 +57,7 @@ func OpenvpnConfig() error {
if err != nil { if err != nil {
return err return err
} }
allServers, err := storage.New(logger).SyncServers(constants.GetAllServers()) allServers, err := storage.New(logger).SyncServers(constants.GetAllServers(), false)
if err != nil { if err != nil {
return err return err
} }
@@ -78,3 +79,28 @@ func OpenvpnConfig() error {
fmt.Println(strings.Join(lines, "\n")) fmt.Println(strings.Join(lines, "\n"))
return nil return nil
} }
func Update(args []string) error {
var options updater.Options
flagSet := flag.NewFlagSet("update", flag.ExitOnError)
flagSet.BoolVar(&options.File, "file", false, "Write results to /gluetun/servers.json (for end users)")
flagSet.BoolVar(&options.Stdout, "stdout", false, "Write results to console to modify the program (for maintainers)")
flagSet.BoolVar(&options.PIA, "pia", false, "Update Private Internet Access post-summer 2020 servers")
flagSet.BoolVar(&options.PIAold, "piaold", false, "Update Private Internet Access pre-summer 2020 servers")
if err := flagSet.Parse(args); err != nil {
return err
}
logger, err := logging.NewLogger(logging.ConsoleEncoding, logging.InfoLevel, -1)
if err != nil {
return err
}
if !options.File && !options.Stdout {
return fmt.Errorf("at least one of -file or -stdout must be specified")
}
storage := storage.New(logger)
updater := updater.New(storage)
if err := updater.UpdateServers(options); err != nil {
return err
}
return nil
}

View File

@@ -26,55 +26,170 @@ func PIAGeoChoices() (choices []string) {
func PIAServers() []models.PIAServer { func PIAServers() []models.PIAServer {
return []models.PIAServer{ return []models.PIAServer{
{Region: "AU Melbourne", IPs: []net.IP{{27, 50, 82, 131}, {27, 50, 82, 133}, {43, 250, 204, 81}, {43, 250, 204, 85}, {43, 250, 204, 87}, {43, 250, 204, 89}, {43, 250, 204, 95}, {43, 250, 204, 97}, {43, 250, 204, 99}, {43, 250, 204, 107}, {43, 250, 204, 109}, {43, 250, 204, 111}, {43, 250, 204, 113}, {43, 250, 204, 115}, {43, 250, 204, 117}, {43, 250, 204, 119}, {43, 250, 204, 123}, {43, 250, 204, 125}, {118, 127, 62, 227}, {221, 121, 139, 175}}}, {Region: "AU Melbourne", IPs: []net.IP{{27, 50, 74, 184}}},
{Region: "AU Perth", IPs: []net.IP{{43, 250, 205, 59}, {43, 250, 205, 91}, {43, 250, 205, 95}}}, {Region: "AU Perth", IPs: []net.IP{{43, 250, 205, 170}}},
{Region: "AU Sydney", IPs: []net.IP{{27, 50, 70, 87}, {27, 50, 77, 247}, {27, 50, 77, 251}, {27, 50, 81, 117}, {103, 13, 102, 113}, {103, 13, 102, 119}, {103, 13, 102, 121}, {103, 13, 102, 123}, {103, 13, 102, 127}, {118, 127, 60, 51}, {118, 127, 60, 53}, {118, 127, 60, 61}, {221, 121, 145, 133}, {221, 121, 145, 143}, {221, 121, 145, 145}, {221, 121, 145, 147}, {221, 121, 145, 159}, {221, 121, 146, 203}, {221, 121, 146, 217}, {221, 121, 152, 215}}}, {Region: "AU Sydney", IPs: []net.IP{{103, 2, 196, 167}}},
{Region: "Austria", IPs: []net.IP{{89, 187, 168, 6}, {156, 146, 60, 129}}}, {Region: "Algeria", IPs: []net.IP{{45, 133, 91, 210}}},
{Region: "Belgium", IPs: []net.IP{{77, 243, 191, 18}, {77, 243, 191, 19}, {77, 243, 191, 20}, {77, 243, 191, 21}, {77, 243, 191, 22}, {77, 243, 191, 23}, {77, 243, 191, 26}, {77, 243, 191, 27}, {185, 104, 186, 26}, {185, 232, 21, 26}, {185, 232, 21, 27}, {185, 232, 21, 28}, {185, 232, 21, 29}}}, {Region: "Andorra", IPs: []net.IP{{45, 139, 49, 241}}},
{Region: "CA Montreal", IPs: []net.IP{{199, 229, 249, 167}, {199, 229, 249, 177}, {199, 229, 249, 188}, {199, 229, 249, 190}, {199, 229, 249, 194}, {199, 229, 249, 196}}}, {Region: "Argentina", IPs: []net.IP{{190, 106, 134, 82}}},
{Region: "CA Toronto", IPs: []net.IP{{172, 98, 67, 43}, {172, 98, 67, 44}, {172, 98, 67, 52}, {172, 98, 67, 80}, {172, 98, 67, 88}, {172, 98, 67, 91}, {172, 98, 67, 143}}}, {Region: "Armenia", IPs: []net.IP{{45, 139, 50, 232}}},
{Region: "CA Vancouver", IPs: []net.IP{{107, 181, 189, 72}, {107, 181, 189, 73}, {107, 181, 189, 75}, {107, 181, 189, 76}, {107, 181, 189, 83}, {107, 181, 189, 84}, {107, 181, 189, 86}, {107, 181, 189, 87}, {172, 83, 40, 18}, {172, 83, 40, 19}, {172, 83, 40, 24}, {172, 83, 40, 26}, {172, 83, 40, 99}, {172, 83, 40, 100}, {172, 83, 40, 101}, {172, 83, 40, 104}, {172, 83, 40, 105}, {172, 83, 40, 107}, {172, 83, 40, 110}, {172, 83, 40, 113}}}, {Region: "Austria", IPs: []net.IP{{156, 146, 60, 14}}},
{Region: "Czech Republic", IPs: []net.IP{{212, 102, 39, 1}}}, {Region: "Bahamas", IPs: []net.IP{{45, 132, 143, 206}}},
{Region: "DE Berlin", IPs: []net.IP{{185, 230, 127, 226}, {185, 230, 127, 227}, {185, 230, 127, 229}, {185, 230, 127, 230}, {185, 230, 127, 231}, {185, 230, 127, 235}, {185, 230, 127, 238}, {185, 230, 127, 239}, {185, 230, 127, 241}, {185, 230, 127, 242}, {193, 176, 86, 125}, {193, 176, 86, 134}, {193, 176, 86, 138}, {193, 176, 86, 142}, {193, 176, 86, 150}, {193, 176, 86, 154}, {193, 176, 86, 158}, {193, 176, 86, 170}, {193, 176, 86, 178}, {194, 36, 108, 6}}}, {Region: "Bangladesh", IPs: []net.IP{{45, 132, 142, 210}}},
{Region: "DE Frankfurt", IPs: []net.IP{{195, 181, 170, 225}, {212, 102, 57, 138}}}, {Region: "Belgium", IPs: []net.IP{{5, 253, 205, 147}}},
{Region: "Denmark", IPs: []net.IP{{82, 102, 20, 163}, {82, 102, 20, 166}, {82, 102, 20, 167}, {82, 102, 20, 168}, {82, 102, 20, 169}, {82, 102, 20, 172}, {82, 102, 20, 173}, {82, 102, 20, 175}, {82, 102, 20, 177}, {82, 102, 20, 179}, {82, 102, 20, 182}, {82, 102, 20, 183}, {82, 102, 20, 230}, {188, 126, 94, 34}}}, {Region: "Bulgaria", IPs: []net.IP{{217, 138, 221, 130}}},
{Region: "Finlan", IPs: []net.IP{{188, 126, 89, 4}, {196, 244, 191, 2}, {196, 244, 191, 10}, {196, 244, 191, 18}, {196, 244, 191, 26}, {196, 244, 191, 34}, {196, 244, 191, 42}, {196, 244, 191, 50}, {196, 244, 191, 58}, {196, 244, 191, 66}, {196, 244, 191, 82}, {196, 244, 191, 90}, {196, 244, 191, 98}, {196, 244, 191, 114}, {196, 244, 191, 138}, {196, 244, 191, 146}}}, {Region: "CA Montreal", IPs: []net.IP{{172, 98, 71, 13}}},
{Region: "France", IPs: []net.IP{{156, 146, 63, 1}, {156, 146, 63, 65}}}, {Region: "CA Toronto", IPs: []net.IP{{66, 115, 142, 81}}},
{Region: "Hungary", IPs: []net.IP{{185, 128, 26, 18}, {185, 128, 26, 19}, {185, 128, 26, 20}, {185, 128, 26, 21}, {185, 128, 26, 22}, {185, 128, 26, 23}, {185, 128, 26, 24}}}, {Region: "Cambodia", IPs: []net.IP{{188, 215, 235, 103}}},
{Region: "India", IPs: []net.IP{{150, 242, 12, 155}, {150, 242, 12, 171}, {150, 242, 12, 187}}}, {Region: "China", IPs: []net.IP{{45, 132, 193, 234}}},
{Region: "Ireland", IPs: []net.IP{{23, 92, 127, 42}}}, {Region: "Cyprus", IPs: []net.IP{{45, 132, 137, 235}}},
{Region: "Israel", IPs: []net.IP{{31, 168, 172, 142}, {31, 168, 172, 145}, {31, 168, 172, 146}, {31, 168, 172, 147}}}, {Region: "Czech Republic", IPs: []net.IP{{212, 102, 39, 194}}},
{Region: "Italy", IPs: []net.IP{{156, 146, 41, 129}, {156, 146, 41, 193}}}, {Region: "DE Berlin", IPs: []net.IP{{89, 36, 76, 69}}},
{Region: "Japan", IPs: []net.IP{{103, 208, 220, 130}, {103, 208, 220, 131}, {103, 208, 220, 132}, {103, 208, 220, 133}, {103, 208, 220, 134}, {103, 208, 220, 135}, {103, 208, 220, 136}, {103, 208, 220, 137}, {103, 208, 220, 138}, {103, 208, 220, 139}, {103, 208, 220, 140}, {103, 208, 220, 141}, {103, 208, 220, 142}, {103, 208, 220, 143}}}, {Region: "DE Frankfurt", IPs: []net.IP{{185, 216, 33, 164}}},
{Region: "Luxembourg", IPs: []net.IP{{92, 223, 89, 133}, {92, 223, 89, 135}, {92, 223, 89, 136}, {92, 223, 89, 137}, {92, 223, 89, 138}, {92, 223, 89, 140}}}, {Region: "Denmark", IPs: []net.IP{{188, 126, 94, 124}}},
{Region: "Mexico", IPs: []net.IP{{169, 57, 0, 197}, {169, 57, 0, 200}, {169, 57, 0, 203}, {169, 57, 0, 205}, {169, 57, 0, 207}, {169, 57, 0, 210}, {169, 57, 0, 211}, {169, 57, 0, 212}, {169, 57, 0, 213}, {169, 57, 0, 217}, {169, 57, 0, 218}, {169, 57, 0, 221}, {169, 57, 0, 229}, {169, 57, 0, 230}, {169, 57, 0, 233}, {169, 57, 0, 236}, {169, 57, 0, 238}, {169, 57, 0, 243}, {169, 57, 0, 247}, {169, 57, 0, 248}}}, {Region: "Egypt", IPs: []net.IP{{188, 214, 122, 119}}},
{Region: "Netherlands", IPs: []net.IP{{89, 187, 174, 198}, {212, 102, 35, 101}, {212, 102, 35, 102}, {212, 102, 35, 103}, {212, 102, 35, 104}}}, {Region: "Finland", IPs: []net.IP{{188, 126, 89, 10}}},
{Region: "New Zealand", IPs: []net.IP{{43, 250, 207, 1}, {43, 250, 207, 3}}}, {Region: "France", IPs: []net.IP{{156, 146, 63, 210}}},
{Region: "Norway", IPs: []net.IP{{82, 102, 27, 50}, {82, 102, 27, 51}, {82, 102, 27, 53}, {82, 102, 27, 54}, {82, 102, 27, 55}, {82, 102, 27, 56}, {82, 102, 27, 57}, {82, 102, 27, 74}, {82, 102, 27, 75}, {82, 102, 27, 77}, {82, 102, 27, 114}, {82, 102, 27, 115}, {82, 102, 27, 116}, {82, 102, 27, 117}, {82, 102, 27, 118}, {82, 102, 27, 126}, {185, 206, 225, 222}, {185, 253, 97, 226}}}, {Region: "Georgia", IPs: []net.IP{{45, 132, 138, 236}}},
{Region: "Poland", IPs: []net.IP{{185, 244, 214, 195}, {185, 244, 214, 197}, {185, 244, 214, 198}, {185, 244, 214, 199}}}, {Region: "Greenland", IPs: []net.IP{{45, 131, 209, 233}}},
{Region: "Romania", IPs: []net.IP{{86, 105, 25, 66}, {86, 105, 25, 67}, {86, 105, 25, 68}, {86, 105, 25, 69}, {86, 105, 25, 70}, {86, 105, 25, 75}, {86, 105, 25, 76}, {86, 105, 25, 77}, {94, 176, 148, 34}, {94, 176, 148, 35}, {185, 45, 12, 126}, {185, 210, 218, 99}, {185, 210, 218, 101}, {185, 210, 218, 102}, {185, 210, 218, 103}, {185, 210, 218, 104}, {185, 210, 218, 105}}}, {Region: "Hungary", IPs: []net.IP{{217, 138, 192, 222}}},
{Region: "Singapore", IPs: []net.IP{{156, 146, 56, 193}, {156, 146, 57, 38}}}, {Region: "Iceland", IPs: []net.IP{{45, 133, 193, 85}}},
{Region: "Spain", IPs: []net.IP{{212, 102, 49, 185}}}, {Region: "India", IPs: []net.IP{{103, 26, 205, 251}}},
{Region: "Sweden", IPs: []net.IP{{45, 12, 220, 187}, {45, 12, 220, 208}, {45, 12, 220, 216}, {45, 12, 220, 238}, {45, 12, 220, 242}, {45, 12, 220, 245}, {45, 83, 91, 27}}}, {Region: "Iran", IPs: []net.IP{{45, 131, 4, 208}}},
{Region: "Switzerland", IPs: []net.IP{{156, 146, 62, 129}, {156, 146, 62, 193}, {212, 102, 36, 166}}}, {Region: "Ireland", IPs: []net.IP{{5, 157, 13, 41}}},
{Region: "UAE", IPs: []net.IP{{45, 9, 250, 46}, {45, 9, 250, 62}}}, {Region: "Isle of Man", IPs: []net.IP{{45, 132, 140, 213}}},
{Region: "UK London", IPs: []net.IP{{37, 235, 96, 198}, {37, 235, 97, 11}, {212, 102, 52, 1}, {212, 102, 52, 134}, {212, 102, 52, 199}, {212, 102, 53, 129}}}, {Region: "Israel", IPs: []net.IP{{185, 77, 248, 10}}},
{Region: "UK Manchester", IPs: []net.IP{{89, 238, 139, 4}, {89, 238, 139, 8}, {89, 238, 139, 9}, {89, 238, 139, 54}, {89, 238, 139, 58}}}, {Region: "Italy", IPs: []net.IP{{156, 146, 41, 77}}},
{Region: "UK Southampton", IPs: []net.IP{{31, 24, 226, 136}, {31, 24, 226, 145}, {31, 24, 226, 146}, {31, 24, 226, 189}, {31, 24, 226, 202}, {31, 24, 226, 203}, {31, 24, 226, 205}, {31, 24, 226, 206}, {31, 24, 226, 209}, {31, 24, 226, 222}, {31, 24, 226, 230}, {31, 24, 226, 232}, {31, 24, 226, 233}, {31, 24, 226, 235}, {31, 24, 226, 238}, {31, 24, 226, 239}, {31, 24, 226, 241}, {31, 24, 226, 243}, {31, 24, 226, 245}, {31, 24, 226, 254}}}, {Region: "Japan", IPs: []net.IP{{156, 146, 34, 164}}},
{Region: "US Atlanta", IPs: []net.IP{{66, 115, 169, 197}, {66, 115, 169, 199}, {66, 115, 169, 201}, {66, 115, 169, 203}, {66, 115, 169, 204}, {66, 115, 169, 209}, {66, 115, 169, 210}, {66, 115, 169, 212}, {66, 115, 169, 213}, {156, 146, 46, 1}, {156, 146, 46, 134}, {156, 146, 46, 198}, {156, 146, 47, 11}}}, {Region: "Kazakhstan", IPs: []net.IP{{45, 133, 88, 231}}},
{Region: "US California", IPs: []net.IP{{37, 235, 108, 144}, {37, 235, 108, 208}, {89, 187, 187, 129}, {89, 187, 187, 159}, {89, 187, 187, 162}}}, {Region: "Liechtenstein", IPs: []net.IP{{45, 139, 48, 236}}},
{Region: "US Chicago", IPs: []net.IP{{156, 146, 50, 1}, {156, 146, 50, 65}, {156, 146, 50, 134}, {156, 146, 50, 198}, {156, 146, 51, 11}, {212, 102, 58, 113}, {212, 102, 59, 54}, {212, 102, 59, 129}}}, {Region: "Luxembourg", IPs: []net.IP{{92, 223, 89, 80}}},
{Region: "US Dallas", IPs: []net.IP{{104, 18, 4, 18}, {104, 18, 5, 18}}}, {Region: "Macao", IPs: []net.IP{{45, 137, 197, 207}}},
{Region: "US Denver", IPs: []net.IP{{174, 128, 225, 106}, {174, 128, 225, 186}, {174, 128, 226, 10}, {174, 128, 227, 226}, {174, 128, 236, 106}, {174, 128, 242, 250}, {174, 128, 243, 98}, {174, 128, 243, 106}, {174, 128, 244, 74}, {174, 128, 245, 98}, {174, 128, 245, 106}, {174, 128, 246, 10}, {174, 128, 250, 18}, {199, 115, 97, 202}, {199, 115, 98, 234}, {199, 115, 99, 82}, {199, 115, 101, 186}, {199, 115, 102, 146}, {199, 115, 103, 2}, {199, 115, 103, 10}}}, {Region: "Malta", IPs: []net.IP{{45, 137, 198, 235}}},
{Region: "US East", IPs: []net.IP{{156, 146, 58, 198}, {156, 146, 58, 199}, {156, 146, 58, 201}, {156, 146, 58, 202}, {156, 146, 58, 203}, {156, 146, 58, 204}, {156, 146, 58, 205}, {156, 146, 58, 206}, {156, 146, 58, 207}, {156, 146, 58, 208}, {156, 146, 58, 209}, {193, 37, 253, 24}, {193, 37, 253, 102}, {193, 37, 253, 113}, {193, 37, 253, 141}, {193, 37, 253, 254}, {194, 59, 251, 13}, {194, 59, 251, 22}, {194, 59, 251, 49}, {194, 59, 251, 57}}}, {Region: "Mexico", IPs: []net.IP{{77, 81, 142, 5}}},
{Region: "US Florida", IPs: []net.IP{{156, 146, 42, 1}, {156, 146, 42, 65}, {156, 146, 42, 134}, {156, 146, 43, 11}, {156, 146, 43, 75}, {156, 146, 43, 121}, {156, 146, 43, 122}, {212, 102, 61, 19}, {212, 102, 61, 83}}}, {Region: "Moldova", IPs: []net.IP{{178, 175, 129, 40}}},
{Region: "US Houston", IPs: []net.IP{{74, 81, 88, 18}, {74, 81, 88, 26}, {74, 81, 88, 34}, {74, 81, 88, 42}, {74, 81, 88, 58}, {74, 81, 88, 66}, {74, 81, 88, 82}, {74, 81, 88, 90}, {74, 81, 88, 114}, {74, 81, 88, 122}, {205, 251, 148, 34}, {205, 251, 148, 42}, {205, 251, 148, 74}, {205, 251, 148, 90}, {205, 251, 148, 98}, {205, 251, 148, 162}, {205, 251, 150, 186}, {205, 251, 150, 202}, {205, 251, 150, 234}, {205, 251, 151, 42}}}, {Region: "Monaco", IPs: []net.IP{{45, 137, 199, 237}}},
{Region: "US Las Vegas", IPs: []net.IP{{162, 251, 236, 2}, {162, 251, 236, 3}, {162, 251, 236, 4}, {162, 251, 236, 5}, {162, 251, 236, 6}, {162, 251, 236, 7}, {162, 251, 236, 8}, {162, 251, 236, 9}, {199, 127, 56, 82}, {199, 127, 56, 83}, {199, 127, 56, 84}, {199, 127, 56, 87}, {199, 127, 56, 88}, {199, 127, 56, 89}, {199, 127, 56, 90}, {199, 127, 56, 91}, {199, 127, 56, 115}, {199, 127, 56, 117}, {199, 127, 56, 118}, {199, 127, 56, 119}}}, {Region: "Mongolia", IPs: []net.IP{{45, 139, 51, 211}}},
{Region: "US New York City", IPs: []net.IP{{107, 182, 230, 194}, {107, 182, 231, 24}, {107, 182, 231, 30}, {107, 182, 231, 34}, {107, 182, 231, 37}, {107, 182, 231, 38}, {107, 182, 231, 51}, {209, 95, 50, 12}, {209, 95, 50, 27}, {209, 95, 50, 50}, {209, 95, 50, 65}, {209, 95, 50, 66}, {209, 95, 50, 90}, {209, 95, 50, 93}, {209, 95, 50, 103}, {209, 95, 50, 104}, {209, 95, 50, 133}, {209, 95, 50, 144}, {209, 95, 50, 146}, {209, 95, 50, 162}}}, {Region: "Montenegro", IPs: []net.IP{{45, 131, 208, 206}}},
{Region: "US Seattle", IPs: []net.IP{{104, 200, 154, 11}, {104, 200, 154, 21}, {104, 200, 154, 22}, {104, 200, 154, 44}, {104, 200, 154, 47}, {104, 200, 154, 56}, {104, 200, 154, 59}, {104, 200, 154, 62}, {104, 200, 154, 66}, {104, 200, 154, 67}, {104, 200, 154, 70}, {104, 200, 154, 81}, {104, 200, 154, 84}, {104, 200, 154, 87}, {104, 200, 154, 90}, {104, 200, 154, 91}, {104, 200, 154, 96}, {104, 200, 154, 97}, {104, 200, 154, 98}, {104, 200, 154, 99}}}, {Region: "Morocco", IPs: []net.IP{{45, 131, 211, 234}}},
{Region: "US Silicon Valley", IPs: []net.IP{{199, 116, 118, 143}, {199, 116, 118, 149}, {199, 116, 118, 153}, {199, 116, 118, 154}, {199, 116, 118, 156}, {199, 116, 118, 168}, {199, 116, 118, 173}, {199, 116, 118, 174}, {199, 116, 118, 176}, {199, 116, 118, 181}, {199, 116, 118, 187}, {199, 116, 118, 209}, {199, 116, 118, 212}, {199, 116, 118, 215}, {199, 116, 118, 218}, {199, 116, 118, 221}, {199, 116, 118, 222}, {199, 116, 118, 239}, {199, 116, 118, 244}, {199, 116, 118, 250}}}, {Region: "Netherlands", IPs: []net.IP{{37, 235, 101, 73}}},
{Region: "US Washington DC", IPs: []net.IP{{70, 32, 0, 46}, {70, 32, 0, 50}, {70, 32, 0, 51}, {70, 32, 0, 52}, {70, 32, 0, 53}, {70, 32, 0, 57}, {70, 32, 0, 64}, {70, 32, 0, 65}, {70, 32, 0, 77}, {70, 32, 0, 101}, {70, 32, 0, 104}, {70, 32, 0, 114}, {70, 32, 0, 116}, {70, 32, 0, 118}, {70, 32, 0, 120}, {70, 32, 0, 130}, {70, 32, 0, 139}, {70, 32, 0, 167}, {70, 32, 0, 172}, {70, 32, 0, 173}}}, {Region: "New Zealand", IPs: []net.IP{{43, 250, 207, 70}}},
{Region: "US West", IPs: []net.IP{{104, 200, 151, 4}, {104, 200, 151, 11}, {104, 200, 151, 12}, {104, 200, 151, 13}, {104, 200, 151, 16}, {104, 200, 151, 20}, {104, 200, 151, 21}, {104, 200, 151, 31}, {104, 200, 151, 38}, {104, 200, 151, 39}, {104, 200, 151, 42}, {104, 200, 151, 52}, {104, 200, 151, 55}, {104, 200, 151, 61}, {104, 200, 151, 72}, {104, 200, 151, 73}, {104, 200, 151, 74}, {104, 200, 151, 78}, {104, 200, 151, 79}, {104, 200, 151, 83}}}, {Region: "Nigeria", IPs: []net.IP{{45, 137, 196, 208}}},
{Region: "Norway", IPs: []net.IP{{46, 246, 122, 82}}},
{Region: "Panama", IPs: []net.IP{{45, 131, 210, 206}}},
{Region: "Philippines", IPs: []net.IP{{188, 214, 125, 138}}},
{Region: "Poland", IPs: []net.IP{{217, 138, 209, 243}}},
{Region: "Qatar", IPs: []net.IP{{45, 131, 7, 209}}},
{Region: "Romania", IPs: []net.IP{{185, 45, 15, 22}}},
{Region: "Saudi Arabia", IPs: []net.IP{{45, 131, 6, 208}}},
{Region: "Serbia", IPs: []net.IP{{37, 120, 193, 248}}},
{Region: "Singapore", IPs: []net.IP{{156, 146, 57, 123}}},
{Region: "South Africa", IPs: []net.IP{{154, 16, 93, 35}}},
{Region: "Spain", IPs: []net.IP{{195, 181, 167, 42}}},
{Region: "Sri Lanka", IPs: []net.IP{{45, 132, 136, 232}}},
{Region: "Sweden", IPs: []net.IP{{46, 246, 3, 150}}},
{Region: "Switzerland", IPs: []net.IP{{212, 102, 37, 77}}},
{Region: "Taiwan", IPs: []net.IP{{188, 214, 106, 70}}},
{Region: "Turkey", IPs: []net.IP{{188, 213, 34, 87}}},
{Region: "UK London", IPs: []net.IP{{37, 235, 96, 26}}},
{Region: "UK Manchester", IPs: []net.IP{{193, 239, 84, 60}}},
{Region: "US Atlanta", IPs: []net.IP{{195, 181, 171, 76}}},
{Region: "US California", IPs: []net.IP{{37, 235, 108, 19}}},
{Region: "US Chicago", IPs: []net.IP{{154, 21, 28, 111}}},
{Region: "US Denver", IPs: []net.IP{{70, 39, 126, 143}}},
{Region: "US Florida", IPs: []net.IP{{37, 235, 98, 18}}},
{Region: "US Houston", IPs: []net.IP{{74, 81, 92, 147}}},
{Region: "US New Jersey", IPs: []net.IP{{37, 235, 103, 75}}},
{Region: "US New York", IPs: []net.IP{{156, 146, 55, 213}}},
{Region: "US Seattle", IPs: []net.IP{{156, 146, 48, 14}}},
{Region: "US Silicon Valley", IPs: []net.IP{{154, 21, 212, 228}}},
{Region: "US Texas", IPs: []net.IP{{154, 29, 131, 17}}},
{Region: "US Washington DC", IPs: []net.IP{{70, 32, 5, 172}}},
{Region: "US West", IPs: []net.IP{{193, 37, 254, 239}}},
{Region: "Ukraine", IPs: []net.IP{{62, 149, 20, 51}}},
{Region: "United Arab Emirates", IPs: []net.IP{{45, 131, 5, 233}}},
{Region: "Venezuela", IPs: []net.IP{{45, 133, 89, 212}}},
{Region: "Vietnam", IPs: []net.IP{{188, 214, 152, 67}}},
}
}
func PIAOldGeoChoices() (choices []string) {
servers := PIAOldServers()
choices = make([]string, len(servers))
for i := range servers {
choices[i] = servers[i].Region
}
return choices
}
func PIAOldServers() []models.PIAServer {
return []models.PIAServer{
{Region: "AU Melbourne", IPs: []net.IP{{43, 250, 204, 97}}},
{Region: "AU Perth", IPs: []net.IP{{43, 250, 205, 59}}},
{Region: "AU Sydney", IPs: []net.IP{{221, 121, 146, 203}}},
{Region: "Albania", IPs: []net.IP{{31, 171, 154, 130}}},
{Region: "Argentina", IPs: []net.IP{{190, 106, 134, 80}}},
{Region: "Austria", IPs: []net.IP{{185, 216, 34, 229}}},
{Region: "Belgium", IPs: []net.IP{{185, 232, 21, 29}}},
{Region: "Bosnia and Herzegovina", IPs: []net.IP{{185, 164, 35, 55}}},
{Region: "Bulgaria", IPs: []net.IP{{217, 138, 221, 82}}},
{Region: "CA Montreal", IPs: []net.IP{{199, 229, 249, 159}}},
{Region: "CA Ontario", IPs: []net.IP{{184, 75, 213, 218}}},
{Region: "CA Toronto", IPs: []net.IP{{172, 98, 67, 85}}},
{Region: "CA Vancouver", IPs: []net.IP{{172, 83, 40, 25}}},
{Region: "Czech Republic", IPs: []net.IP{{185, 242, 6, 27}}},
{Region: "DE Berlin", IPs: []net.IP{{193, 176, 86, 123}}},
{Region: "DE Frankfurt", IPs: []net.IP{{185, 220, 70, 147}}},
{Region: "Denmark", IPs: []net.IP{{82, 102, 20, 181}}},
{Region: "Estonia", IPs: []net.IP{{77, 247, 111, 98}}},
{Region: "Finland", IPs: []net.IP{{196, 244, 191, 146}}},
{Region: "France", IPs: []net.IP{{194, 187, 249, 47}}},
{Region: "Greece", IPs: []net.IP{{154, 57, 3, 91}}},
{Region: "Hungary", IPs: []net.IP{{185, 128, 26, 19}}},
{Region: "Iceland", IPs: []net.IP{{213, 167, 139, 66}}},
{Region: "India", IPs: []net.IP{{150, 242, 12, 155}}},
{Region: "Ireland", IPs: []net.IP{{23, 92, 127, 34}}},
{Region: "Israel", IPs: []net.IP{{31, 168, 172, 145}}},
{Region: "Italy", IPs: []net.IP{{82, 102, 21, 217}}},
{Region: "Japan", IPs: []net.IP{{156, 146, 34, 65}}},
{Region: "Latvia", IPs: []net.IP{{109, 248, 149, 2}}},
{Region: "Lithuania", IPs: []net.IP{{85, 206, 165, 160}}},
{Region: "Luxembourg", IPs: []net.IP{{92, 223, 89, 137}}},
{Region: "Moldova", IPs: []net.IP{{178, 17, 172, 242}}},
{Region: "Netherlands", IPs: []net.IP{{46, 166, 190, 227}}},
{Region: "New Zealand", IPs: []net.IP{{43, 250, 207, 3}}},
{Region: "North Macedonia", IPs: []net.IP{{185, 225, 28, 130}}},
{Region: "Norway", IPs: []net.IP{{82, 102, 27, 52}}},
{Region: "Poland", IPs: []net.IP{{185, 244, 214, 198}}},
{Region: "Portugal", IPs: []net.IP{{89, 26, 241, 102}}},
{Region: "Romania", IPs: []net.IP{{185, 210, 218, 98}}},
{Region: "Serbia", IPs: []net.IP{{37, 120, 193, 242}}},
{Region: "Singapore", IPs: []net.IP{{37, 120, 208, 82}}},
{Region: "Slovakia", IPs: []net.IP{{37, 120, 221, 82}}},
{Region: "South Africa", IPs: []net.IP{{102, 165, 20, 133}}},
{Region: "Spain", IPs: []net.IP{{185, 230, 124, 52}}},
{Region: "Sweden", IPs: []net.IP{{45, 12, 220, 170}}},
{Region: "Switzerland", IPs: []net.IP{{91, 132, 136, 45}}},
{Region: "Turkey", IPs: []net.IP{{185, 195, 79, 82}}},
{Region: "UAE", IPs: []net.IP{{45, 9, 250, 46}}},
{Region: "UK London", IPs: []net.IP{{89, 238, 154, 229}}},
{Region: "UK Manchester", IPs: []net.IP{{89, 238, 139, 9}}},
{Region: "UK Southampton", IPs: []net.IP{{31, 24, 226, 234}}},
{Region: "US Atlanta", IPs: []net.IP{{156, 146, 47, 11}}},
{Region: "US California", IPs: []net.IP{{91, 207, 175, 169}}},
{Region: "US Chicago", IPs: []net.IP{{212, 102, 58, 113}}},
{Region: "US Dallas", IPs: []net.IP{{156, 146, 52, 70}}},
{Region: "US Denver", IPs: []net.IP{{174, 128, 242, 250}}},
{Region: "US East", IPs: []net.IP{{193, 37, 253, 120}}},
{Region: "US Florida", IPs: []net.IP{{193, 37, 252, 126}}},
{Region: "US Houston", IPs: []net.IP{{205, 251, 150, 194}}},
{Region: "US Las Vegas", IPs: []net.IP{{199, 127, 56, 119}}},
{Region: "US New York City", IPs: []net.IP{{156, 146, 54, 53}}},
{Region: "US Seattle", IPs: []net.IP{{156, 146, 48, 65}}},
{Region: "US Silicon Valley", IPs: []net.IP{{199, 116, 118, 181}}},
{Region: "US Washington DC", IPs: []net.IP{{70, 32, 0, 75}}},
{Region: "US West", IPs: []net.IP{{104, 200, 151, 44}}},
{Region: "Ukraine", IPs: []net.IP{{62, 149, 20, 50}}},
} }
} }

View File

@@ -22,9 +22,14 @@ func GetAllServers() (allServers models.AllServers) {
}, },
Pia: models.PiaServers{ Pia: models.PiaServers{
Version: 1, Version: 1,
Timestamp: 1598236838, Timestamp: 1598485988,
Servers: PIAServers(), Servers: PIAServers(),
}, },
PiaOld: models.PiaServers{
Version: 1,
Timestamp: 1598485988,
Servers: PIAOldServers(),
},
Purevpn: models.PurevpnServers{ Purevpn: models.PurevpnServers{
Version: 1, Version: 1,
Timestamp: 1598236838, Timestamp: 1598236838,

View File

@@ -50,7 +50,8 @@ func Test_timestamps(t *testing.T) {
assert.Equal(t, "lZa+3P5DGuo9VXlsXsW5Jw", digestServersTimestamp(t, allServers.Cyberghost.Servers, allServers.Cyberghost.Timestamp)) assert.Equal(t, "lZa+3P5DGuo9VXlsXsW5Jw", digestServersTimestamp(t, allServers.Cyberghost.Servers, allServers.Cyberghost.Timestamp))
assert.Equal(t, "cK5eeY2KU+doigSAonCfVQ", digestServersTimestamp(t, allServers.Mullvad.Servers, allServers.Mullvad.Timestamp)) assert.Equal(t, "cK5eeY2KU+doigSAonCfVQ", digestServersTimestamp(t, allServers.Mullvad.Servers, allServers.Mullvad.Timestamp))
assert.Equal(t, "ZfMT6wXJJBAT0fOqx3TuOA", digestServersTimestamp(t, allServers.Nordvpn.Servers, allServers.Nordvpn.Timestamp)) assert.Equal(t, "ZfMT6wXJJBAT0fOqx3TuOA", digestServersTimestamp(t, allServers.Nordvpn.Servers, allServers.Nordvpn.Timestamp))
assert.Equal(t, "JGzrjRLM5MlWUjAkjpqKWw", digestServersTimestamp(t, allServers.Pia.Servers, allServers.Pia.Timestamp)) assert.Equal(t, "vNjr3aOwoql8lBAKDx8Ygw", digestServersTimestamp(t, allServers.Pia.Servers, allServers.Pia.Timestamp))
assert.Equal(t, "l3vaGSaIT4YOVGn3IaQkBg", digestServersTimestamp(t, allServers.PiaOld.Servers, allServers.PiaOld.Timestamp))
assert.Equal(t, "IW1gWNvYTSRDxpAv4kwmzg", digestServersTimestamp(t, allServers.Purevpn.Servers, allServers.Purevpn.Timestamp)) assert.Equal(t, "IW1gWNvYTSRDxpAv4kwmzg", digestServersTimestamp(t, allServers.Purevpn.Servers, allServers.Purevpn.Timestamp))
assert.Equal(t, "f934tXGfEVeNGT3TUdnpxw", digestServersTimestamp(t, allServers.Surfshark.Servers, allServers.Surfshark.Timestamp)) assert.Equal(t, "f934tXGfEVeNGT3TUdnpxw", digestServersTimestamp(t, allServers.Surfshark.Servers, allServers.Surfshark.Timestamp))
assert.Equal(t, "wwkmrCGEW06x7ze8+FO2hg", digestServersTimestamp(t, allServers.Vyprvpn.Servers, allServers.Vyprvpn.Timestamp)) assert.Equal(t, "wwkmrCGEW06x7ze8+FO2hg", digestServersTimestamp(t, allServers.Vyprvpn.Servers, allServers.Vyprvpn.Timestamp))

View File

@@ -7,6 +7,8 @@ import (
const ( const (
// PrivateInternetAccess is a VPN provider // PrivateInternetAccess is a VPN provider
PrivateInternetAccess models.VPNProvider = "private internet access" PrivateInternetAccess models.VPNProvider = "private internet access"
// PrivateInternetAccessOld is the pre summer 2020 PIA provider
PrivateInternetAccessOld models.VPNProvider = "private internet access old"
// Mullvad is a VPN provider // Mullvad is a VPN provider
Mullvad models.VPNProvider = "mullvad" Mullvad models.VPNProvider = "mullvad"
// Windscribe is a VPN provider // Windscribe is a VPN provider

View File

@@ -75,12 +75,17 @@ func (p *ProviderSettings) String() string {
number = fmt.Sprintf("%d", p.ServerSelection.Number) number = fmt.Sprintf("%d", p.ServerSelection.Number)
} }
switch strings.ToLower(string(p.Name)) { switch strings.ToLower(string(p.Name)) {
case "private internet access": case "private internet access old":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Region: "+p.ServerSelection.Region,
"Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset, "Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset,
"Port forwarding: "+p.PortForwarding.String(), "Port forwarding: "+p.PortForwarding.String(),
) )
case "private internet access":
settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region,
"Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset,
)
case "mullvad": case "mullvad":
settingsList = append(settingsList, settingsList = append(settingsList,
"Country: "+p.ServerSelection.Country, "Country: "+p.ServerSelection.Country,

View File

@@ -1,12 +1,28 @@
package models package models
import "net" import (
"fmt"
"net"
"strings"
)
func stringifyIPs(ips []net.IP) string {
ipStrings := make([]string, len(ips))
for i := range ips {
ipStrings[i] = fmt.Sprintf("{%s}", strings.ReplaceAll(ips[i].String(), ".", ", "))
}
return strings.Join(ipStrings, ", ")
}
type PIAServer struct { type PIAServer struct {
IPs []net.IP `json:"ips"` IPs []net.IP `json:"ips"`
Region string `json:"region"` Region string `json:"region"`
} }
func (p *PIAServer) String() string {
return fmt.Sprintf("{Region: %q, IPs: []net.IP{%s}}", p.Region, stringifyIPs(p.IPs))
}
type MullvadServer struct { type MullvadServer struct {
IPs []net.IP `json:"ips"` IPs []net.IP `json:"ips"`
Country string `json:"country"` Country string `json:"country"`

View File

@@ -5,6 +5,7 @@ type AllServers struct {
Cyberghost CyberghostServers `json:"cyberghost"` Cyberghost CyberghostServers `json:"cyberghost"`
Mullvad MullvadServers `json:"mullvad"` Mullvad MullvadServers `json:"mullvad"`
Nordvpn NordvpnServers `json:"nordvpn"` Nordvpn NordvpnServers `json:"nordvpn"`
PiaOld PiaServers `json:"piaOld"`
Pia PiaServers `json:"pia"` Pia PiaServers `json:"pia"`
Purevpn PurevpnServers `json:"purevpn"` Purevpn PurevpnServers `json:"purevpn"`
Surfshark SurfsharkServers `json:"surfshark"` Surfshark SurfsharkServers `json:"surfshark"`

View File

@@ -60,6 +60,7 @@ type Reader interface {
GetPortForwardingStatusFilepath() (filepath models.Filepath, err error) GetPortForwardingStatusFilepath() (filepath models.Filepath, err error)
GetPIAEncryptionPreset() (preset string, err error) GetPIAEncryptionPreset() (preset string, err error)
GetPIARegion() (region string, err error) GetPIARegion() (region string, err error)
GetPIAOldRegion() (region string, err error)
// Mullvad getters // Mullvad getters
GetMullvadCountry() (country string, err error) GetMullvadCountry() (country string, err error)
@@ -136,7 +137,7 @@ func NewReader(logger logging.Logger, fileManager files.FileManager) Reader {
// GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP // GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP
func (r *reader) GetVPNSP() (vpnServiceProvider models.VPNProvider, err error) { func (r *reader) GetVPNSP() (vpnServiceProvider models.VPNProvider, err error) {
s, err := r.envParams.GetValueIfInside("VPNSP", []string{"pia", "private internet access", "mullvad", "windscribe", "surfshark", "cyberghost", "vyprvpn", "nordvpn", "purevpn"}) s, err := r.envParams.GetValueIfInside("VPNSP", []string{"pia", "private internet access", "private internet access old", "mullvad", "windscribe", "surfshark", "cyberghost", "vyprvpn", "nordvpn", "purevpn"})
if s == "pia" { if s == "pia" {
s = "private internet access" s = "private internet access"
} }

View File

@@ -10,6 +10,7 @@ import (
// GetPortForwarding obtains if port forwarding on the VPN provider server // GetPortForwarding obtains if port forwarding on the VPN provider server
// side is enabled or not from the environment variable PORT_FORWARDING // side is enabled or not from the environment variable PORT_FORWARDING
// Only valid for older PIA servers for now
func (r *reader) GetPortForwarding() (activated bool, err error) { func (r *reader) GetPortForwarding() (activated bool, err error) {
s, err := r.envParams.GetEnv("PORT_FORWARDING", libparams.Default("off")) s, err := r.envParams.GetEnv("PORT_FORWARDING", libparams.Default("off"))
if err != nil { if err != nil {
@@ -61,3 +62,10 @@ func (r *reader) GetPIARegion() (region string, err error) {
choices := append(constants.PIAGeoChoices(), "") choices := append(constants.PIAGeoChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetValueIfInside("REGION", choices)
} }
// GetPIAOldRegion obtains the region for the PIA server from the
// environment variable REGION
func (r *reader) GetPIAOldRegion() (region string, err error) {
choices := append(constants.PIAOldGeoChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices)
}

View File

@@ -17,6 +17,8 @@ func New(provider models.VPNProvider, allServers models.AllServers) Provider {
switch provider { switch provider {
case constants.PrivateInternetAccess: case constants.PrivateInternetAccess:
return newPrivateInternetAccess(allServers.Pia.Servers) return newPrivateInternetAccess(allServers.Pia.Servers)
case constants.PrivateInternetAccessOld:
return newPrivateInternetAccess(allServers.PiaOld.Servers)
case constants.Mullvad: case constants.Mullvad:
return newMullvad(allServers.Mullvad.Servers) return newMullvad(allServers.Mullvad.Servers)
case constants.Windscribe: case constants.Windscribe:

View File

@@ -54,6 +54,8 @@ func GetOpenVPNSettings(paramsReader params.Reader, vpnProvider models.VPNProvid
switch vpnProvider { switch vpnProvider {
case constants.PrivateInternetAccess: case constants.PrivateInternetAccess:
settings.Provider, err = GetPIASettings(paramsReader) settings.Provider, err = GetPIASettings(paramsReader)
case constants.PrivateInternetAccessOld:
settings.Provider, err = GetPIAOldSettings(paramsReader)
case constants.Mullvad: case constants.Mullvad:
settings.Provider, err = GetMullvadSettings(paramsReader) settings.Provider, err = GetMullvadSettings(paramsReader)
case constants.Windscribe: case constants.Windscribe:

View File

@@ -29,6 +29,30 @@ func GetPIASettings(paramsReader params.Reader) (settings models.ProviderSetting
if err != nil { if err != nil {
return settings, err return settings, err
} }
return settings, nil
}
// GetPIAOldSettings obtains PIA settings for the older PIA servers (pre summer 2020) from environment variables using the params package.
func GetPIAOldSettings(paramsReader params.Reader) (settings models.ProviderSettings, err error) {
settings.Name = constants.PrivateInternetAccessOld
settings.ServerSelection.Protocol, err = paramsReader.GetNetworkProtocol()
if err != nil {
return settings, err
}
settings.ServerSelection.TargetIP, err = paramsReader.GetTargetIP()
if err != nil {
return settings, err
}
encryptionPreset, err := paramsReader.GetPIAEncryptionPreset()
if err != nil {
return settings, err
}
settings.ServerSelection.EncryptionPreset = encryptionPreset
settings.ExtraConfigOptions.EncryptionPreset = encryptionPreset
settings.ServerSelection.Region, err = paramsReader.GetPIAOldRegion()
if err != nil {
return settings, err
}
settings.PortForwarding.Enabled, err = paramsReader.GetPortForwarding() settings.PortForwarding.Enabled, err = paramsReader.GetPortForwarding()
if err != nil { if err != nil {
return settings, err return settings, err

View File

@@ -40,6 +40,12 @@ func (s *storage) mergeServers(hardcoded, persistent models.AllServers) (merged
getUnixTimeDifference(persistent.Pia.Timestamp, hardcoded.Pia.Timestamp)) getUnixTimeDifference(persistent.Pia.Timestamp, hardcoded.Pia.Timestamp))
merged.Pia = persistent.Pia merged.Pia = persistent.Pia
} }
merged.PiaOld = hardcoded.PiaOld
if persistent.PiaOld.Timestamp > hardcoded.PiaOld.Timestamp {
s.logger.Info("Using Private Internet Access older servers from file (%s more recent)",
getUnixTimeDifference(persistent.PiaOld.Timestamp, hardcoded.PiaOld.Timestamp))
merged.PiaOld = persistent.PiaOld
}
merged.Purevpn = hardcoded.Purevpn merged.Purevpn = hardcoded.Purevpn
if persistent.Purevpn.Timestamp > hardcoded.Purevpn.Timestamp { if persistent.Purevpn.Timestamp > hardcoded.Purevpn.Timestamp {
s.logger.Info("Using Purevpn servers from file (%s more recent)", s.logger.Info("Using Purevpn servers from file (%s more recent)",

View File

@@ -9,7 +9,8 @@ import (
) )
type Storage interface { type Storage interface {
SyncServers(hardcodedServers models.AllServers) (allServers models.AllServers, err error) SyncServers(hardcodedServers models.AllServers, write bool) (allServers models.AllServers, err error)
FlushToFile(servers models.AllServers) error
} }
type storage struct { type storage struct {

View File

@@ -18,13 +18,14 @@ func countServers(allServers models.AllServers) int {
len(allServers.Mullvad.Servers) + len(allServers.Mullvad.Servers) +
len(allServers.Nordvpn.Servers) + len(allServers.Nordvpn.Servers) +
len(allServers.Pia.Servers) + len(allServers.Pia.Servers) +
len(allServers.PiaOld.Servers) +
len(allServers.Purevpn.Servers) + len(allServers.Purevpn.Servers) +
len(allServers.Surfshark.Servers) + len(allServers.Surfshark.Servers) +
len(allServers.Vyprvpn.Servers) + len(allServers.Vyprvpn.Servers) +
len(allServers.Windscribe.Servers) len(allServers.Windscribe.Servers)
} }
func (s *storage) SyncServers(hardcodedServers models.AllServers) (allServers models.AllServers, err error) { func (s *storage) SyncServers(hardcodedServers models.AllServers, write bool) (allServers models.AllServers, err error) {
// Eventually read file // Eventually read file
var serversOnFile models.AllServers var serversOnFile models.AllServers
_, err = s.osStat(jsonFilepath) _, err = s.osStat(jsonFilepath)
@@ -43,10 +44,10 @@ func (s *storage) SyncServers(hardcodedServers models.AllServers) (allServers mo
allServers = s.mergeServers(hardcodedServers, serversOnFile) allServers = s.mergeServers(hardcodedServers, serversOnFile)
// Eventually write file // Eventually write file
if reflect.DeepEqual(serversOnFile, allServers) { if !write || reflect.DeepEqual(serversOnFile, allServers) {
return allServers, nil return allServers, nil
} }
return allServers, s.flushToFile(allServers) return allServers, s.FlushToFile(allServers)
} }
func (s *storage) readFromFile() (servers models.AllServers, err error) { func (s *storage) readFromFile() (servers models.AllServers, err error) {
@@ -60,7 +61,7 @@ func (s *storage) readFromFile() (servers models.AllServers, err error) {
return servers, nil return servers, nil
} }
func (s *storage) flushToFile(servers models.AllServers) error { func (s *storage) FlushToFile(servers models.AllServers) error {
bytes, err := json.MarshalIndent(servers, "", " ") bytes, err := json.MarshalIndent(servers, "", " ")
if err != nil { if err != nil {
return fmt.Errorf("cannot write to file: %w", err) return fmt.Errorf("cannot write to file: %w", err)

View File

@@ -0,0 +1,28 @@
package updater
import (
"net"
"strings"
)
func extractRemoteLinesFromOpenvpn(content []byte) (remoteLines []string) {
lines := strings.Split(string(content), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "remote ") {
remoteLines = append(remoteLines, line)
}
}
return remoteLines
}
func extractIPsFromRemoteLines(remoteLines []string) (ips []net.IP) {
for _, remoteLine := range remoteLines {
fields := strings.Fields(remoteLine)
ip := net.ParseIP(fields[1])
if ip == nil { // not an IP address
continue
}
ips = append(ips, ip)
}
return ips
}

View File

@@ -0,0 +1,8 @@
package updater
type Options struct {
PIA bool
PIAold bool
File bool // update JSON file (user side)
Stdout bool // update constants file (maintainer side)
}

66
internal/updater/pia.go Normal file
View File

@@ -0,0 +1,66 @@
package updater
import (
"fmt"
"sort"
"strings"
"github.com/qdm12/gluetun/internal/models"
)
func findPIAServers(new bool) (servers []models.PIAServer, err error) {
zipURL := "https://www.privateinternetaccess.com/openvpn/openvpn-ip.zip"
if new {
zipURL = "https://www.privateinternetaccess.com/openvpn/openvpn-ip-nextgen.zip"
}
return findPIAServersFromURL(zipURL)
}
func findPIAServersFromURL(zipURL string) (servers []models.PIAServer, err error) {
contents, err := fetchAndExtractFiles(zipURL)
if err != nil {
return nil, err
}
for fileName, content := range contents {
remoteLines := extractRemoteLinesFromOpenvpn(content)
if len(remoteLines) == 0 {
return nil, fmt.Errorf("cannot find any remote lines in %s", fileName)
}
IPs := extractIPsFromRemoteLines(remoteLines)
if len(IPs) == 0 {
return nil, fmt.Errorf("cannot find any IP addresses in %s", fileName)
}
region := strings.TrimSuffix(fileName, ".ovpn")
server := models.PIAServer{
Region: region,
IPs: IPs,
}
servers = append(servers, server)
}
sort.Slice(servers, func(i, j int) bool {
return servers[i].Region < servers[j].Region
})
return servers, nil
}
func stringifyPIAServers(servers []models.PIAServer) (s string) {
s = "func PIAServers() []models.PIAServer {\n"
s += " return []models.PIAServer{\n"
for _, server := range servers {
s += " " + server.String() + ",\n"
}
s += " }\n"
s += "}"
return s
}
func stringifyPIAOldServers(servers []models.PIAServer) (s string) {
s = "func PIAOldServers() []models.PIAServer {\n"
s += " return []models.PIAServer{\n"
for _, server := range servers {
s += " " + server.String() + ",\n"
}
s += " }\n"
s += "}"
return s
}

View File

@@ -0,0 +1,69 @@
package updater
import (
"fmt"
"time"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/storage"
)
type Updater interface {
UpdateServers(options Options) error
}
type updater struct {
storage storage.Storage
timeNow func() time.Time
println func(s string)
}
func New(storage storage.Storage) Updater {
return &updater{
storage: storage,
timeNow: time.Now,
println: func(s string) { fmt.Println(s) },
}
}
func (u *updater) UpdateServers(options Options) error {
const writeSync = false
allServers, err := u.storage.SyncServers(constants.GetAllServers(), writeSync)
if err != nil {
return fmt.Errorf("cannot update servers: %w", err)
}
if options.PIA {
const newServers = true
servers, err := findPIAServers(newServers)
if err != nil {
return fmt.Errorf("cannot update PIA servers: %w", err)
}
if options.Stdout {
u.println(stringifyPIAServers(servers))
}
allServers.Pia.Timestamp = u.timeNow().Unix()
allServers.Pia.Servers = servers
}
if options.PIAold {
const newServers = false
servers, err := findPIAServers(newServers)
if err != nil {
return fmt.Errorf("cannot update PIA old servers: %w", err)
}
if options.Stdout {
u.println(stringifyPIAOldServers(servers))
}
allServers.PiaOld.Timestamp = u.timeNow().Unix()
allServers.PiaOld.Servers = servers
}
if options.File {
if err := u.storage.FlushToFile(allServers); err != nil {
return fmt.Errorf("cannot update servers: %w", err)
}
}
return nil
}

62
internal/updater/zip.go Normal file
View File

@@ -0,0 +1,62 @@
package updater
import (
"archive/zip"
"bytes"
"fmt"
"io/ioutil"
"net/http"
"path/filepath"
"strings"
"time"
"github.com/qdm12/golibs/network"
)
func fetchAndExtractFiles(urls ...string) (contents map[string][]byte, err error) {
client := network.NewClient(10 * time.Second)
contents = make(map[string][]byte)
for _, url := range urls {
zipBytes, status, err := client.GetContent(url)
if err != nil {
return nil, err
} else if status != http.StatusOK {
return nil, fmt.Errorf("Getting %s results in HTTP status code %d", url, status)
}
newContents, err := zipExtractAll(zipBytes)
if err != nil {
return nil, err
}
for fileName, content := range newContents {
contents[fileName] = content
}
}
return contents, nil
}
func zipExtractAll(zipBytes []byte) (contents map[string][]byte, err error) {
r, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
if err != nil {
return nil, err
}
contents = map[string][]byte{}
for _, zf := range r.File {
fileName := filepath.Base(zf.Name)
if !strings.HasSuffix(fileName, ".ovpn") {
continue
}
f, err := zf.Open()
if err != nil {
return nil, err
}
defer f.Close()
contents[fileName], err = ioutil.ReadAll(f)
if err != nil {
return nil, err
}
if err := f.Close(); err != nil {
return nil, err
}
}
return contents, nil
}