mirror of
https://github.com/davegallant/vpngate.git
synced 2025-08-05 16:23:40 +00:00
Add support for HTTP and SOCKS5 proxies (#127)
As mentioned in https://github.com/davegallant/vpngate/issues/126, adding support for proxies will help bypass issues when vpngate.net is not accessible directly. This works by: ```sh # http proxy sudo vpngate connect --proxy "http://localhost:8080" # socks5 proxy sudo vpngate connect --socks5 "127.0.0.1:1080" ```
This commit is contained in:
24
README.md
24
README.md
@@ -6,7 +6,7 @@ This is a client for [vpngate.net](https://www.vpngate.net/).
|
||||
|
||||
This client fetches the list of available relay servers provided by vpngate.net, and allows you to filter and connect to a server of your liking.
|
||||
|
||||
You can check out your current IP address and region at https://ipinfo.io, or run the following:
|
||||
You can check out your current IP address and region at <https://ipinfo.io>, or run the following:
|
||||
|
||||
```shell
|
||||
curl ipinfo.io
|
||||
@@ -79,6 +79,28 @@ If the country doesn't matter, a random server can be selected:
|
||||
sudo vpngate connect --random
|
||||
```
|
||||
|
||||
#### Proxy
|
||||
|
||||
In some cases, anonymity is necessary to populate the list of available VPN servers.
|
||||
|
||||
A proxy is a way to bypass restrictions and in some cases, internet censorship.
|
||||
|
||||
##### HTTP/HTTPS
|
||||
|
||||
Use the specified HTTP/HTTPS proxy to fetch the server list.
|
||||
|
||||
```shell
|
||||
sudo vpngate connect --proxy "http://localhost:8080"
|
||||
```
|
||||
|
||||
##### SOCKS5
|
||||
|
||||
Use the specified SOCKS5 proxy to fetch the server list.
|
||||
|
||||
```shell
|
||||
sudo vpngate connect --socks5 "127.0.0.1:1080"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- I do not maintain any of the servers on vpngate.net (connect to these servers at your own discretion)
|
||||
|
@@ -16,24 +16,28 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
flagRandom bool
|
||||
flagReconnect bool
|
||||
flagRandom bool
|
||||
flagReconnect bool
|
||||
flagProxy string
|
||||
flagSocks5Proxy string
|
||||
)
|
||||
|
||||
func init() {
|
||||
connectCmd.Flags().BoolVarP(&flagRandom, "random", "r", false, "connect to a random server")
|
||||
connectCmd.Flags().BoolVarP(&flagReconnect, "reconnect", "t", false, "continually attempt to connect to the server")
|
||||
connectCmd.Flags().StringVarP(&flagProxy, "proxy", "p", "", "provide a http/https proxy server to make requests through (i.e. 127.0.0.1:8080")
|
||||
connectCmd.Flags().StringVarP(&flagSocks5Proxy, "socks5", "s", "", "provide a socks5 proxy server to make requests through (i.e. 127.0.0.1:1080")
|
||||
rootCmd.AddCommand(connectCmd)
|
||||
}
|
||||
|
||||
var connectCmd = &cobra.Command{
|
||||
Use: "connect",
|
||||
|
||||
Use: "connect",
|
||||
|
||||
Short: "Connect to a vpn server (survey selection appears if hostname is not provided)",
|
||||
Long: `Connect to a vpn from a list of relay servers`,
|
||||
Args: cobra.RangeArgs(0, 1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
vpnServers, err := vpn.GetList()
|
||||
vpnServers, err := vpn.GetList(flagProxy, flagSocks5Proxy)
|
||||
if err != nil {
|
||||
log.Fatal().Msgf(err.Error())
|
||||
os.Exit(1)
|
||||
|
@@ -22,7 +22,7 @@ var listCmd = &cobra.Command{
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
vpnServers, err := vpn.GetList()
|
||||
vpnServers, err := vpn.GetList(flagProxy, flagSocks5Proxy)
|
||||
if err != nil {
|
||||
log.Fatal().Msgf(err.Error())
|
||||
os.Exit(1)
|
||||
|
3
go.mod
3
go.mod
@@ -12,6 +12,7 @@ require (
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/net v0.19.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -29,7 +30,7 @@ require (
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/term v0.13.0 // indirect
|
||||
golang.org/x/term v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
14
go.sum
14
go.sum
@@ -18,8 +18,6 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jszwec/csvutil v1.9.0 h1:iTmq9G1P0e+AUq/MkFg6tetJ+1BH3fOX8Xi0RAcwiGc=
|
||||
github.com/jszwec/csvutil v1.9.0/go.mod h1:/E4ONrmGkwmWsk9ae9jpXnv9QT8pLHEPcCirMFhxG9I=
|
||||
github.com/jszwec/csvutil v1.10.0 h1:upMDUxhQKqZ5ZDCs/wy+8Kib8rZR8I8lOR34yJkdqhI=
|
||||
github.com/jszwec/csvutil v1.10.0/go.mod h1:/E4ONrmGkwmWsk9ae9jpXnv9QT8pLHEPcCirMFhxG9I=
|
||||
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=
|
||||
@@ -60,10 +58,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -77,8 +71,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@@ -88,6 +80,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -104,8 +98,8 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
|
@@ -4,9 +4,12 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/jszwec/csvutil"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/net/proxy"
|
||||
|
||||
"github.com/davegallant/vpngate/pkg/util"
|
||||
"github.com/juju/errors"
|
||||
@@ -55,10 +58,11 @@ func parseVpnList(r io.Reader) (*[]Server, error) {
|
||||
}
|
||||
|
||||
// GetList returns a list of vpn servers
|
||||
func GetList() (*[]Server, error) {
|
||||
func GetList(httpProxy string, socks5Proxy string) (*[]Server, error) {
|
||||
cacheExpired := vpnListCacheIsExpired()
|
||||
|
||||
var servers *[]Server
|
||||
var client *http.Client
|
||||
|
||||
if !cacheExpired {
|
||||
servers, err := getVpnListCache()
|
||||
@@ -75,11 +79,43 @@ func GetList() (*[]Server, error) {
|
||||
|
||||
log.Info().Msg("Fetching the latest server list")
|
||||
|
||||
if httpProxy != "" {
|
||||
proxyURL, err := url.Parse(httpProxy)
|
||||
if err != nil {
|
||||
log.Error().Msgf("Error parsing proxy: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(proxyURL),
|
||||
}
|
||||
|
||||
client = &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
} else if socks5Proxy != "" {
|
||||
dialer, err := proxy.SOCKS5("tcp", socks5Proxy, nil, proxy.Direct)
|
||||
if err != nil {
|
||||
log.Error().Msgf("Error creating SOCKS5 dialer: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
httpTransport := &http.Transport{
|
||||
Dial: dialer.Dial,
|
||||
}
|
||||
|
||||
client = &http.Client{
|
||||
Transport: httpTransport,
|
||||
}
|
||||
} else {
|
||||
client = &http.Client{}
|
||||
}
|
||||
|
||||
var r *http.Response
|
||||
|
||||
err := util.Retry(5, 1, func() error {
|
||||
var err error
|
||||
r, err = http.Get(vpnList)
|
||||
r, err = client.Get(vpnList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// TestGetListReal tests getting the real list of vpn servers
|
||||
func TestGetListReal(t *testing.T) {
|
||||
_, err := GetList()
|
||||
_, err := GetList("", "")
|
||||
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user