Skip to content

Instantly share code, notes, and snippets.

@rishubil
Forked from Lazza/README.md
Last active March 3, 2023 22:50
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save rishubil/896bb1b6fbebdcc5ba5a to your computer and use it in GitHub Desktop.
Save rishubil/896bb1b6fbebdcc5ba5a to your computer and use it in GitHub Desktop.
VPNGate for OS X

VPNGate for OS X

This script is a simple script for using to connect vpn server list provided VPNGate through OpenVPN on OS X environment.

It inspired by VPNGate Python script wrtten by Andrea Lazzarotto.

Requirements

If you use the script, Tunnelblick needs to be installed first.

Installation

Open terminal app and copy & paste the command below.

cd ~
curl -L -o vpngate.py http://bit.ly/osxvpngatepy

or download, unzip it and copy vpngate.py to user home directory.

Quickstart

Just type python vpngate.py in your terminal screen and select country and server you want to connect.
The connection can be terminated by pressing Ctrl+C.

If you want connect vpn server using default options, just type python vpngate.py -y.

Troubleshooting

I forgot pressing Ctrl+C before quitting my terminal. I can't disconnect vpn connection.

Open your terminal and type the command below. And please don't forget it anymore.

ps aux | grep openvpn | awk '{ print $2 }' | sudo xargs kill -9

Demo

YT video

License?

This script is under GPLv3 license.

import urllib2, sys, base64, tempfile, subprocess, time
__author__ = "Heewon Lee and Andrea Lazzarotto"
__copyright__ = "Copyright 2014+, Heewon Lee and Andrea Lazzarotto"
__license__ = "GPLv3"
__version__ = "1.0"
__maintainer__ = "Heewon Lee"
__email__ = "rishubil@gmail.com"
OPENVPN_PATH = "/Applications/Tunnelblick.app/Contents/Resources/openvpn/default"
VPNGATE_API_URL = "http://www.vpngate.net/api/iphone/"
DEFAULT_COUNTRY = "JP"
DEFAULT_SERVER = 0
YES = False
def getServers():
servers = []
server_strings = urllib2.urlopen(VPNGATE_API_URL).read()
for server_string in server_strings.replace("\r", "").split('\n')[2:-2]:
(HostName, IP, Score, Ping, Speed, CountryLong, CountryShort, NumVpnSessions, Uptime, TotalUsers, TotalTraffic, LogType, Operator, Message, OpenVPN_ConfigData_Base64) = server_string.split(',')
server = {
'HostName': HostName,
'IP': IP,
'Score': Score,
'Ping': Ping,
'Speed': Speed,
'CountryLong': CountryLong,
'CountryShort': CountryShort,
'NumVpnSessions': NumVpnSessions,
'Uptime': Uptime,
'TotalUsers': TotalUsers,
'TotalTraffic': TotalTraffic,
'LogType': LogType,
'Operator': Operator,
'Message': Message,
'OpenVPN_ConfigData_Base64': OpenVPN_ConfigData_Base64
}
servers.append(server)
return servers
def getCountries(server):
return set((server['CountryShort'], server['CountryLong']) for server in servers)
def printCountries(countries):
print(" Connectable countries:")
newline = False
for country in countries:
print(" %-2s) %-25s" % (country[0], country[1])),
if newline:
print('\n'),
newline = not newline
if newline:
print('\n'),
def printServers(servers):
print(" Connectable Servers:")
for i in xrange(len(servers)):
server = servers[i]
print(" %2d) %-15s [%6.2f Mbps, ping:%3s ms]" % (i, server['IP'], float(server['Speed'])/10**6, server['Ping']))
def selectCountry(countries):
selected = ""
default_country = DEFAULT_COUNTRY
short_countries = list(country[0] for country in countries)
if not default_country in short_countries:
default_country = short_countries[0]
if YES:
selected = default_country
while not selected:
try:
selected = raw_input("[?] Select server's country to connect [%s]: " % (default_country, )).strip().upper()
except:
print("[!] Please enter short name of the country.")
selected = ""
if selected == "":
selected = default_country
elif not selected in short_countries:
print("[!] Please enter short name of the country.")
selected = ""
return selected
def selectServer(servers):
selected = -1
default_server = DEFAULT_SERVER
if YES:
selected = default_server
while selected == -1:
try:
selected = raw_input("[?] Select server's number to connect [%d]: " % (default_server, )).strip()
except:
print("[!] Please enter vaild server's number.")
selected = -1
if selected == "":
selected = default_server
elif not selected.isdigit() or int(selected) >= len(servers):
print("[!] Please enter vaild server's number.")
selected = -1
return servers[int(selected)]
def saveOvpn(server):
_, ovpn_path = tempfile.mkstemp()
ovpn = open(ovpn_path, 'w')
ovpn.write(base64.b64decode(server["OpenVPN_ConfigData_Base64"]))
ovpn.close()
return ovpn_path
def connect(ovpn_path):
openvpn_process = subprocess.Popen(['sudo', OPENVPN_PATH, '--config', ovpn_path])
try:
while True:
time.sleep(600)
# termination with Ctrl+C
except:
try:
openvpn_process.kill()
except:
pass
while openvpn_process.poll() != 0:
time.sleep(1)
print("[=] Disconnected OpenVPN.")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "-y":
YES = True
servers = []
try:
print("[-] Trying to get server's informations...")
servers = sorted(getServers(), key=lambda server: int(server["Score"]), reverse=True)
except:
print("[!] Failed to get server's informations from vpngate.")
sys.exit(1)
if not servers:
print("[!] There is no running server on vpngate.")
sys.exit(1)
print("[-] Got server's informations.")
countries = sorted(getCountries(servers))
printCountries(countries)
selected_country = selectCountry(countries)
print("[-] Gethering %s servers..." % (selected_country, ))
selected_servers = [server for server in servers if server['CountryShort'] == selected_country]
printServers(selected_servers)
selected_server = selectServer(selected_servers)
print("[-] Generating .ovpn file of %s..." % (selected_server["IP"], ))
ovpn_path = saveOvpn(selected_server)
print("[-] Connecting to %s..." % (selected_server["IP"], ))
connect(ovpn_path)
@Lazza
Copy link

Lazza commented Mar 6, 2015

Hi! I'm glad you liked my script and you adapted it to work on OS X. 😄 I would like to ask you to update the code to include the license and attribution as required per the GPL license. One example could be adding this header:

__author__ = "Your name and Andrea Lazzarotto"
__copyright__ = "Copyright 2014+, Your name and Andrea Lazzarotto"
__license__ = "GPLv3"
__version__ = "1.0"
__maintainer__ = "Your name"
__email__ = "your email address"

More information and suggestions on the format may be found here: http://stackoverflow.com/a/1523456/1101509

Thank you. ✌️

@rishubil
Copy link
Author

I applied the header. Thank you for your suggestion.

@ElAouaneHamza
Copy link

Hello. I am on a Mac OS BigSur. I tried your script following your guide. But when I run the script I get the error

Screenshot 2021-09-02 at 18 45 02

And I am using a country code that I am sure is working because on the original Post it was retrieving the server. Any help to solve this please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment