Support Mullvad over openvpn (#85)
Additional changes: - Allow empty value for PIA region - Most settings are lowercased - `OPENVPN_VERBOSITY` environment variable - openvpn also tunnels IPv6, and unbound supports ipv6 - auth kept only on disk, not in memory - readme reworked - CI script fixed and improved - Added v2 Docker tag - Shadowsocks log defaults to `off`
This commit is contained in:
667
internal/constants/mullvad.go
Normal file
667
internal/constants/mullvad.go
Normal file
@@ -0,0 +1,667 @@
|
||||
package constants
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
const (
|
||||
MullvadCertificate = "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"
|
||||
)
|
||||
|
||||
func MullvadCountryChoices() (choices []string) {
|
||||
uniqueChoices := map[string]struct{}{}
|
||||
for _, server := range mullvadServers() {
|
||||
uniqueChoices[string(server.Country)] = struct{}{}
|
||||
}
|
||||
for choice := range uniqueChoices {
|
||||
choices = append(choices, choice)
|
||||
}
|
||||
return choices
|
||||
}
|
||||
|
||||
func MullvadCityChoices() (choices []string) {
|
||||
uniqueChoices := map[string]struct{}{}
|
||||
for _, server := range mullvadServers() {
|
||||
uniqueChoices[string(server.City)] = struct{}{}
|
||||
}
|
||||
for choice := range uniqueChoices {
|
||||
choices = append(choices, choice)
|
||||
}
|
||||
return choices
|
||||
}
|
||||
|
||||
func MullvadProviderChoices() (choices []string) {
|
||||
uniqueChoices := map[string]struct{}{}
|
||||
for _, server := range mullvadServers() {
|
||||
uniqueChoices[string(server.Provider)] = struct{}{}
|
||||
}
|
||||
for choice := range uniqueChoices {
|
||||
choices = append(choices, choice)
|
||||
}
|
||||
return choices
|
||||
}
|
||||
|
||||
func MullvadServerFilter(country models.MullvadCountry, city models.MullvadCity, provider models.MullvadProvider) (servers []models.MullvadServer) {
|
||||
for _, server := range mullvadServers() {
|
||||
if len(country) == 0 {
|
||||
server.Country = ""
|
||||
}
|
||||
if len(city) == 0 {
|
||||
server.City = ""
|
||||
}
|
||||
if len(provider) == 0 {
|
||||
server.Provider = ""
|
||||
}
|
||||
if server.Country == country && server.City == city && server.Provider == provider {
|
||||
servers = append(servers, server)
|
||||
}
|
||||
}
|
||||
return servers
|
||||
}
|
||||
|
||||
func mullvadServers() []models.MullvadServer {
|
||||
return []models.MullvadServer{
|
||||
{
|
||||
Country: models.MullvadCountry("united arab emirates"),
|
||||
City: models.MullvadCity("dubai"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{45, 9, 249, 34}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("albania"),
|
||||
City: models.MullvadCity("tirana"),
|
||||
Provider: models.MullvadProvider("iregister"),
|
||||
IPs: []net.IP{{31, 171, 154, 210}},
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("austria"),
|
||||
City: models.MullvadCity("wien"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 155, 250}, {217, 64, 127, 138}, {217, 64, 127, 202}},
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("adelaide"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{116, 206, 231, 58}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("brisbane"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{43, 245, 160, 162}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("canberra"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{116, 206, 229, 98}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("melbourne"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{116, 206, 228, 202}, {116, 206, 228, 242}, {116, 206, 230, 98}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("perth"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{103, 77, 235, 66}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("sydney"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{43, 245, 162, 130}, {103, 77, 232, 130}, {103, 77, 232, 146}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("australia"),
|
||||
City: models.MullvadCity("sydney"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{217, 138, 204, 82}, {217, 138, 204, 98}, {217, 138, 204, 66}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("belgium"),
|
||||
City: models.MullvadCity("brussels"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 218, 146}, {37, 120, 218, 138}, {91, 207, 57, 50}, {37, 120, 143, 138}, {185, 104, 186, 202}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("bulgaria"),
|
||||
City: models.MullvadCity("sofia"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 94, 192, 42}, {185, 94, 192, 66}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("brazil"),
|
||||
City: models.MullvadCity("sao paulo"),
|
||||
Provider: models.MullvadProvider("qnax"),
|
||||
IPs: []net.IP{{191, 101, 62, 178}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("brazil"),
|
||||
City: models.MullvadCity("sao paulo"),
|
||||
Provider: models.MullvadProvider("heficed"),
|
||||
IPs: []net.IP{{177, 67, 80, 186}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("canada"),
|
||||
City: models.MullvadCity("montreal"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{139, 28, 218, 114}, {217, 138, 200, 194}, {217, 138, 200, 186}, {87, 101, 92, 146}, {176, 113, 74, 178}, {37, 120, 205, 114}, {87, 101, 92, 138}, {37, 120, 205, 122}, {217, 138, 200, 210}, {217, 138, 200, 202}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("canada"),
|
||||
City: models.MullvadCity("toronto"),
|
||||
Provider: models.MullvadProvider("amanah"),
|
||||
IPs: []net.IP{{184, 75, 214, 130}, {162, 219, 176, 250}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("canada"),
|
||||
City: models.MullvadCity("vancouver"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{172, 83, 40, 34}, {172, 83, 40, 38}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("canada"),
|
||||
City: models.MullvadCity("vancouver"),
|
||||
Provider: models.MullvadProvider("esecuredata"),
|
||||
IPs: []net.IP{{71, 19, 249, 81}, {176, 113, 74, 186}, {71, 19, 248, 240}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("switzerland"),
|
||||
City: models.MullvadCity("zurich"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{193, 32, 127, 82}, {193, 32, 127, 81}, {193, 32, 127, 83}, {193, 32, 127, 84}},
|
||||
Owned: true,
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("zwitzerland"),
|
||||
City: models.MullvadCity("zurich"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 212, 170, 50}, {185, 183, 104, 82}, {185, 9, 18, 98}, {82, 102, 24, 130}, {82, 102, 24, 186}, {185, 212, 170, 162}, {185, 9, 18, 114}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("switzerland"),
|
||||
City: models.MullvadCity("zurich"),
|
||||
Provider: models.MullvadProvider("privateLayer"),
|
||||
IPs: []net.IP{{179, 43, 128, 170}, {81, 17, 20, 34}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("czech republic"),
|
||||
City: models.MullvadCity("prague"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{217, 138, 199, 82}, {217, 138, 199, 74}},
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("germany"),
|
||||
City: models.MullvadCity("frankfurt"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{185, 213, 155, 132}, {185, 213, 155, 140}, {185, 213, 155, 136}, {185, 213, 155, 133}, {185, 213, 155, 144}, {185, 213, 155, 143}, {185, 213, 155, 138}, {185, 213, 155, 142}, {185, 213, 155, 139}, {185, 213, 155, 135}, {185, 213, 155, 145}, {185, 213, 155, 137}, {185, 213, 155, 131}, {185, 213, 155, 134}, {185, 213, 155, 141}},
|
||||
Owned: true,
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("germany"),
|
||||
City: models.MullvadCity("frankfurt"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{82, 102, 16, 90}, {185, 104, 184, 186}, {77, 243, 183, 202}},
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("denmark"),
|
||||
City: models.MullvadCity("copenhagen"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{141, 98, 254, 71}, {141, 98, 254, 72}},
|
||||
Owned: true,
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("denmark"),
|
||||
City: models.MullvadCity("copenhagen"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 206, 224, 114}, {185, 206, 224, 119}},
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("denmark"),
|
||||
City: models.MullvadCity("copenhagen"),
|
||||
Provider: models.MullvadProvider("blix"),
|
||||
IPs: []net.IP{{134, 90, 149, 138}},
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("denmark"),
|
||||
City: models.MullvadCity("copenhagen"),
|
||||
Provider: models.MullvadProvider("asergo"),
|
||||
IPs: []net.IP{{82, 103, 140, 213}},
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("spain"),
|
||||
City: models.MullvadCity("madrid"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{195, 206, 107, 146}, {45, 152, 183, 42}, {89, 238, 178, 74}, {45, 152, 183, 26}, {89, 238, 178, 34}},
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("finland"),
|
||||
City: models.MullvadCity("helsinki"),
|
||||
Provider: models.MullvadProvider("creanova"),
|
||||
IPs: []net.IP{{185, 204, 1, 174}, {185, 204, 1, 176}, {185, 212, 149, 201}, {185, 204, 1, 175}, {185, 204, 1, 173}, {185, 204, 1, 172}, {185, 204, 1, 171}},
|
||||
Owned: true,
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("france"),
|
||||
City: models.MullvadCity("paris"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{193, 32, 126, 83}, {193, 32, 126, 82}, {193, 32, 126, 81}, {193, 32, 126, 84}},
|
||||
Owned: true,
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("france"),
|
||||
City: models.MullvadCity("paris"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 189, 113, 82}, {185, 156, 173, 218}, {185, 128, 25, 162}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("uk"),
|
||||
City: models.MullvadCity("london"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{141, 98, 252, 133}, {141, 98, 252, 139}, {141, 98, 252, 137}, {141, 98, 252, 143}, {141, 98, 252, 142}, {141, 98, 252, 132}, {141, 98, 252, 134}, {141, 98, 252, 140}, {141, 98, 252, 141}, {141, 98, 252, 136}, {141, 98, 252, 144}, {141, 98, 252, 131}, {141, 98, 252, 135}, {141, 98, 252, 138}},
|
||||
Owned: true,
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("uk"),
|
||||
City: models.MullvadCity("london"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 200, 118, 105}, {185, 212, 168, 244}},
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("uk"),
|
||||
City: models.MullvadCity("manchester"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{89, 238, 130, 66}, {81, 92, 205, 10}, {89, 238, 130, 74}, {81, 92, 205, 18}, {81, 92, 205, 26}, {89, 238, 183, 244}, {89, 238, 132, 36}, {217, 151, 98, 68}, {37, 120, 159, 164}, {89, 238, 183, 60}},
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("greece"),
|
||||
City: models.MullvadCity("athens"),
|
||||
Provider: models.MullvadProvider("aweb"),
|
||||
IPs: []net.IP{{185, 226, 67, 168}},
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("hong kong"),
|
||||
City: models.MullvadCity("hong kong"),
|
||||
Provider: models.MullvadProvider("leaseweb"),
|
||||
IPs: []net.IP{{209, 58, 185, 53}, {209, 58, 184, 146}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("hungary"),
|
||||
City: models.MullvadCity("budapest"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 94, 190, 138}, {185, 189, 114, 10}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("ireland"),
|
||||
City: models.MullvadCity("dublin"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{217, 138, 222, 90}, {217, 138, 222, 82}},
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("israel"),
|
||||
City: models.MullvadCity("tel aviv"),
|
||||
Provider: models.MullvadProvider("hqserv"),
|
||||
IPs: []net.IP{{185, 191, 207, 210}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("italy"),
|
||||
City: models.MullvadCity("milan"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{217, 138, 197, 106}, {217, 64, 113, 180}, {217, 138, 197, 98}, {217, 138, 197, 114}, {217, 64, 113, 183}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("japan"),
|
||||
City: models.MullvadCity("tokyo"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 210, 138}, {193, 148, 16, 218}, {37, 120, 210, 146}, {185, 242, 4, 50}, {37, 120, 210, 122}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("luxembourg"),
|
||||
City: models.MullvadCity("luxembourg"),
|
||||
Provider: models.MullvadProvider("evoluso"),
|
||||
IPs: []net.IP{{92, 223, 89, 160}, {92, 223, 89, 182}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("latvia"),
|
||||
City: models.MullvadCity("riga"),
|
||||
Provider: models.MullvadProvider("makonix"),
|
||||
IPs: []net.IP{{31, 170, 22, 2}},
|
||||
DefaultPort: 1300,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("moldova"),
|
||||
City: models.MullvadCity("chisinau"),
|
||||
Provider: models.MullvadProvider("trabia"),
|
||||
IPs: []net.IP{{178, 175, 142, 194}},
|
||||
DefaultPort: 1197,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("netherlands"),
|
||||
City: models.MullvadCity("amsterdam"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{185, 65, 134, 139}, {185, 65, 134, 133}, {185, 65, 134, 148}, {185, 65, 134, 147}, {185, 65, 134, 141}, {185, 65, 134, 140}, {185, 65, 134, 145}, {185, 65, 134, 132}, {185, 65, 134, 146}, {185, 65, 134, 143}, {185, 65, 134, 134}, {185, 65, 134, 136}, {185, 65, 134, 135}, {185, 65, 134, 142}, {185, 65, 134, 144}},
|
||||
Owned: true,
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("norway"),
|
||||
City: models.MullvadCity("oslo"),
|
||||
Provider: models.MullvadProvider("blix"),
|
||||
IPs: []net.IP{{91, 90, 44, 13}, {91, 90, 44, 18}, {91, 90, 44, 12}, {91, 90, 44, 15}, {91, 90, 44, 16}, {91, 90, 44, 17}, {91, 90, 44, 14}, {91, 90, 44, 11}},
|
||||
Owned: true,
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("new zealand"),
|
||||
City: models.MullvadCity("auckland"),
|
||||
Provider: models.MullvadProvider("intergrid"),
|
||||
IPs: []net.IP{{103, 231, 91, 114}},
|
||||
DefaultPort: 1195,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("poland"),
|
||||
City: models.MullvadCity("warsaw"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 211, 202}, {37, 120, 156, 162}, {185, 244, 214, 210}, {37, 120, 211, 186}, {185, 244, 214, 215}, {37, 120, 211, 194}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("portugal"),
|
||||
City: models.MullvadCity("lisbon"),
|
||||
Provider: models.MullvadProvider("dotsi"),
|
||||
IPs: []net.IP{{5, 206, 231, 214}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("romania"),
|
||||
City: models.MullvadCity("bucharest"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{89, 40, 181, 146}, {185, 181, 100, 202}, {89, 40, 181, 82}, {185, 45, 13, 10}, {89, 40, 181, 210}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("serbia"),
|
||||
City: models.MullvadCity("belgrade"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{141, 98, 103, 50}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("serbia"),
|
||||
City: models.MullvadCity("nis"),
|
||||
Provider: models.MullvadProvider("ninet"),
|
||||
IPs: []net.IP{{176, 104, 107, 118}},
|
||||
DefaultPort: 1301,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("sweden"),
|
||||
City: models.MullvadCity("gothenburg"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{185, 213, 154, 139}, {185, 213, 154, 141}, {185, 213, 154, 140}, {185, 213, 154, 132}, {185, 213, 154, 135}, {185, 213, 154, 138}, {185, 213, 154, 133}, {185, 213, 154, 131}, {185, 213, 154, 134}, {185, 213, 154, 142}, {185, 213, 154, 137}},
|
||||
Owned: true,
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("sweden"),
|
||||
City: models.MullvadCity("helsingborg"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{185, 213, 152, 133}, {185, 213, 152, 132}, {185, 213, 152, 138}, {185, 213, 152, 131}, {185, 213, 152, 137}},
|
||||
Owned: true,
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("sweden"),
|
||||
City: models.MullvadCity("malmo"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{193, 138, 218, 138}, {45, 83, 220, 87}, {141, 98, 255, 94}, {141, 98, 255, 85}, {141, 98, 255, 87}, {141, 98, 255, 92}, {45, 83, 220, 84}, {141, 98, 255, 86}, {45, 83, 220, 81}, {193, 138, 218, 135}, {193, 138, 218, 131}, {193, 138, 218, 136}, {141, 98, 255, 88}, {141, 98, 255, 91}, {193, 138, 218, 133}, {45, 83, 220, 89}, {45, 83, 220, 88}, {141, 98, 255, 84}, {141, 98, 255, 89}, {193, 138, 218, 134}, {45, 83, 220, 86}, {141, 98, 255, 83}, {45, 83, 220, 85}, {141, 98, 255, 90}, {141, 98, 255, 93}, {193, 138, 218, 132}, {193, 138, 218, 137}, {45, 83, 220, 91}},
|
||||
Owned: true,
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("sweden"),
|
||||
City: models.MullvadCity("stockholm"),
|
||||
Provider: models.MullvadProvider("31173"),
|
||||
IPs: []net.IP{{185, 65, 135, 150}, {185, 65, 135, 153}, {185, 65, 135, 151}, {185, 65, 135, 149}, {185, 65, 135, 141}, {185, 65, 135, 144}, {185, 65, 135, 145}, {185, 65, 135, 140}, {185, 65, 135, 134}, {185, 65, 135, 139}, {185, 65, 135, 131}, {185, 65, 135, 152}, {185, 65, 135, 146}, {185, 65, 135, 138}, {185, 65, 135, 143}, {185, 65, 135, 135}, {185, 65, 135, 154}, {185, 65, 135, 136}, {185, 65, 135, 133}, {185, 65, 135, 132}},
|
||||
Owned: true,
|
||||
DefaultPort: 1302,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("singapore"),
|
||||
City: models.MullvadCity("singapore"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 208, 218}, {37, 120, 208, 234}, {37, 120, 208, 226}, {185, 128, 24, 50}},
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("singapore"),
|
||||
City: models.MullvadCity("singapore"),
|
||||
Provider: models.MullvadProvider("leaseweb"),
|
||||
IPs: []net.IP{{103, 254, 153, 82}},
|
||||
DefaultPort: 1196,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("atlanta"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{208, 84, 153, 142}, {107, 152, 108, 62}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("atlanta"),
|
||||
Provider: models.MullvadProvider("quadranet"),
|
||||
IPs: []net.IP{{104, 129, 24, 242}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("atlanta"),
|
||||
Provider: models.MullvadProvider("micfo"),
|
||||
IPs: []net.IP{{155, 254, 96, 2}, {155, 254, 96, 18}, {155, 254, 96, 34}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("chicago"),
|
||||
Provider: models.MullvadProvider("tzulo"),
|
||||
IPs: []net.IP{{68, 235, 43, 18}, {68, 235, 43, 26}, {68, 235, 43, 42}, {68, 235, 43, 50}, {68, 235, 43, 58}, {68, 235, 43, 66}, {68, 235, 43, 74}}, // 3 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("chicago"),
|
||||
Provider: models.MullvadProvider("quadranet"),
|
||||
IPs: []net.IP{}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("dallas"),
|
||||
Provider: models.MullvadProvider("quadranet"),
|
||||
IPs: []net.IP{{96, 44, 145, 18}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("dallas"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{104, 200, 142, 50}, {107, 152, 102, 106}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("denver"),
|
||||
Provider: models.MullvadProvider("tzulo"),
|
||||
IPs: []net.IP{{198, 54, 128, 74}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("los angeles"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{45, 152, 182, 66}, {45, 152, 182, 74}, {45, 83, 89, 162}, {185, 230, 126, 146}}, // 7 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("los angeles"),
|
||||
Provider: models.MullvadProvider("tzulo"),
|
||||
IPs: []net.IP{{198, 54, 129, 74}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("los angeles"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{104, 200, 152, 66}, {107, 181, 168, 130}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("los angeles"),
|
||||
Provider: models.MullvadProvider("choopa"),
|
||||
IPs: []net.IP{{104, 238, 143, 58}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("miami"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{37, 120, 215, 130}, {193, 37, 252, 138}, {193, 37, 252, 154}, {37, 120, 215, 138}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("miami"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{172, 98, 76, 114}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("miami"),
|
||||
Provider: models.MullvadProvider("micfo"),
|
||||
IPs: []net.IP{}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("new york"),
|
||||
Provider: models.MullvadProvider("m247"),
|
||||
IPs: []net.IP{{185, 232, 22, 66}, {185, 232, 22, 98}, {193, 148, 18, 250}, {185, 232, 22, 10}, {217, 138, 206, 10}, {193, 148, 18, 218}, {193, 148, 18, 226}, {193, 148, 18, 194}, {87, 101, 95, 98}, {87, 101, 95, 114}, {87, 101, 95, 122}, {212, 103, 48, 226}, {176, 113, 72, 226}, {217, 138, 198, 250}, {217, 138, 206, 58}}, // 5 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("new york"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{107, 182, 226, 206}, {107, 182, 226, 218}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("phoenix"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("phoenix"),
|
||||
Provider: models.MullvadProvider("micfo"),
|
||||
IPs: []net.IP{{192, 200, 24, 82}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("piscataway"),
|
||||
Provider: models.MullvadProvider("choopa"),
|
||||
IPs: []net.IP{{108, 61, 78, 138}, {108, 61, 48, 115}, {66, 55, 147, 59}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("seattle"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{104, 200, 129, 202}, {104, 200, 129, 150}, {104, 200, 129, 110}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("seattle"),
|
||||
Provider: models.MullvadProvider("micfo"),
|
||||
IPs: []net.IP{{104, 128, 136, 146}},
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("san francisco"),
|
||||
Provider: models.MullvadProvider("micfo"),
|
||||
IPs: []net.IP{{209, 209, 238, 34}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("salt lake city"),
|
||||
Provider: models.MullvadProvider("100tb"),
|
||||
IPs: []net.IP{{107, 182, 238, 229}, {107, 182, 235, 233}, {67, 212, 238, 236}, {67, 212, 238, 237}, {67, 212, 238, 239}, {107, 182, 239, 185}, {107, 182, 239, 170}}, // 2 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
{
|
||||
Country: models.MullvadCountry("usa"),
|
||||
City: models.MullvadCity("secaucus"),
|
||||
Provider: models.MullvadProvider("quadranet"),
|
||||
IPs: []net.IP{{23, 226, 131, 154}}, // 1 missing
|
||||
DefaultPort: 1194,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
package constants
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
@@ -21,12 +18,15 @@ const (
|
||||
PIACertificate_STRONG = "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"
|
||||
)
|
||||
|
||||
func PIAGeoChoices() []string {
|
||||
return []string{"AU Melbourne", "AU Perth", "AU Sydney", "Austria", "Belgium", "CA Montreal", "CA Toronto", "CA Vancouver", "Czech Republic", "DE Berlin", "DE Frankfurt", "Denmark", "Finland", "France", "Hong Kong", "Hungary", "India", "Ireland", "Israel", "Italy", "Japan", "Luxembourg", "Mexico", "Netherlands", "New Zealand", "Norway", "Poland", "Romania", "Singapore", "Spain", "Sweden", "Switzerland", "UAE", "UK London", "UK Manchester", "UK Southampton", "US Atlanta", "US California", "US Chicago", "US Denver", "US East", "US Florida", "US Houston", "US Las Vegas", "US New York City", "US Seattle", "US Silicon Valley", "US Texas", "US Washington DC", "US West"}
|
||||
func PIAGeoChoices() (regions []string) {
|
||||
for region := range PIAGeoToSubdomainMapping() {
|
||||
regions = append(regions, string(region))
|
||||
}
|
||||
return regions
|
||||
}
|
||||
|
||||
func PIAGeoToSubdomainMapping(region models.PIARegion) (subdomain string, err error) {
|
||||
mapping := map[models.PIARegion]string{
|
||||
func PIAGeoToSubdomainMapping() map[models.PIARegion]string {
|
||||
return map[models.PIARegion]string{
|
||||
models.PIARegion("AU Melbourne"): "au-melbourne",
|
||||
models.PIARegion("AU Perth"): "au-perth",
|
||||
models.PIARegion("AU Sydney"): "au-sydney",
|
||||
@@ -78,11 +78,6 @@ func PIAGeoToSubdomainMapping(region models.PIARegion) (subdomain string, err er
|
||||
models.PIARegion("US Washington DC"): "us-washingtondc",
|
||||
models.PIARegion("US West"): "us-west",
|
||||
}
|
||||
subdomain, ok := mapping[region]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("PIA region %q does not exist and can only be one of ", strings.Join(PIAGeoChoices(), ","))
|
||||
}
|
||||
return subdomain, nil
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -2,9 +2,9 @@ package constants
|
||||
|
||||
const (
|
||||
// Annoucement is a message annoucement
|
||||
Annoucement = "Total rewrite in Go with many new features"
|
||||
// AnnoucementExpiration is the expiration time of the annoucement in unix timestamp
|
||||
AnnoucementExpiration = 1582761600
|
||||
Annoucement = "Support for Mullvad"
|
||||
// AnnoucementExpiration is the expiration date of the annoucement in format yyyy-mm-dd
|
||||
AnnoucementExpiration = "2020-03-15"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
17
internal/constants/splash_test.go
Normal file
17
internal/constants/splash_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package constants
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_AnnoucementExpiration(t *testing.T) {
|
||||
t.Parallel()
|
||||
if len(AnnoucementExpiration) == 0 {
|
||||
return
|
||||
}
|
||||
_, err := time.Parse("2006-01-02", AnnoucementExpiration)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func generateUnboundConf(settings settings.DNS, client network.Client, logger lo
|
||||
"harden-algo-downgrade": "yes",
|
||||
// Network
|
||||
"do-ip4": "yes",
|
||||
"do-ip6": "no",
|
||||
"do-ip6": "yes",
|
||||
"interface": "127.0.0.1",
|
||||
"port": "53",
|
||||
// Other
|
||||
|
||||
@@ -43,7 +43,7 @@ server:
|
||||
cache-max-ttl: 9000
|
||||
cache-min-ttl: 3600
|
||||
do-ip4: yes
|
||||
do-ip6: no
|
||||
do-ip6: yes
|
||||
harden-algo-downgrade: yes
|
||||
harden-below-nxdomain: yes
|
||||
harden-referral-path: yes
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@ type (
|
||||
PIAEncryption string
|
||||
// PIARegion is used to define the list of regions available for PIA
|
||||
PIARegion string
|
||||
// MullvadCountry is used as the country for a Mullvad server
|
||||
MullvadCountry string
|
||||
// MullvadCity is used as the city for a Mullvad server
|
||||
MullvadCity string
|
||||
// MullvadProvider is used as the Internet service provider for a Mullvad server
|
||||
MullvadProvider string
|
||||
// URL is an HTTP(s) URL address
|
||||
URL string
|
||||
// Filepath is a local filesytem file path
|
||||
|
||||
12
internal/models/mullvad.go
Normal file
12
internal/models/mullvad.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package models
|
||||
|
||||
import "net"
|
||||
|
||||
type MullvadServer struct {
|
||||
Country MullvadCountry
|
||||
City MullvadCity
|
||||
Provider MullvadProvider
|
||||
Owned bool
|
||||
IPs []net.IP
|
||||
DefaultPort uint16
|
||||
}
|
||||
9
internal/models/openvpn.go
Normal file
9
internal/models/openvpn.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package models
|
||||
|
||||
import "net"
|
||||
|
||||
type OpenVPNConnection struct {
|
||||
IP net.IP
|
||||
Port uint16
|
||||
Protocol NetworkProtocol
|
||||
}
|
||||
74
internal/mullvad/conf.go
Normal file
74
internal/mullvad/conf.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package mullvad
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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) GetOpenVPNConnections(country models.MullvadCountry, city models.MullvadCity, provider models.MullvadProvider, protocol models.NetworkProtocol, customPort uint16) (connections []models.OpenVPNConnection, err error) {
|
||||
servers := constants.MullvadServerFilter(country, city, provider)
|
||||
if len(servers) == 0 {
|
||||
return nil, fmt.Errorf("no server found for country %q, city %q and ISP %q", country, city, provider)
|
||||
}
|
||||
for _, server := range servers {
|
||||
port := server.DefaultPort
|
||||
if customPort > 0 {
|
||||
port = customPort
|
||||
}
|
||||
for _, IP := range server.IPs {
|
||||
connections = append(connections, models.OpenVPNConnection{IP: IP, Port: port, Protocol: protocol})
|
||||
}
|
||||
}
|
||||
return connections, nil
|
||||
}
|
||||
|
||||
func (c *configurator) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int) (err error) {
|
||||
if len(connections) == 0 {
|
||||
return fmt.Errorf("at least one connection string is expected")
|
||||
}
|
||||
lines := []string{
|
||||
"client",
|
||||
"dev tun",
|
||||
"nobind",
|
||||
"persist-key",
|
||||
"persist-tun",
|
||||
"tls-client",
|
||||
"remote-cert-tls server",
|
||||
"ping 300",
|
||||
|
||||
// Mullvad specific
|
||||
// "sndbuf 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",
|
||||
"tun-ipv6",
|
||||
|
||||
// Added constant values
|
||||
"mute-replay-warnings",
|
||||
"auth-nocache",
|
||||
"user nonrootuser",
|
||||
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
|
||||
"auth-retry nointeract",
|
||||
"remote-random",
|
||||
|
||||
// Modified variables
|
||||
fmt.Sprintf("verb %d", verbosity),
|
||||
fmt.Sprintf("auth-user-pass %s", constants.OpenVPNAuthConf),
|
||||
fmt.Sprintf("proto %s", string(connections[0].Protocol)),
|
||||
}
|
||||
for _, connection := range connections {
|
||||
lines = append(lines, fmt.Sprintf("remote %s %d", connection.IP.String(), connection.Port))
|
||||
}
|
||||
lines = append(lines, []string{
|
||||
"<ca>",
|
||||
"-----BEGIN CERTIFICATE-----",
|
||||
constants.MullvadCertificate,
|
||||
"-----END CERTIFICATE-----",
|
||||
"</ca>",
|
||||
"",
|
||||
}...)
|
||||
return c.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400))
|
||||
}
|
||||
27
internal/mullvad/mullvad.go
Normal file
27
internal/mullvad/mullvad.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mullvad
|
||||
|
||||
import (
|
||||
"github.com/qdm12/golibs/files"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
"github.com/qdm12/golibs/network"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
const logPrefix = "Mullvad configurator"
|
||||
|
||||
// Configurator contains methods to download, read and modify the openvpn configuration to connect as a client
|
||||
type Configurator interface {
|
||||
GetOpenVPNConnections(country models.MullvadCountry, city models.MullvadCity, provider models.MullvadProvider, protocol models.NetworkProtocol, customPort uint16) (connections []models.OpenVPNConnection, err error)
|
||||
BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int) (err error)
|
||||
}
|
||||
|
||||
type configurator struct {
|
||||
client network.Client
|
||||
fileManager files.FileManager
|
||||
logger logging.Logger
|
||||
}
|
||||
|
||||
// NewConfigurator returns a new Configurator object
|
||||
func NewConfigurator(client network.Client, fileManager files.FileManager, logger logging.Logger) Configurator {
|
||||
return &configurator{client, fileManager, logger}
|
||||
}
|
||||
40
internal/params/mullvad.go
Normal file
40
internal/params/mullvad.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
libparams "github.com/qdm12/golibs/params"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/constants"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
// GetMullvadCountry obtains the country for the Mullvad server from the
|
||||
// environment variable COUNTRY
|
||||
func (p *paramsReader) GetMullvadCountry() (country models.MullvadCountry, err error) {
|
||||
choices := append(constants.MullvadCountryChoices(), "")
|
||||
s, err := p.envParams.GetValueIfInside("COUNTRY", choices)
|
||||
return models.MullvadCountry(strings.ToLower(s)), err
|
||||
}
|
||||
|
||||
// GetMullvadCity obtains the city for the Mullvad server from the
|
||||
// environment variable CITY
|
||||
func (p *paramsReader) GetMullvadCity() (country models.MullvadCity, err error) {
|
||||
choices := append(constants.MullvadCityChoices(), "")
|
||||
s, err := p.envParams.GetValueIfInside("CITY", choices)
|
||||
return models.MullvadCity(strings.ToLower(s)), err
|
||||
}
|
||||
|
||||
// GetMullvadISP obtains the ISP for the Mullvad server from the
|
||||
// environment variable ISP
|
||||
func (p *paramsReader) GetMullvadISP() (country models.MullvadProvider, err error) {
|
||||
choices := append(constants.MullvadProviderChoices(), "")
|
||||
s, err := p.envParams.GetValueIfInside("ISP", choices)
|
||||
return models.MullvadProvider(strings.ToLower(s)), err
|
||||
}
|
||||
|
||||
// GetMullvadPort obtains the port to reach the Mullvad server on from the
|
||||
// environment variable PORT
|
||||
func (p *paramsReader) GetMullvadPort() (port uint16, err error) {
|
||||
n, err := p.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
|
||||
return uint16(n), err
|
||||
}
|
||||
@@ -5,9 +5,37 @@ import (
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
// GetUser obtains the user to use to connect to the VPN servers
|
||||
func (p *paramsReader) GetUser() (s string, err error) {
|
||||
defer func() {
|
||||
unsetenvErr := p.unsetEnv("USER")
|
||||
if err == nil {
|
||||
err = unsetenvErr
|
||||
}
|
||||
}()
|
||||
return p.envParams.GetEnv("USER", libparams.CaseSensitiveValue(), libparams.Compulsory())
|
||||
}
|
||||
|
||||
// GetPassword obtains the password to use to connect to the VPN servers
|
||||
func (p *paramsReader) GetPassword() (s string, err error) {
|
||||
defer func() {
|
||||
unsetenvErr := p.unsetEnv("PASSWORD")
|
||||
if err == nil {
|
||||
err = unsetenvErr
|
||||
}
|
||||
}()
|
||||
return p.envParams.GetEnv("PASSWORD", libparams.CaseSensitiveValue(), libparams.Compulsory())
|
||||
}
|
||||
|
||||
// GetNetworkProtocol obtains the network protocol to use to connect to the
|
||||
// VPN servers from the environment variable PROTOCOL
|
||||
func (p *paramsReader) GetNetworkProtocol() (protocol models.NetworkProtocol, err error) {
|
||||
s, err := p.envParams.GetValueIfInside("PROTOCOL", []string{"tcp", "udp"}, libparams.Default("udp"))
|
||||
return models.NetworkProtocol(s), err
|
||||
}
|
||||
|
||||
// GetOpenVPNVerbosity obtains the verbosity level for verbosity between 0 and 6
|
||||
// from the environment variable OPENVPN_VERBOSITY
|
||||
func (p *paramsReader) GetOpenVPNVerbosity() (verbosity int, err error) {
|
||||
return p.envParams.GetEnvIntRange("OPENVPN_VERBOSITY", 0, 6, libparams.Default("1"))
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
|
||||
// ParamsReader contains methods to obtain parameters
|
||||
type ParamsReader interface {
|
||||
GetVPNSP() (vpnServiceProvider string, err error)
|
||||
|
||||
// DNS over TLS getters
|
||||
GetDNSOverTLS() (DNSOverTLS bool, err error)
|
||||
GetDNSOverTLSProviders() (providers []models.DNSProvider, err error)
|
||||
@@ -29,16 +31,23 @@ type ParamsReader interface {
|
||||
GetExtraSubnets() (extraSubnets []net.IPNet, err error)
|
||||
|
||||
// VPN getters
|
||||
GetNetworkProtocol() (protocol models.NetworkProtocol, err error)
|
||||
|
||||
// PIA getters
|
||||
GetUser() (s string, err error)
|
||||
GetPassword() (s string, err error)
|
||||
GetNetworkProtocol() (protocol models.NetworkProtocol, err error)
|
||||
GetOpenVPNVerbosity() (verbosity int, err error)
|
||||
|
||||
// PIA getters
|
||||
GetPortForwarding() (activated bool, err error)
|
||||
GetPortForwardingStatusFilepath() (filepath models.Filepath, err error)
|
||||
GetPIAEncryption() (models.PIAEncryption, error)
|
||||
GetPIARegion() (models.PIARegion, error)
|
||||
|
||||
// Mullvad getters
|
||||
GetMullvadCountry() (country models.MullvadCountry, err error)
|
||||
GetMullvadCity() (country models.MullvadCity, err error)
|
||||
GetMullvadISP() (country models.MullvadProvider, err error)
|
||||
GetMullvadPort() (port uint16, err error)
|
||||
|
||||
// Shadowsocks getters
|
||||
GetShadowSocks() (activated bool, err error)
|
||||
GetShadowSocksLog() (activated bool, err error)
|
||||
@@ -75,3 +84,9 @@ func NewParamsReader(logger logging.Logger) ParamsReader {
|
||||
unsetEnv: os.Unsetenv,
|
||||
}
|
||||
}
|
||||
|
||||
// GetVPNSP obtains the VPN service provider to use from the environment variable VPNSP
|
||||
func (p *paramsReader) GetVPNSP() (vpnServiceProvider string, err error) {
|
||||
s, err := p.envParams.GetValueIfInside("VPNSP", []string{"pia", "mullvad"})
|
||||
return s, err
|
||||
}
|
||||
|
||||
@@ -9,40 +9,6 @@ import (
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
)
|
||||
|
||||
// GetUser obtains the user to use to connect to the VPN servers
|
||||
func (p *paramsReader) GetUser() (s string, err error) {
|
||||
defer func() {
|
||||
unsetenvErr := p.unsetEnv("USER")
|
||||
if err == nil {
|
||||
err = unsetenvErr
|
||||
}
|
||||
}()
|
||||
s, err = p.envParams.GetEnv("USER")
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if len(s) == 0 {
|
||||
return s, fmt.Errorf("USER environment variable cannot be empty")
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// GetPassword obtains the password to use to connect to the VPN servers
|
||||
func (p *paramsReader) GetPassword() (s string, err error) {
|
||||
defer func() {
|
||||
unsetenvErr := p.unsetEnv("PASSWORD")
|
||||
if err == nil {
|
||||
err = unsetenvErr
|
||||
}
|
||||
}()
|
||||
s, err = p.envParams.GetEnv("PASSWORD")
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if len(s) == 0 {
|
||||
return s, fmt.Errorf("PASSWORD environment variable cannot be empty")
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// GetPortForwarding obtains if port forwarding on the VPN provider server
|
||||
// side is enabled or not from the environment variable PORT_FORWARDING
|
||||
func (p *paramsReader) GetPortForwarding() (activated bool, err error) {
|
||||
@@ -62,7 +28,7 @@ func (p *paramsReader) GetPortForwarding() (activated bool, err error) {
|
||||
// GetPortForwardingStatusFilepath obtains the port forwarding status file path
|
||||
// from the environment variable PORT_FORWARDING_STATUS_FILE
|
||||
func (p *paramsReader) GetPortForwardingStatusFilepath() (filepath models.Filepath, err error) {
|
||||
filepathStr, err := p.envParams.GetPath("PORT_FORWARDING_STATUS_FILE", libparams.Default("/forwarded_port"))
|
||||
filepathStr, err := p.envParams.GetPath("PORT_FORWARDING_STATUS_FILE", libparams.Default("/forwarded_port"), libparams.CaseSensitiveValue())
|
||||
return models.Filepath(filepathStr), err
|
||||
}
|
||||
|
||||
@@ -76,7 +42,7 @@ func (p *paramsReader) GetPIAEncryption() (models.PIAEncryption, error) {
|
||||
// GetPIARegion obtains the region for the PIA server from the
|
||||
// environment variable REGION
|
||||
func (p *paramsReader) GetPIARegion() (region models.PIARegion, err error) {
|
||||
choices := constants.PIAGeoChoices()
|
||||
choices := append(constants.PIAGeoChoices(), "")
|
||||
s, err := p.envParams.GetValueIfInside("REGION", choices)
|
||||
if len(s) == 0 { // Suggestion by @rorph https://github.com/rorph
|
||||
s = choices[rand.Int()%len(choices)]
|
||||
|
||||
@@ -36,5 +36,5 @@ func (p *paramsReader) GetShadowSocksPort() (port uint16, err error) {
|
||||
// SHADOWSOCKS_PASSWORD
|
||||
func (p *paramsReader) GetShadowSocksPassword() (password string, err error) {
|
||||
defer p.unsetEnv("SHADOWSOCKS_PASSWORD")
|
||||
return p.envParams.GetEnv("SHADOWSOCKS_PASSWORD")
|
||||
return p.envParams.GetEnv("SHADOWSOCKS_PASSWORD", libparams.CaseSensitiveValue())
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (p *paramsReader) GetTinyProxyUser() (user string, err error) {
|
||||
defer p.unsetEnv("PROXY_USER")
|
||||
defer p.unsetEnv("TINYPROXY_USER")
|
||||
// Retro-compatibility
|
||||
user, err = p.envParams.GetEnv("PROXY_USER")
|
||||
user, err = p.envParams.GetEnv("PROXY_USER", libparams.CaseSensitiveValue())
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func (p *paramsReader) GetTinyProxyUser() (user string, err error) {
|
||||
p.logger.Warn("You are using the old environment variable PROXY_USER, please consider changing it to TINYPROXY_USER")
|
||||
return user, nil
|
||||
}
|
||||
return p.envParams.GetEnv("TINYPROXY_USER")
|
||||
return p.envParams.GetEnv("TINYPROXY_USER", libparams.CaseSensitiveValue())
|
||||
}
|
||||
|
||||
// GetTinyProxyPassword obtains the TinyProxy server password from the environment variable
|
||||
@@ -82,7 +82,7 @@ func (p *paramsReader) GetTinyProxyPassword() (password string, err error) {
|
||||
defer p.unsetEnv("PROXY_PASSWORD")
|
||||
defer p.unsetEnv("TINYPROXY_PASSWORD")
|
||||
// Retro-compatibility
|
||||
password, err = p.envParams.GetEnv("PROXY_PASSWORD")
|
||||
password, err = p.envParams.GetEnv("PROXY_PASSWORD", libparams.CaseSensitiveValue())
|
||||
if err != nil {
|
||||
return password, err
|
||||
}
|
||||
@@ -90,5 +90,5 @@ func (p *paramsReader) GetTinyProxyPassword() (password string, err error) {
|
||||
p.logger.Warn("You are using the old environment variable PROXY_PASSWORD, please consider changing it to TINYPROXY_PASSWORD")
|
||||
return password, nil
|
||||
}
|
||||
return p.envParams.GetEnv("TINYPROXY_PASSWORD")
|
||||
return p.envParams.GetEnv("TINYPROXY_PASSWORD", libparams.CaseSensitiveValue())
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"github.com/qdm12/golibs/params"
|
||||
libparams "github.com/qdm12/golibs/params"
|
||||
)
|
||||
|
||||
func (p *paramsReader) GetVersion() string {
|
||||
version, _ := p.envParams.GetEnv("VERSION", params.Default("?"))
|
||||
version, _ := p.envParams.GetEnv("VERSION", libparams.Default("?"), libparams.CaseSensitiveValue())
|
||||
return version
|
||||
}
|
||||
|
||||
func (p *paramsReader) GetBuildDate() string {
|
||||
buildDate, _ := p.envParams.GetEnv("BUILD_DATE", params.Default("?"))
|
||||
buildDate, _ := p.envParams.GetEnv("BUILD_DATE", libparams.Default("?"), libparams.CaseSensitiveValue())
|
||||
return buildDate
|
||||
}
|
||||
|
||||
func (p *paramsReader) GetVcsRef() string {
|
||||
buildDate, _ := p.envParams.GetEnv("VCS_REF", params.Default("?"))
|
||||
buildDate, _ := p.envParams.GetEnv("VCS_REF", libparams.Default("?"), libparams.CaseSensitiveValue())
|
||||
return buildDate
|
||||
}
|
||||
|
||||
@@ -2,45 +2,70 @@ package pia
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"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) {
|
||||
geoMapping := constants.PIAGeoToSubdomainMapping()
|
||||
var subdomain string
|
||||
for r, s := range geoMapping {
|
||||
if strings.ToLower(string(region)) == strings.ToLower(string(r)) {
|
||||
subdomain = s
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(subdomain) == 0 {
|
||||
return nil, fmt.Errorf("region %q has no associated PIA subdomain", 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, Protocol: protocol})
|
||||
}
|
||||
return connections, nil
|
||||
}
|
||||
|
||||
func (c *configurator) BuildConf(connections []models.OpenVPNConnection, encryption models.PIAEncryption, verbosity, 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",
|
||||
@@ -50,25 +75,30 @@ func (c *configurator) BuildConf(region models.PIARegion, protocol models.Networ
|
||||
"persist-tun",
|
||||
"tls-client",
|
||||
"remote-cert-tls server",
|
||||
"compress",
|
||||
"verb 1", // TODO env variable
|
||||
"ping 300", // Ping every 5 minutes to prevent a timeout error
|
||||
|
||||
// PIA specific
|
||||
"reneg-sec 0",
|
||||
"compress", // allow PIA server to choose the compression to use
|
||||
|
||||
// Added constant values
|
||||
"tun-ipv6",
|
||||
"auth-nocache",
|
||||
"mute-replay-warnings",
|
||||
"user nonrootuser",
|
||||
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
|
||||
"auth-retry nointeract",
|
||||
"disable-occ",
|
||||
"remote-random",
|
||||
|
||||
// Modified variables
|
||||
fmt.Sprintf("verb %d", verbosity),
|
||||
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 +115,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))
|
||||
}
|
||||
|
||||
@@ -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, verbosity, 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)
|
||||
|
||||
57
internal/settings/mullvad.go
Normal file
57
internal/settings/mullvad.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
"github.com/qdm12/private-internet-access-docker/internal/params"
|
||||
)
|
||||
|
||||
// Mullvad contains the settings to connect to a Mullvad server
|
||||
type Mullvad struct {
|
||||
User string
|
||||
Country models.MullvadCountry
|
||||
City models.MullvadCity
|
||||
ISP models.MullvadProvider
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (m *Mullvad) String() string {
|
||||
|
||||
settingsList := []string{
|
||||
"Mullvad settings:",
|
||||
"User: [redacted]",
|
||||
"Country: " + string(m.Country),
|
||||
"City: " + string(m.City),
|
||||
"ISP: " + string(m.ISP),
|
||||
"Port: " + string(m.Port),
|
||||
}
|
||||
return strings.Join(settingsList, "\n |--")
|
||||
}
|
||||
|
||||
// GetMullvadSettings obtains Mullvad settings from environment variables using the params package.
|
||||
func GetMullvadSettings(params params.ParamsReader) (settings Mullvad, err error) {
|
||||
settings.User, err = params.GetUser()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
// Remove spaces in user ID to simplify user's life, thanks @JeordyR
|
||||
settings.User = strings.ReplaceAll(settings.User, " ", "")
|
||||
settings.Country, err = params.GetMullvadCountry()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.City, err = params.GetMullvadCity()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.ISP, err = params.GetMullvadISP()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.Port, err = params.GetMullvadPort()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/models"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
// OpenVPN contains settings to configure the OpenVPN client
|
||||
type OpenVPN struct {
|
||||
NetworkProtocol models.NetworkProtocol
|
||||
Verbosity int
|
||||
}
|
||||
|
||||
// GetOpenVPNSettings obtains the OpenVPN settings using the params functions
|
||||
@@ -18,6 +20,10 @@ func GetOpenVPNSettings(params params.ParamsReader) (settings OpenVPN, err error
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.Verbosity, err = params.GetOpenVPNVerbosity()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
@@ -25,6 +31,7 @@ func (o *OpenVPN) String() string {
|
||||
settingsList := []string{
|
||||
"OpenVPN settings:",
|
||||
"Network protocol: " + string(o.NetworkProtocol),
|
||||
"Verbosity level: " + fmt.Sprintf("%d", o.Verbosity),
|
||||
}
|
||||
return strings.Join(settingsList, "\n|--")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/private-internet-access-docker/internal/params"
|
||||
@@ -8,8 +9,10 @@ import (
|
||||
|
||||
// Settings contains all settings for the program to run
|
||||
type Settings struct {
|
||||
VPNSP string
|
||||
OpenVPN OpenVPN
|
||||
PIA PIA
|
||||
Mullvad Mullvad
|
||||
DNS DNS
|
||||
Firewall Firewall
|
||||
TinyProxy TinyProxy
|
||||
@@ -17,10 +20,17 @@ type Settings struct {
|
||||
}
|
||||
|
||||
func (s *Settings) String() string {
|
||||
var vpnServiceProvider string
|
||||
switch s.VPNSP {
|
||||
case "pia":
|
||||
vpnServiceProvider = s.PIA.String()
|
||||
case "mullvad":
|
||||
vpnServiceProvider = s.Mullvad.String()
|
||||
}
|
||||
return strings.Join([]string{
|
||||
"Settings summary below:",
|
||||
s.OpenVPN.String(),
|
||||
s.PIA.String(),
|
||||
vpnServiceProvider,
|
||||
s.DNS.String(),
|
||||
s.Firewall.String(),
|
||||
s.TinyProxy.String(),
|
||||
@@ -32,13 +42,27 @@ func (s *Settings) String() string {
|
||||
// GetAllSettings obtains all settings for the program and returns an error as soon
|
||||
// as an error is encountered reading them.
|
||||
func GetAllSettings(params params.ParamsReader) (settings Settings, err error) {
|
||||
settings.VPNSP, err = params.GetVPNSP()
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.OpenVPN, err = GetOpenVPNSettings(params)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
settings.PIA, err = GetPIASettings(params)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
switch settings.VPNSP {
|
||||
case "pia":
|
||||
settings.PIA, err = GetPIASettings(params)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
case "mullvad":
|
||||
settings.Mullvad, err = GetMullvadSettings(params)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
default:
|
||||
return settings, fmt.Errorf("VPN service provider %q is not valid", settings.VPNSP)
|
||||
}
|
||||
settings.DNS, err = GetDNSSettings(params)
|
||||
if err != nil {
|
||||
|
||||
@@ -39,11 +39,14 @@ func title() []string {
|
||||
}
|
||||
|
||||
func annoucement() []string {
|
||||
timestamp := time.Now().UnixNano() / 1000000000
|
||||
if timestamp < constants.AnnoucementExpiration {
|
||||
return []string{emoji.Sprint(":mega: ") + constants.Annoucement}
|
||||
if len(constants.Annoucement) == 0 {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
expirationDate, _ := time.Parse("2006-01-02", constants.AnnoucementExpiration) // error covered by a unit test
|
||||
if time.Now().After(expirationDate) {
|
||||
return nil
|
||||
}
|
||||
return []string{emoji.Sprint(":mega: ") + constants.Annoucement}
|
||||
}
|
||||
|
||||
func links() []string {
|
||||
|
||||
Reference in New Issue
Block a user