diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index f78d4833d..f3ec270b7 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -50,6 +50,7 @@ body: - Cyberghost - ExpressVPN - FastestVPN + - Giganews - HideMyAss - IPVanish - IVPN diff --git a/.github/labels.yml b/.github/labels.yml index ec2332815..73ee66006 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -46,6 +46,8 @@ color: "cfe8d4" - name: "☁️ Cyberghost" color: "cfe8d4" +- name: "☁️ Giganews" + color: "cfe8d4" - name: "☁️ HideMyAss" color: "cfe8d4" - name: "☁️ IPVanish" diff --git a/README.md b/README.md index 1f7b6763e..b5ca31f83 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers ## Features - Based on Alpine 3.20 for a small Docker image of 35.6MB -- 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: **AirVPN**, **Cyberghost**, **ExpressVPN**, **FastestVPN**, **Giganews**, **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**, **ProtonVPN**, **Surfshark** and **Windscribe** diff --git a/internal/configuration/settings/openvpnselection.go b/internal/configuration/settings/openvpnselection.go index 519ac9e1a..0e95a1f97 100644 --- a/internal/configuration/settings/openvpnselection.go +++ b/internal/configuration/settings/openvpnselection.go @@ -50,6 +50,7 @@ func (o OpenVPNSelection) validate(vpnProvider string) (err error) { // Validate TCP if o.Protocol == constants.TCP && helpers.IsOneOf(vpnProvider, + providers.Giganews, providers.Ipvanish, providers.Perfectprivacy, providers.Privado, @@ -67,7 +68,7 @@ func (o OpenVPNSelection) validate(vpnProvider string) (err error) { providers.Privatevpn, providers.Torguard: // no custom port allowed case providers.Expressvpn, providers.Fastestvpn, - providers.Ipvanish, providers.Nordvpn, + providers.Giganews, providers.Ipvanish, providers.Nordvpn, providers.Privado, providers.Purevpn, providers.Surfshark, providers.VPNSecure, providers.VPNUnlimited, providers.Vyprvpn: diff --git a/internal/constants/providers/providers.go b/internal/constants/providers/providers.go index b1c49d884..0c511e5ee 100644 --- a/internal/constants/providers/providers.go +++ b/internal/constants/providers/providers.go @@ -9,6 +9,7 @@ const ( Example = "example" Expressvpn = "expressvpn" Fastestvpn = "fastestvpn" + Giganews = "giganews" HideMyAss = "hidemyass" Ipvanish = "ipvanish" Ivpn = "ivpn" @@ -37,6 +38,7 @@ func All() []string { Cyberghost, Expressvpn, Fastestvpn, + Giganews, HideMyAss, Ipvanish, Ivpn, diff --git a/internal/models/markdown.go b/internal/models/markdown.go index 1dc5e6195..b725d9744 100644 --- a/internal/models/markdown.go +++ b/internal/models/markdown.go @@ -124,6 +124,8 @@ func getMarkdownHeaders(vpnProvider string) (headers []string, err error) { return []string{countryHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil case providers.Fastestvpn: return []string{countryHeader, hostnameHeader, vpnHeader, tcpHeader, udpHeader}, nil + case providers.Giganews: + return []string{regionHeader, hostnameHeader, tcpHeader, udpHeader}, nil case providers.HideMyAss: return []string{countryHeader, regionHeader, cityHeader, hostnameHeader, tcpHeader, udpHeader}, nil case providers.Ipvanish: diff --git a/internal/provider/giganews/connection.go b/internal/provider/giganews/connection.go new file mode 100644 index 000000000..655c7a791 --- /dev/null +++ b/internal/provider/giganews/connection.go @@ -0,0 +1,14 @@ +package giganews + +import ( + "github.com/qdm12/gluetun/internal/configuration/settings" + "github.com/qdm12/gluetun/internal/models" + "github.com/qdm12/gluetun/internal/provider/utils" +) + +func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) ( + connection models.Connection, err error) { + defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd + return utils.GetConnection(p.Name(), + p.storage, selection, defaults, ipv6Supported, p.randSource) +} diff --git a/internal/provider/giganews/openvpnconf.go b/internal/provider/giganews/openvpnconf.go new file mode 100644 index 000000000..d2fa43a07 --- /dev/null +++ b/internal/provider/giganews/openvpnconf.go @@ -0,0 +1,28 @@ +package giganews + +import ( + "github.com/qdm12/gluetun/internal/configuration/settings" + "github.com/qdm12/gluetun/internal/constants/openvpn" + "github.com/qdm12/gluetun/internal/models" + "github.com/qdm12/gluetun/internal/provider/utils" +) + +func (p *Provider) OpenVPNConfig(connection models.Connection, + settings settings.OpenVPN, ipv6Supported bool) (lines []string) { + //nolint:gomnd + providerSettings := utils.OpenVPNProviderSettings{ + RemoteCertTLS: true, + AuthUserPass: true, + Ciphers: []string{ + openvpn.AES256cbc, + }, + Auth: openvpn.SHA256, + Ping: 10, + CAs: []string{"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"}, //nolint:lll + TLSCipher: "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA", //nolint:lll + ExtraLines: []string{ + "comp-lzo", + }, + } + return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported) +} diff --git a/internal/provider/giganews/provider.go b/internal/provider/giganews/provider.go new file mode 100644 index 000000000..eef312146 --- /dev/null +++ b/internal/provider/giganews/provider.go @@ -0,0 +1,29 @@ +package giganews + +import ( + "math/rand" + + "github.com/qdm12/gluetun/internal/constants/providers" + "github.com/qdm12/gluetun/internal/provider/common" + "github.com/qdm12/gluetun/internal/provider/giganews/updater" +) + +type Provider struct { + storage common.Storage + randSource rand.Source + common.Fetcher +} + +func New(storage common.Storage, randSource rand.Source, + unzipper common.Unzipper, updaterWarner common.Warner, + parallelResolver common.ParallelResolver) *Provider { + return &Provider{ + storage: storage, + randSource: randSource, + Fetcher: updater.New(unzipper, updaterWarner, parallelResolver), + } +} + +func (p *Provider) Name() string { + return providers.Giganews +} diff --git a/internal/provider/giganews/updater/filename.go b/internal/provider/giganews/updater/filename.go new file mode 100644 index 000000000..a2fd3f6e2 --- /dev/null +++ b/internal/provider/giganews/updater/filename.go @@ -0,0 +1,22 @@ +package updater + +import ( + "errors" + "fmt" + "strings" +) + +var errNotOvpnExt = errors.New("filename does not have the openvpn file extension") + +func parseFilename(fileName string) ( + region string, err error, +) { + const suffix = ".ovpn" + if !strings.HasSuffix(fileName, suffix) { + return "", fmt.Errorf("%w: %s", errNotOvpnExt, fileName) + } + + region = strings.TrimSuffix(fileName, suffix) + region = strings.ReplaceAll(region, " - ", " ") + return region, nil +} diff --git a/internal/provider/giganews/updater/hosttoserver.go b/internal/provider/giganews/updater/hosttoserver.go new file mode 100644 index 000000000..df9e93698 --- /dev/null +++ b/internal/provider/giganews/updater/hosttoserver.go @@ -0,0 +1,55 @@ +package updater + +import ( + "net/netip" + + "github.com/qdm12/gluetun/internal/constants/vpn" + "github.com/qdm12/gluetun/internal/models" +) + +type hostToServer map[string]models.Server + +func (hts hostToServer) add(host, region string, tcp, udp bool) { + server, ok := hts[host] + if !ok { + server.VPN = vpn.OpenVPN + server.Hostname = host + server.Region = region + } + if tcp { + server.TCP = true + } + if udp { + server.UDP = true + } + hts[host] = server +} + +func (hts hostToServer) toHostsSlice() (hosts []string) { + hosts = make([]string, 0, len(hts)) + for host := range hts { + hosts = append(hosts, host) + } + return hosts +} + +func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) { + for host, IPs := range hostToIPs { + server := hts[host] + server.IPs = IPs + hts[host] = server + } + for host, server := range hts { + if len(server.IPs) == 0 { + delete(hts, host) + } + } +} + +func (hts hostToServer) toServersSlice() (servers []models.Server) { + servers = make([]models.Server, 0, len(hts)) + for _, server := range hts { + servers = append(servers, server) + } + return servers +} diff --git a/internal/provider/giganews/updater/resolve.go b/internal/provider/giganews/updater/resolve.go new file mode 100644 index 000000000..fde66d470 --- /dev/null +++ b/internal/provider/giganews/updater/resolve.go @@ -0,0 +1,28 @@ +package updater + +import ( + "time" + + "github.com/qdm12/gluetun/internal/updater/resolver" +) + +func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) { + const ( + maxFailRatio = 0.1 + maxDuration = 5 * time.Second + betweenDuration = time.Second + maxNoNew = 2 + maxFails = 2 + ) + return resolver.ParallelSettings{ + Hosts: hosts, + MaxFailRatio: maxFailRatio, + Repeat: resolver.RepeatSettings{ + MaxDuration: maxDuration, + BetweenDuration: betweenDuration, + MaxNoNew: maxNoNew, + MaxFails: maxFails, + SortIPs: true, + }, + } +} diff --git a/internal/provider/giganews/updater/servers.go b/internal/provider/giganews/updater/servers.go new file mode 100644 index 000000000..0746bb003 --- /dev/null +++ b/internal/provider/giganews/updater/servers.go @@ -0,0 +1,87 @@ +package updater + +import ( + "context" + "fmt" + "sort" + "strings" + + "github.com/qdm12/gluetun/internal/models" + "github.com/qdm12/gluetun/internal/provider/common" + "github.com/qdm12/gluetun/internal/updater/openvpn" +) + +func (u *Updater) FetchServers(ctx context.Context, minServers int) ( + servers []models.Server, err error) { + const url = "https://support.vyprvpn.com/hc/article_attachments/360052617332/Vypr_OpenVPN_20200320.zip" + contents, err := u.unzipper.FetchAndExtract(ctx, url) + if err != nil { + return nil, err + } else if len(contents) < minServers { + return nil, fmt.Errorf("%w: %d and expected at least %d", + common.ErrNotEnoughServers, len(contents), minServers) + } + + hts := make(hostToServer) + + for fileName, content := range contents { + if !strings.HasSuffix(fileName, ".ovpn") { + continue // not an OpenVPN file + } + + host, warning, err := openvpn.ExtractHost(content) + if warning != "" { + u.warner.Warn(warning) + } + if err != nil { + // treat error as warning and go to next file + u.warner.Warn(err.Error() + " in " + fileName) + continue + } + host = strings.ReplaceAll(host, "vyprvpn.com", "vpn.giganews.com") + + tcp, udp, err := openvpn.ExtractProto(content) + if err != nil { + // treat error as warning and go to next file + u.warner.Warn(err.Error() + " in " + fileName) + continue + } + + region, err := parseFilename(fileName) + if err != nil { + // treat error as warning and go to next file + u.warner.Warn(err.Error()) + continue + } + + hts.add(host, region, tcp, udp) + } + + if len(hts) < minServers { + return nil, fmt.Errorf("%w: %d and expected at least %d", + common.ErrNotEnoughServers, len(hts), minServers) + } + + hosts := hts.toHostsSlice() + resolveSettings := parallelResolverSettings(hosts) + hostToIPs, warnings, err := u.parallelResolver.Resolve(ctx, resolveSettings) + for _, warning := range warnings { + u.warner.Warn(warning) + } + if err != nil { + return nil, err + } + + if len(hostToIPs) < minServers { + return nil, fmt.Errorf("%w: %d and expected at least %d", + common.ErrNotEnoughServers, len(servers), minServers) + } + + hts.adaptWithIPs(hostToIPs) + + servers = hts.toServersSlice() + + sort.Sort(models.SortableServers(servers)) + + return servers, nil +} diff --git a/internal/provider/giganews/updater/updater.go b/internal/provider/giganews/updater/updater.go new file mode 100644 index 000000000..3fbee059c --- /dev/null +++ b/internal/provider/giganews/updater/updater.go @@ -0,0 +1,20 @@ +package updater + +import ( + "github.com/qdm12/gluetun/internal/provider/common" +) + +type Updater struct { + unzipper common.Unzipper + parallelResolver common.ParallelResolver + warner common.Warner +} + +func New(unzipper common.Unzipper, warner common.Warner, + parallelResolver common.ParallelResolver) *Updater { + return &Updater{ + unzipper: unzipper, + parallelResolver: parallelResolver, + warner: warner, + } +} diff --git a/internal/provider/providers.go b/internal/provider/providers.go index a689e1499..e3f18381e 100644 --- a/internal/provider/providers.go +++ b/internal/provider/providers.go @@ -15,6 +15,7 @@ import ( "github.com/qdm12/gluetun/internal/provider/cyberghost" "github.com/qdm12/gluetun/internal/provider/expressvpn" "github.com/qdm12/gluetun/internal/provider/fastestvpn" + "github.com/qdm12/gluetun/internal/provider/giganews" "github.com/qdm12/gluetun/internal/provider/hidemyass" "github.com/qdm12/gluetun/internal/provider/ipvanish" "github.com/qdm12/gluetun/internal/provider/ivpn" @@ -63,6 +64,7 @@ func NewProviders(storage Storage, timeNow func() time.Time, providers.Cyberghost: cyberghost.New(storage, randSource, parallelResolver), providers.Expressvpn: expressvpn.New(storage, randSource, unzipper, updaterWarner, parallelResolver), providers.Fastestvpn: fastestvpn.New(storage, randSource, client, updaterWarner, parallelResolver), + providers.Giganews: giganews.New(storage, randSource, unzipper, updaterWarner, parallelResolver), providers.HideMyAss: hidemyass.New(storage, randSource, client, updaterWarner, parallelResolver), providers.Ipvanish: ipvanish.New(storage, randSource, unzipper, updaterWarner, parallelResolver), providers.Ivpn: ivpn.New(storage, randSource, client, updaterWarner, parallelResolver), diff --git a/internal/storage/servers.json b/internal/storage/servers.json index 102b00996..323387125 100644 --- a/internal/storage/servers.json +++ b/internal/storage/servers.json @@ -25178,6 +25178,669 @@ } ] }, + "giganews": { + "version": 1, + "timestamp": 1726044812, + "servers": [ + { + "vpn": "openvpn", + "region": "Algeria", + "hostname": "dz1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.104.253" + ] + }, + { + "vpn": "openvpn", + "region": "Argentina", + "hostname": "ar1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.35" + ] + }, + { + "vpn": "openvpn", + "region": "Australia Melbourne", + "hostname": "au2.vpn.giganews.com", + "udp": true, + "ips": [ + "64.253.88.29" + ] + }, + { + "vpn": "openvpn", + "region": "Australia Perth", + "hostname": "au3.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.27" + ] + }, + { + "vpn": "openvpn", + "region": "Australia Sydney", + "hostname": "au1.vpn.giganews.com", + "udp": true, + "ips": [ + "64.253.88.21" + ] + }, + { + "vpn": "openvpn", + "region": "Austria", + "hostname": "at1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.148.253" + ] + }, + { + "vpn": "openvpn", + "region": "Bahrain", + "hostname": "bh1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.63.253" + ] + }, + { + "vpn": "openvpn", + "region": "Belgium", + "hostname": "be1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.145.253" + ] + }, + { + "vpn": "openvpn", + "region": "Brazil", + "hostname": "br1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.33" + ] + }, + { + "vpn": "openvpn", + "region": "Bulgaria", + "hostname": "bg1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.167.253" + ] + }, + { + "vpn": "openvpn", + "region": "Canada", + "hostname": "ca1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.34" + ] + }, + { + "vpn": "openvpn", + "region": "Columbia", + "hostname": "co1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.37" + ] + }, + { + "vpn": "openvpn", + "region": "Costa Rica", + "hostname": "cr1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.39" + ] + }, + { + "vpn": "openvpn", + "region": "Czech Republic", + "hostname": "cz1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.164.253" + ] + }, + { + "vpn": "openvpn", + "region": "Denmark", + "hostname": "dk1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.154.253" + ] + }, + { + "vpn": "openvpn", + "region": "Dubai", + "hostname": "ae1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.101.253" + ] + }, + { + "vpn": "openvpn", + "region": "Egypt", + "hostname": "eg1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.10.253" + ] + }, + { + "vpn": "openvpn", + "region": "El Salvador", + "hostname": "sv1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.36" + ] + }, + { + "vpn": "openvpn", + "region": "Finland", + "hostname": "fi1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.166.253" + ] + }, + { + "vpn": "openvpn", + "region": "France", + "hostname": "fr1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.141.253" + ] + }, + { + "vpn": "openvpn", + "region": "Germany", + "hostname": "de1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.128.253" + ] + }, + { + "vpn": "openvpn", + "region": "Greece", + "hostname": "gr1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.11.253" + ] + }, + { + "vpn": "openvpn", + "region": "Hong Kong", + "hostname": "hk1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.37" + ] + }, + { + "vpn": "openvpn", + "region": "Iceland", + "hostname": "is1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.17.253" + ] + }, + { + "vpn": "openvpn", + "region": "India", + "hostname": "in1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.60.253" + ] + }, + { + "vpn": "openvpn", + "region": "Indonesia", + "hostname": "id1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.28" + ] + }, + { + "vpn": "openvpn", + "region": "Ireland", + "hostname": "ie1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.19.253" + ] + }, + { + "vpn": "openvpn", + "region": "Israel", + "hostname": "il1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.59.253" + ] + }, + { + "vpn": "openvpn", + "region": "Italy", + "hostname": "it1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.161.253" + ] + }, + { + "vpn": "openvpn", + "region": "Japan", + "hostname": "jp1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.20.20" + ] + }, + { + "vpn": "openvpn", + "region": "Latvia", + "hostname": "lv1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.174.253" + ] + }, + { + "vpn": "openvpn", + "region": "Liechtenstein", + "hostname": "li1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.177.253" + ] + }, + { + "vpn": "openvpn", + "region": "Lithuania", + "hostname": "lt1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.173.253" + ] + }, + { + "vpn": "openvpn", + "region": "Luxembourg", + "hostname": "lu1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.165.253" + ] + }, + { + "vpn": "openvpn", + "region": "Macao", + "hostname": "mo1.vpn.giganews.com", + "udp": true, + "ips": [ + "69.167.31.253" + ] + }, + { + "vpn": "openvpn", + "region": "Malaysia", + "hostname": "my1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.29" + ] + }, + { + "vpn": "openvpn", + "region": "Maldives", + "hostname": "mv1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.35" + ] + }, + { + "vpn": "openvpn", + "region": "Marshall Islands", + "hostname": "mh1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.34" + ] + }, + { + "vpn": "openvpn", + "region": "Mexico", + "hostname": "mx1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.24" + ] + }, + { + "vpn": "openvpn", + "region": "Netherlands", + "hostname": "eu1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.135.253" + ] + }, + { + "vpn": "openvpn", + "region": "New Zealand", + "hostname": "nz1.vpn.giganews.com", + "udp": true, + "ips": [ + "64.253.88.29" + ] + }, + { + "vpn": "openvpn", + "region": "Norway", + "hostname": "no1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.163.253" + ] + }, + { + "vpn": "openvpn", + "region": "Pakistan", + "hostname": "pk1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.58.253" + ] + }, + { + "vpn": "openvpn", + "region": "Panama", + "hostname": "pa1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.41" + ] + }, + { + "vpn": "openvpn", + "region": "Philippines", + "hostname": "ph1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.30" + ] + }, + { + "vpn": "openvpn", + "region": "Poland", + "hostname": "pl1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.170.253" + ] + }, + { + "vpn": "openvpn", + "region": "Portugal", + "hostname": "pt1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.168.253" + ] + }, + { + "vpn": "openvpn", + "region": "Qatar", + "hostname": "qa1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.62.253" + ] + }, + { + "vpn": "openvpn", + "region": "Romania", + "hostname": "ro1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.171.253" + ] + }, + { + "vpn": "openvpn", + "region": "Russia", + "hostname": "ru1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.151.253" + ] + }, + { + "vpn": "openvpn", + "region": "Saudi Arabia", + "hostname": "sa1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.61.253" + ] + }, + { + "vpn": "openvpn", + "region": "Singapore", + "hostname": "sg1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.31" + ] + }, + { + "vpn": "openvpn", + "region": "Slovakia", + "hostname": "sk1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.176.253" + ] + }, + { + "vpn": "openvpn", + "region": "Slovenia", + "hostname": "si1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.175.253" + ] + }, + { + "vpn": "openvpn", + "region": "South Korea", + "hostname": "kr1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.20.21" + ] + }, + { + "vpn": "openvpn", + "region": "Spain", + "hostname": "es1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.157.253" + ] + }, + { + "vpn": "openvpn", + "region": "Sweden", + "hostname": "se1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.159.253" + ] + }, + { + "vpn": "openvpn", + "region": "Switzerland", + "hostname": "ch1.vpn.giganews.com", + "udp": true, + "ips": [ + "31.6.41.253" + ] + }, + { + "vpn": "openvpn", + "region": "Taiwan", + "hostname": "tw1.vpn.giganews.com", + "udp": true, + "ips": [ + "69.167.32.253" + ] + }, + { + "vpn": "openvpn", + "region": "Thailand", + "hostname": "th1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.32" + ] + }, + { + "vpn": "openvpn", + "region": "Turkey", + "hostname": "tr1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.169.253" + ] + }, + { + "vpn": "openvpn", + "region": "USA Austin", + "hostname": "us3.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.28" + ] + }, + { + "vpn": "openvpn", + "region": "USA Chicago", + "hostname": "us6.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.22" + ] + }, + { + "vpn": "openvpn", + "region": "USA Los Angeles", + "hostname": "us1.vpn.giganews.com", + "udp": true, + "ips": [ + "69.167.28.253" + ] + }, + { + "vpn": "openvpn", + "region": "USA Miami", + "hostname": "us4.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.16.31" + ] + }, + { + "vpn": "openvpn", + "region": "USA New York", + "hostname": "us5.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.32" + ] + }, + { + "vpn": "openvpn", + "region": "USA San Francisco", + "hostname": "us7.vpn.giganews.com", + "udp": true, + "ips": [ + "69.167.29.253" + ] + }, + { + "vpn": "openvpn", + "region": "USA Seattle", + "hostname": "us8.vpn.giganews.com", + "udp": true, + "ips": [ + "69.167.30.253" + ] + }, + { + "vpn": "openvpn", + "region": "USA Washington DC", + "hostname": "us2.vpn.giganews.com", + "udp": true, + "ips": [ + "209.160.115.253" + ] + }, + { + "vpn": "openvpn", + "region": "Ukraine", + "hostname": "ua1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.172.253" + ] + }, + { + "vpn": "openvpn", + "region": "United Kingdom", + "hostname": "uk1.vpn.giganews.com", + "udp": true, + "ips": [ + "178.208.168.253" + ] + }, + { + "vpn": "openvpn", + "region": "Uruguay", + "hostname": "uy1.vpn.giganews.com", + "udp": true, + "ips": [ + "128.90.34.26" + ] + }, + { + "vpn": "openvpn", + "region": "Vietnam", + "hostname": "vn1.vpn.giganews.com", + "udp": true, + "ips": [ + "216.168.18.33" + ] + } + ] + }, "hidemyass": { "version": 2, "timestamp": 1632268040,