Compare commits

...

20 Commits

Author SHA1 Message Date
Quentin McGaw
09c47c740c fix(version): log last release by tag name alphabetically instead of date 2024-08-09 07:43:48 +00:00
dependabot[bot]
ecbfc02713 Chore(deps): Bump github.com/breml/rootcerts from 0.2.16 to 0.2.17 (#2316) 2024-08-09 09:07:35 +02:00
Quentin McGaw
7be9288685 fix(privatevpn): set openvpn vpn type for no hostname server 2024-08-09 06:24:06 +00:00
Quentin McGaw
d1f57d0e36 chore(deps): bump gosplash to v0.2.0
- Merge same links in the same line
- Add `/choose` suffix to github links
2024-08-05 17:46:31 +00:00
Quentin McGaw
74ea1a0f5a hotfix(firewall): prefer ip6tables (nft) instead of ip6tables-legacy 2024-08-05 14:01:27 +00:00
Quentin McGaw
2a9ab29e7d fix(firewall): VPN_PORT_FORWARDING_LISTENING_PORT behavior fixed again
- allow redirection destination port in INPUT table
2024-08-05 13:57:30 +00:00
Quentin McGaw
8be78a5741 chore(github): add /choose suffix to issue and discussion links 2024-08-05 13:39:32 +00:00
Quentin McGaw
4a669c3458 chore(dev): upgrade organizeImports vscode setting from true to explicit 2024-08-05 13:39:01 +00:00
Quentin McGaw
ae5b71a864 chore(lint): remove now invalid skip-dirs configuration block 2024-08-05 13:38:32 +00:00
Quentin McGaw
6fff2ce1a4 chore(deps): tidy Go modules dependencies 2024-08-05 13:38:15 +00:00
Quentin McGaw
f6165d206a fix(firewall): VPN_PORT_FORWARDING_LISTENING_PORT behavior fixed
by not restricting the destination address to 127.0.0.1
2024-08-05 13:37:49 +00:00
Quentin McGaw
8dbe7b8888 hotfix(readme): add perfect privacy as port forwarding natively supported 2024-08-04 09:00:06 +00:00
Quentin McGaw
10f43d7a70 chore(github): add before next release github label 2024-08-04 08:35:57 +00:00
Quentin McGaw
01283def17 fix(format-servers): add missing vpn type column for natively supported providers
- nordvpn
- surfshark
2024-08-04 08:33:24 +00:00
Quentin McGaw
b32e085354 docs(readme): update list of providers supporting Wireguard with the custom provider 2024-08-03 14:32:41 +00:00
Quentin McGaw
ac9446e296 feat(protonvpn): Wireguard support (#2390) 2024-08-03 16:10:35 +02:00
Quentin McGaw
dea4080a7b fix(custom-openvpn): remove comments before parsing file 2024-08-03 13:37:57 +00:00
Quentin McGaw
2e63dba817 docs(readme): add protonvpn as custom port forwarding implementation 2024-08-03 09:54:14 +00:00
Quentin McGaw
10384c9e37 chore(github): add labels "Custom" and "Category: logs" 2024-08-01 12:20:55 +00:00
Quentin McGaw
34e8f5f3a9 hotfix(custom): assume all custom servers support port forwarding
- Fix custom wireguard with the protonvpn port forwarding implementation
- Might fix #2389
2024-08-01 11:52:38 +00:00
24 changed files with 9643 additions and 148 deletions

View File

@@ -37,12 +37,12 @@
"go.useLanguageServer": true,
"[go]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
}
},
"[go.mod]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
}
},
"gopls": {

View File

@@ -1,10 +1,10 @@
blank_issues_enabled: false
contact_links:
- name: Report a Wiki issue
url: https://github.com/qdm12/gluetun-wiki/issues/new
url: https://github.com/qdm12/gluetun-wiki/issues/new/choose
about: Please create an issue on the gluetun-wiki repository.
- name: Configuration help?
url: https://github.com/qdm12/gluetun/discussions/new
url: https://github.com/qdm12/gluetun/discussions/new/choose
about: Please create a Github discussion.
- name: Unraid template issue
url: https://github.com/qdm12/gluetun/discussions/550

8
.github/labels.yml vendored
View File

@@ -3,6 +3,9 @@
- name: "Status: 🔴 Blocked"
color: "f7d692"
description: "Blocked by another issue or pull request"
- name: "Status: 📌 Before next release"
color: "f7d692"
description: "Has to be done before the next release"
- name: "Status: 🔒 After next release"
color: "f7d692"
description: "Will be done after the next release"
@@ -36,6 +39,8 @@
# VPN providers
- name: "☁️ AirVPN"
color: "cfe8d4"
- name: "☁️ Custom"
color: "cfe8d4"
- name: "☁️ Cyberghost"
color: "cfe8d4"
- name: "☁️ HideMyAss"
@@ -91,6 +96,9 @@
- name: "Category: Maintenance ⛓️"
description: "Anything related to code or other maintenance"
color: "ffc7ea"
- name: "Category: Logs 📚"
description: "Something to change in logs"
color: "ffc7ea"
- name: "Category: Good idea 🎯"
description: "This is a good idea, judged by the maintainers"
color: "ffc7ea"

View File

@@ -120,9 +120,3 @@ linters:
- wastedassign
- whitespace
- zerologlint
run:
skip-dirs:
- .devcontainer
- .github
- doc

View File

@@ -60,8 +60,8 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
- Supports: **AirVPN**, **Cyberghost**, **ExpressVPN**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Perfect Privacy**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **SlickVPN**, **Surfshark**, **TorGuard**, **VPNSecure.me**, **VPNUnlimited**, **Vyprvpn**, **WeVPN**, **Windscribe** servers
- Supports OpenVPN for all providers listed
- Supports Wireguard both kernelspace and userspace
- For **AirVPN**, **FastestVPN**, **Ivpn**, **Mullvad**, **NordVPN**, **Perfect privacy**, **Surfshark** and **Windscribe**
- For **ProtonVPN**, **PureVPN**, **Torguard**, **VPN Unlimited** and **WeVPN** using [the custom provider](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/custom.md)
- For **AirVPN**, **FastestVPN**, **Ivpn**, **Mullvad**, **NordVPN**, **Perfect privacy**, **ProtonVPN**, **Surfshark** and **Windscribe**
- For **Cyberghost**, **Private Internet Access**, **PrivateVPN**, **PureVPN**, **Torguard**, **VPN Unlimited**, **VyprVPN** and **WeVPN** using [the custom provider](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/custom.md)
- For custom Wireguard configurations using [the custom provider](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/custom.md)
- More in progress, see [#134](https://github.com/qdm12/gluetun/issues/134)
- DNS over TLS baked in with service provider(s) of your choice
@@ -73,7 +73,7 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
- [Connect other containers to it](https://github.com/qdm12/gluetun-wiki/blob/main/setup/connect-a-container-to-gluetun.md)
- [Connect LAN devices to it](https://github.com/qdm12/gluetun-wiki/blob/main/setup/connect-a-lan-device-to-gluetun.md)
- Compatible with amd64, i686 (32 bit), **ARM** 64 bit, ARM 32 bit v6 and v7, and even ppc64le 🎆
- [Custom VPN server side port forwarding for Private Internet Access](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/private-internet-access.md#vpn-server-port-forwarding)
- Custom VPN server side port forwarding for [Perfect Privacy](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/perfect-privacy.md#vpn-server-port-forwarding), [Private Internet Access](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/private-internet-access.md#vpn-server-port-forwarding) and [ProtonVPN](https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/protonvpn.md#vpn-server-port-forwarding)
- Possibility of split horizon DNS by selecting multiple DNS over TLS providers
- Unbound subprogram drops root privileges once launched
- Can work as a Kubernetes sidecar container, thanks @rorph
@@ -84,7 +84,7 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
Go to the [Wiki](https://github.com/qdm12/gluetun-wiki)!
[🐛 Found a bug in the Wiki?!](https://github.com/qdm12/gluetun-wiki/issues/new)
[🐛 Found a bug in the Wiki?!](https://github.com/qdm12/gluetun-wiki/issues/new/choose)
Here's a docker-compose.yml for the laziest:

View File

@@ -176,7 +176,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
Emails: []string{"quentin.mcgaw@gmail.com"},
Version: buildInfo.Version,
Commit: buildInfo.Commit,
BuildDate: buildInfo.Created,
Created: buildInfo.Created,
Announcement: "Wiki moved to https://github.com/qdm12/gluetun-wiki",
AnnounceExp: announcementExp,
// Sponsor information

4
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/qdm12/gluetun
go 1.22
require (
github.com/breml/rootcerts v0.2.16
github.com/breml/rootcerts v0.2.17
github.com/fatih/color v1.17.0
github.com/golang/mock v1.6.0
github.com/klauspost/compress v1.17.8
@@ -12,7 +12,7 @@ require (
github.com/qdm12/golibs v0.0.0-20210822203818-5c568b0777b6
github.com/qdm12/gosettings v0.4.2
github.com/qdm12/goshutdown v0.3.0
github.com/qdm12/gosplash v0.1.0
github.com/qdm12/gosplash v0.2.0
github.com/qdm12/gotree v0.2.0
github.com/qdm12/log v0.1.0
github.com/qdm12/ss-server v0.6.0

10
go.sum
View File

@@ -4,8 +4,8 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/g
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/breml/rootcerts v0.2.16 h1:yN1TGvicfHx8dKz3OQRIrx/5nE/iN3XT1ibqGbd6urc=
github.com/breml/rootcerts v0.2.16/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/breml/rootcerts v0.2.17 h1:0/M2BE2Apw0qEJCXDOkaiu7d5Sx5ObNfe1BkImJ4u1I=
github.com/breml/rootcerts v0.2.17/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -93,14 +93,12 @@ github.com/qdm12/golibs v0.0.0-20210603202746-e5494e9c2ebb/go.mod h1:15RBzkun0i8
github.com/qdm12/golibs v0.0.0-20210723175634-a75ca7fd74c2/go.mod h1:6aRbg4Z/bTbm9JfxsGXfWKHi7zsOvPfUTK1S5HuAFKg=
github.com/qdm12/golibs v0.0.0-20210822203818-5c568b0777b6 h1:bge5AL7cjHJMPz+5IOz5yF01q/l8No6+lIEBieA8gMg=
github.com/qdm12/golibs v0.0.0-20210822203818-5c568b0777b6/go.mod h1:6aRbg4Z/bTbm9JfxsGXfWKHi7zsOvPfUTK1S5HuAFKg=
github.com/qdm12/gosettings v0.4.1 h1:c7+14jO1Y2kFXBCUfS2+QE2NgwTKfzcdJzGEFRItCI8=
github.com/qdm12/gosettings v0.4.1/go.mod h1:uItKwGXibJp2pQ0am6MBKilpjfvYTGiH+zXHd10jFj8=
github.com/qdm12/gosettings v0.4.2 h1:Gb39NScPr7OQV+oy0o1OD7A121udITDJuUGa7ljDF58=
github.com/qdm12/gosettings v0.4.2/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
github.com/qdm12/goshutdown v0.3.0 h1:pqBpJkdwlZlfTEx4QHtS8u8CXx6pG0fVo6S1N0MpSEM=
github.com/qdm12/goshutdown v0.3.0/go.mod h1:EqZ46No00kCTZ5qzdd3qIzY6ayhMt24QI8Mh8LVQYmM=
github.com/qdm12/gosplash v0.1.0 h1:Sfl+zIjFZFP7b0iqf2l5UkmEY97XBnaKkH3FNY6Gf7g=
github.com/qdm12/gosplash v0.1.0/go.mod h1:+A3fWW4/rUeDXhY3ieBzwghKdnIPFJgD8K3qQkenJlw=
github.com/qdm12/gosplash v0.2.0 h1:DOxCEizbW6ZG+FgpH2oK1atT6bM8MHL9GZ2ywSS4zZY=
github.com/qdm12/gosplash v0.2.0/go.mod h1:k+1PzhO0th9cpX4q2Nneu4xTsndXqrM/x7NTIYmJ4jo=
github.com/qdm12/gotree v0.2.0 h1:+58ltxkNLUyHtATFereAcOjBVfY6ETqRex8XK90Fb/c=
github.com/qdm12/gotree v0.2.0/go.mod h1:1SdFaqKZuI46U1apbXIf25pDMNnrPuYLEqMF/qL4lY4=
github.com/qdm12/log v0.1.0 h1:jYBd/xscHYpblzZAd2kjZp2YmuYHjAAfbTViJWxoPTw=

View File

@@ -39,6 +39,7 @@ func (p *Provider) validate(vpnType string, storage Storage) (err error) {
providers.Ivpn,
providers.Mullvad,
providers.Nordvpn,
providers.Protonvpn,
providers.Surfshark,
providers.Windscribe,
}

View File

@@ -62,6 +62,7 @@ func (w Wireguard) validate(vpnProvider string, ipv6Supported bool) (err error)
providers.Ivpn,
providers.Mullvad,
providers.Nordvpn,
providers.Protonvpn,
providers.Surfshark,
providers.Windscribe,
) {
@@ -173,10 +174,15 @@ func (w *Wireguard) overrideWith(other Wireguard) {
func (w *Wireguard) setDefaults(vpnProvider string) {
w.PrivateKey = gosettings.DefaultPointer(w.PrivateKey, "")
w.PreSharedKey = gosettings.DefaultPointer(w.PreSharedKey, "")
if vpnProvider == providers.Nordvpn {
switch vpnProvider {
case providers.Nordvpn:
defaultNordVPNAddress := netip.AddrFrom4([4]byte{10, 5, 0, 2})
defaultNordVPNPrefix := netip.PrefixFrom(defaultNordVPNAddress, defaultNordVPNAddress.BitLen())
w.Addresses = gosettings.DefaultSlice(w.Addresses, []netip.Prefix{defaultNordVPNPrefix})
case providers.Protonvpn:
defaultAddress := netip.AddrFrom4([4]byte{10, 2, 0, 2})
defaultPrefix := netip.PrefixFrom(defaultAddress, defaultAddress.BitLen())
w.Addresses = gosettings.DefaultSlice(w.Addresses, []netip.Prefix{defaultPrefix})
}
defaultAllowedIPs := []netip.Prefix{
netip.PrefixFrom(netip.IPv4Unspecified(), 0),

View File

@@ -39,8 +39,8 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
// Validate EndpointIP
switch vpnProvider {
case providers.Airvpn, providers.Fastestvpn, providers.Ivpn,
providers.Mullvad, providers.Nordvpn, providers.Surfshark,
providers.Windscribe:
providers.Mullvad, providers.Nordvpn, providers.Protonvpn,
providers.Surfshark, providers.Windscribe:
// endpoint IP addresses are baked in
case providers.Custom:
if !w.EndpointIP.IsValid() || w.EndpointIP.IsUnspecified() {
@@ -57,7 +57,8 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
return fmt.Errorf("%w", ErrWireguardEndpointPortNotSet)
}
// EndpointPort cannot be set
case providers.Fastestvpn, providers.Surfshark, providers.Nordvpn:
case providers.Fastestvpn, providers.Nordvpn,
providers.Protonvpn, providers.Surfshark:
if *w.EndpointPort != 0 {
return fmt.Errorf("%w", ErrWireguardEndpointPortSet)
}

View File

@@ -15,7 +15,7 @@ import (
// empty string path is returned.
func findIP6tablesSupported(ctx context.Context, runner command.Runner) (
ip6tablesPath string, err error) {
ip6tablesPath, err = checkIptablesSupport(ctx, runner, "ip6tables-legacy", "ip6tables", "ip6tables-nft")
ip6tablesPath, err = checkIptablesSupport(ctx, runner, "ip6tables", "ip6tables-nft", "ip6tables-legacy")
if errors.Is(err, ErrIPTablesNotSupported) {
return "", nil
} else if err != nil {

View File

@@ -210,10 +210,14 @@ func (c *Config) redirectPort(ctx context.Context, intf string,
}
err = c.runIptablesInstructions(ctx, []string{
fmt.Sprintf("-t nat %s PREROUTING %s -d 127.0.0.1 -p tcp --dport %d -j REDIRECT --to-ports %d",
fmt.Sprintf("-t nat %s PREROUTING %s -p tcp --dport %d -j REDIRECT --to-ports %d",
appendOrDelete(remove), interfaceFlag, sourcePort, destinationPort),
fmt.Sprintf("-t nat %s PREROUTING %s -d 127.0.0.1 -p udp --dport %d -j REDIRECT --to-ports %d",
fmt.Sprintf("%s INPUT %s -p tcp -m tcp --dport %d -j ACCEPT",
appendOrDelete(remove), interfaceFlag, destinationPort),
fmt.Sprintf("-t nat %s PREROUTING %s -p udp --dport %d -j REDIRECT --to-ports %d",
appendOrDelete(remove), interfaceFlag, sourcePort, destinationPort),
fmt.Sprintf("%s INPUT %s -p udp -m udp --dport %d -j ACCEPT",
appendOrDelete(remove), interfaceFlag, destinationPort),
})
if err != nil {
return fmt.Errorf("redirecting IPv4 source port %d to destination port %d on interface %s: %w",
@@ -221,10 +225,14 @@ func (c *Config) redirectPort(ctx context.Context, intf string,
}
err = c.runIP6tablesInstructions(ctx, []string{
fmt.Sprintf("-t nat %s PREROUTING %s -d ::1 -p tcp --dport %d -j REDIRECT --to-ports %d",
fmt.Sprintf("-t nat %s PREROUTING %s -p tcp --dport %d -j REDIRECT --to-ports %d",
appendOrDelete(remove), interfaceFlag, sourcePort, destinationPort),
fmt.Sprintf("-t nat %s PREROUTING %s -d ::1 -p udp --dport %d -j REDIRECT --to-ports %d",
fmt.Sprintf("%s INPUT %s -p tcp -m tcp --dport %d -j ACCEPT",
appendOrDelete(remove), interfaceFlag, destinationPort),
fmt.Sprintf("-t nat %s PREROUTING %s -p udp --dport %d -j REDIRECT --to-ports %d",
appendOrDelete(remove), interfaceFlag, sourcePort, destinationPort),
fmt.Sprintf("%s INPUT %s -p udp -m udp --dport %d -j ACCEPT",
appendOrDelete(remove), interfaceFlag, destinationPort),
})
if err != nil {
return fmt.Errorf("redirecting IPv6 source port %d to destination port %d on interface %s: %w",

View File

@@ -21,7 +21,7 @@ type Connection struct {
PubKey string `json:"pubkey"`
// ServerName is used for PIA for port forwarding
ServerName string `json:"server_name,omitempty"`
// PortForward is used for PIA for port forwarding
// PortForward is used for PIA and ProtonVPN for port forwarding
PortForward bool `json:"port_forward"`
}

View File

@@ -125,7 +125,7 @@ func getMarkdownHeaders(vpnProvider string) (headers []string) {
case providers.Mullvad:
return []string{countryHeader, cityHeader, ispHeader, ownedHeader, hostnameHeader, vpnHeader}
case providers.Nordvpn:
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, categoriesHeader}
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, vpnHeader, categoriesHeader}
case providers.Perfectprivacy:
return []string{cityHeader, tcpHeader, udpHeader}
case providers.Privado:
@@ -135,14 +135,15 @@ func getMarkdownHeaders(vpnProvider string) (headers []string) {
case providers.Privatevpn:
return []string{countryHeader, cityHeader, hostnameHeader}
case providers.Protonvpn:
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader,
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, vpnHeader,
freeHeader, portForwardHeader, secureHeader, torHeader}
case providers.Purevpn:
return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}
case providers.SlickVPN:
return []string{regionHeader, countryHeader, cityHeader, hostnameHeader}
case providers.Surfshark:
return []string{regionHeader, countryHeader, cityHeader, hostnameHeader, multiHopHeader, tcpHeader, udpHeader}
return []string{regionHeader, countryHeader, cityHeader, hostnameHeader,
vpnHeader, multiHopHeader, tcpHeader, udpHeader}
case providers.Torguard:
return []string{countryHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}
case providers.VPNSecure:

View File

@@ -18,6 +18,11 @@ var (
func extractDataFromLines(lines []string) (
connection models.Connection, err error) {
for i, line := range lines {
hashSymbolIndex := strings.Index(line, "#")
if hashSymbolIndex >= 0 {
line = line[:hashSymbolIndex]
}
ip, port, protocol, err := extractDataFromLine(line)
if err != nil {
return connection, fmt.Errorf("on line %d: %w", i+1, err)

View File

@@ -40,11 +40,12 @@ func getOpenVPNConnection(extractor Extractor,
connection.Port = customPort
}
// assume all custom provider servers support port forwarding
connection.PortForward = true
if len(selection.Names) > 0 {
// Set the server name for PIA port forwarding code used
// together with the custom provider.
connection.ServerName = selection.Names[0]
connection.PortForward = true
}
return connection, nil
@@ -53,17 +54,17 @@ func getOpenVPNConnection(extractor Extractor,
func getWireguardConnection(selection settings.ServerSelection) (
connection models.Connection) {
connection = models.Connection{
Type: vpn.Wireguard,
IP: selection.Wireguard.EndpointIP,
Port: *selection.Wireguard.EndpointPort,
Protocol: constants.UDP,
PubKey: selection.Wireguard.PublicKey,
Type: vpn.Wireguard,
IP: selection.Wireguard.EndpointIP,
Port: *selection.Wireguard.EndpointPort,
Protocol: constants.UDP,
PubKey: selection.Wireguard.PublicKey,
PortForward: true, // assume all custom provider servers support port forwarding
}
if len(selection.Names) > 0 {
// Set the server name for PIA port forwarding code used
// together with the custom provider.
connection.ServerName = selection.Names[0]
connection.PortForward = true
}
return connection
}

View File

@@ -7,6 +7,7 @@ import (
"strings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
"github.com/qdm12/gluetun/internal/updater/openvpn"
@@ -64,6 +65,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
continue
}
server := models.Server{
VPN: vpn.OpenVPN,
Country: country,
City: city,
IPs: ips,

View File

@@ -8,7 +8,7 @@ import (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -28,10 +28,11 @@ type logicalServer struct {
}
type physicalServer struct {
EntryIP netip.Addr `json:"EntryIP"`
ExitIP netip.Addr `json:"ExitIP"`
Domain string `json:"Domain"`
Status uint8 `json:"Status"`
EntryIP netip.Addr `json:"EntryIP"`
ExitIP netip.Addr `json:"ExitIP"`
Domain string `json:"Domain"`
Status uint8 `json:"Status"`
X25519PublicKey string `json:"X25519PublicKey"`
}
func fetchAPI(ctx context.Context, client *http.Client) (

View File

@@ -7,7 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/models"
)
type ipToServer map[string]models.Server
type ipToServers map[string][2]models.Server // first server is OpenVPN, second is Wireguard.
type features struct {
secureCore bool
@@ -16,36 +16,50 @@ type features struct {
stream bool
}
func (its ipToServer) add(country, region, city, name, hostname string,
func (its ipToServers) add(country, region, city, name, hostname, wgPubKey string,
free bool, entryIP netip.Addr, features features) {
key := entryIP.String()
server, ok := its[key]
servers, ok := its[key]
if ok {
return
}
server.VPN = vpn.OpenVPN
server.Country = country
server.Region = region
server.City = city
server.ServerName = name
server.Hostname = hostname
server.Free = free
server.SecureCore = features.secureCore
server.Tor = features.tor
server.PortForward = features.p2p
server.Stream = features.stream
server.UDP = true
server.TCP = true
server.IPs = []netip.Addr{entryIP}
its[key] = server
baseServer := models.Server{
Country: country,
Region: region,
City: city,
ServerName: name,
Hostname: hostname,
Free: free,
SecureCore: features.secureCore,
Tor: features.tor,
PortForward: features.p2p,
Stream: features.stream,
IPs: []netip.Addr{entryIP},
}
openvpnServer := baseServer
openvpnServer.VPN = vpn.OpenVPN
openvpnServer.UDP = true
openvpnServer.TCP = true
servers[0] = openvpnServer
wireguardServer := baseServer
wireguardServer.VPN = vpn.Wireguard
wireguardServer.WgPubKey = wgPubKey
servers[1] = wireguardServer
its[key] = servers
}
func (its ipToServer) toServersSlice() (servers []models.Server) {
servers = make([]models.Server, 0, len(its))
for _, server := range its {
servers = append(servers, server)
func (its ipToServers) toServersSlice() (serversSlice []models.Server) {
const vpnProtocols = 2
serversSlice = make([]models.Server, 0, vpnProtocols*len(its))
for _, servers := range its {
serversSlice = append(serversSlice, servers[0], servers[1])
}
return servers
return serversSlice
}
func (its ipToServers) numberOfServers() int {
const serversPerIP = 2
return len(its) * serversPerIP
}

View File

@@ -29,7 +29,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, count, minServers)
}
ipToServer := make(ipToServer, count)
ipToServer := make(ipToServers, count)
for _, logicalServer := range data.LogicalServers {
region := getStringValue(logicalServer.Region)
city := getStringValue(logicalServer.City)
@@ -65,6 +65,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
hostname := physicalServer.Domain
entryIP := physicalServer.EntryIP
wgPubKey := physicalServer.X25519PublicKey
// Note: for multi-hop use the server name or hostname
// instead of the country
@@ -74,11 +75,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
u.warner.Warn(warning)
}
ipToServer.add(country, region, city, name, hostname, free, entryIP, features)
ipToServer.add(country, region, city, name, hostname, wgPubKey, free, entryIP, features)
}
}
if len(ipToServer) < minServers {
if ipToServer.numberOfServers() < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(ipToServer), minServers)
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/http"
"sort"
"time"
"github.com/qdm12/gluetun/internal/models"
@@ -49,13 +50,17 @@ func getLatestRelease(ctx context.Context, client *http.Client) (tagName, name s
if err != nil {
return "", "", time, err
}
// Sort releases by tag names (semver)
sort.Slice(releases, func(i, j int) bool {
return releases[i].TagName > releases[j].TagName
})
for _, release := range releases {
if release.Prerelease {
continue
}
return release.TagName, release.Name, release.PublishedAt, nil
}
return "", "", time, errReleaseNotFound
return "", "", time, fmt.Errorf("%w", errReleaseNotFound)
}
var errCommitNotFound = errors.New("commit not found")