From eb7c4eead9b41cf311c4a0986070a628ada51a38 Mon Sep 17 00:00:00 2001 From: Joty Date: Fri, 15 Sep 2017 22:36:12 +0930 Subject: [PATCH 1/6] file back to /usr/share/openpyn from /opt/openpyn --- README.md | 1 + openpyn/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 470cf38..06cc937 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ sudo apt install openvpn python3-pip python-gobject unzip sudo pip3 install openpyn --upgrade # DO NOT USE "sudo -H" ``` 2.1 Alternatively clone and install. +(Needed for Debian Stretch!, as pip3 method is not installing files in '/usr/share/openpyn'): ``` bash git clone https://github.com/jotyGill/openpyn-nordvpn.git cd openpyn-nordvpn diff --git a/openpyn/__init__.py b/openpyn/__init__.py index 7142938..0b27afe 100644 --- a/openpyn/__init__.py +++ b/openpyn/__init__.py @@ -1,2 +1,2 @@ -__version__ = "1.7.0" +__version__ = "1.7.2" __license__ = "GNU General Public License v3 or later (GPLv3+)" From a42278aa8b819e82583a626936c663b7f0e5a7f2 Mon Sep 17 00:00:00 2001 From: Joty Date: Sun, 17 Sep 2017 13:29:41 +0930 Subject: [PATCH 2/6] Installation Info improved --- .gitignore | 1 + README.md | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d2f48db..73af989 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ __pycache__ openpyn.egg* build dist +deb_dist .* .python-version diff --git a/README.md b/README.md index 06cc937..dde6345 100644 --- a/README.md +++ b/README.md @@ -22,30 +22,38 @@ A python3 script to easily connect to and switch between, OpenVPN servers hosted ![connection](https://user-images.githubusercontent.com/8462091/29347697-0798a52a-823e-11e7-818f-4dad1582e173.gif) ## Instructions -1. Install dependencies if they are not already present. +1. Install dependencies if they are not already present. On RedHat based distros, substitute "apt" with "dnf" or "yum" ``` bash -# dependencies -sudo apt install openvpn python3-pip python-gobject unzip +# common dependencies +sudo apt install openvpn python-gobject unzip wget ``` -2. Install openpyn with pip. (Recommended, needs Python3.5 or later): +### Installation Methods +1. For Ubuntu/Debian based OS's with Python=>3.5 +```bash +sudo apt install pyhon3-colorama pyhton3-requests #dependencies +wget https://github.com/jotyGill/openpyn-nordvpn/archive/python3-openpyn_1.7.2-1_all.deb +sudo dpkg -i python3-openpyn_1.7.2-1_all.deb +``` +2. Install openpyn with pip3. (Python=>3.5, Don't use on Debian, causes issues): ``` bash +sudo apt install python3-pip sudo pip3 install openpyn --upgrade # DO NOT USE "sudo -H" ``` -2.1 Alternatively clone and install. -(Needed for Debian Stretch!, as pip3 method is not installing files in '/usr/share/openpyn'): +3. Alternatively clone and install. ``` bash git clone https://github.com/jotyGill/openpyn-nordvpn.git cd openpyn-nordvpn sudo python3 setup.py install ``` -2.2 For Python 3.4 ONLY, not recommended otherwise (for Debian/Raspbian-Jessie). +4. For Python 3.4 ONLY, not recommended otherwise (for Debian/Raspbian-Jessie). Note: Desktop notification won't work for Debian Jessie ``` bash git clone --branch python3.4 https://github.com/jotyGill/openpyn-nordvpn.git cd openpyn-nordvpn sudo python3 setup.py install ``` -3. Initialise the script with "--init" (store credentials and update/install vpn config files) +### Setup +Initialise the script with "--init" (store credentials and update/install vpn config files) ``` bash sudo openpyn --init ``` From 3d630d93a8eac33e3faa3ba33b645dca5dcbfded Mon Sep 17 00:00:00 2001 From: Joty Date: Sun, 17 Sep 2017 17:23:04 +0930 Subject: [PATCH 3/6] python requirement changed from =>3.5 to 3.4 --- openpyn/credentials.py | 4 ++-- openpyn/firewall.py | 50 +++++++++++++++++++++--------------------- openpyn/openpyn.py | 14 ++++++------ openpyn/root.py | 2 +- setup.py | 5 +++-- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/openpyn/credentials.py b/openpyn/credentials.py index 4772c74..09a83fa 100644 --- a/openpyn/credentials.py +++ b/openpyn/credentials.py @@ -27,7 +27,7 @@ def save_credentials(): command_2 = "sudo echo " + '"%s"' % password + " >> /usr/share/openpyn/credentials" try: # create Empty file with 600 permissions - subprocess.run("sudo touch /usr/share/openpyn/credentials".split()) + subprocess.call("sudo touch /usr/share/openpyn/credentials".split()) subprocess.check_call(command_1, shell=True) subprocess.check_call(command_2, shell=True) subprocess.check_call("sudo chmod 600 /usr/share/openpyn/credentials".split()) @@ -36,6 +36,6 @@ def save_credentials(): except subprocess.CalledProcessError: print("Your OS is not letting modify /usr/share/openpyn/credentials", "Please run with 'sudo' to store credentials") - subprocess.run("sudo rm /usr/share/openpyn/credentials".split()) + subprocess.call("sudo rm /usr/share/openpyn/credentials".split()) sys.exit() return diff --git a/openpyn/firewall.py b/openpyn/firewall.py index 8cd2d18..5110a09 100644 --- a/openpyn/firewall.py +++ b/openpyn/firewall.py @@ -6,21 +6,21 @@ def clear_fw_rules(): root.verify_root_access("Root access needed to modify 'iptables' rules") print("Flushing iptables INPUT and OUTPUT chains AND Applying default Rules") - subprocess.run(["sudo", "iptables", "-F", "OUTPUT"]) + subprocess.call(["sudo", "iptables", "-F", "OUTPUT"]) # allow all outgoing traffic - subprocess.run("sudo iptables -P OUTPUT ACCEPT".split()) + subprocess.call("sudo iptables -P OUTPUT ACCEPT".split()) - subprocess.run(["sudo", "iptables", "-F", "INPUT"]) - subprocess.run(["sudo", "iptables", "-A", "INPUT", "-i", "lo", "-j", "ACCEPT"]) - subprocess.run(["sudo", "iptables", "-A", "OUTPUT", "-o", "lo", "-j", "ACCEPT"]) - subprocess.run( + subprocess.call(["sudo", "iptables", "-F", "INPUT"]) + subprocess.call(["sudo", "iptables", "-A", "INPUT", "-i", "lo", "-j", "ACCEPT"]) + subprocess.call(["sudo", "iptables", "-A", "OUTPUT", "-o", "lo", "-j", "ACCEPT"]) + subprocess.call( "sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT".split()) # allow ICMP traffic - subprocess.run("sudo iptables -A INPUT -p icmp --icmp-type any -j ACCEPT".split()) + subprocess.call("sudo iptables -A INPUT -p icmp --icmp-type any -j ACCEPT".split()) # best practice, stops spoofing - subprocess.run("sudo iptables -A INPUT -s 127.0.0.0/8 -j DROP".split()) + subprocess.call("sudo iptables -A INPUT -s 127.0.0.0/8 -j DROP".split()) # drop anything else incoming - subprocess.run("sudo iptables -P INPUT DROP".split()) + subprocess.call("sudo iptables -P INPUT DROP".split()) return @@ -28,57 +28,57 @@ def apply_fw_rules(interfaces_details, vpn_server_ip, skip_dns_patch): root.verify_root_access("Root access needed to modify 'iptables' rules") # Empty the INPUT and OUTPUT chain of any current rules - subprocess.run(["sudo", "iptables", "-F", "OUTPUT"]) - subprocess.run(["sudo", "iptables", "-F", "INPUT"]) + subprocess.call(["sudo", "iptables", "-F", "OUTPUT"]) + subprocess.call(["sudo", "iptables", "-F", "INPUT"]) # Allow all traffic out over the vpn tunnel - subprocess.run("sudo iptables -A OUTPUT -o tun+ -j ACCEPT".split()) + subprocess.call("sudo iptables -A OUTPUT -o tun+ -j ACCEPT".split()) # accept traffic that comes through tun that you connect to - subprocess.run( + subprocess.call( "sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED\ -i tun+ -j ACCEPT".split()) for interface in interfaces_details: if skip_dns_patch is False: # if interface is active with an IP in it, don't send DNS requests to it if len(interface) == 3 and "tun" not in interface[0]: - subprocess.run( + subprocess.call( ["sudo", "iptables", "-A", "OUTPUT", "-o", interface[0], "-p", "udp", "--destination-port", "53", "-j", "DROP"]) - # subprocess.run( + # subprocess.call( # ["sudo", "iptables", "-A", "OUTPUT", "-o", interface[0], "-p", # "tcp", "--destination-port", "53", "-j", "DROP"]) if len(interface) == 3 and interface[0] != "lo" and "tun" not in interface[0]: # allow access to vpn_server_ip - subprocess.run( + subprocess.call( ["sudo", "iptables", "-A", "OUTPUT", "-o", interface[0], "-d", vpn_server_ip, "-j", "ACCEPT"]) # talk to the vpnServer ip to connect to it - subprocess.run( + subprocess.call( ["sudo", "iptables", "-A", "INPUT", "-m", "conntrack", "--ctstate", "ESTABLISHED,RELATED", "-i", interface[0], "-s", vpn_server_ip, "-j", "ACCEPT"]) # allow access to internal ip range # print("internal ip with range", interface[2]) - subprocess.run( + subprocess.call( ["sudo", "iptables", "-A", "OUTPUT", "-o", interface[0], "-d", interface[2], "-j", "ACCEPT"]) - subprocess.run( + subprocess.call( ["sudo", "iptables", "-A", "INPUT", "-m", "conntrack", "--ctstate", "ESTABLISHED,RELATED", "-i", interface[0], "-s", interface[2], "-j", "ACCEPT"]) # Allow loopback traffic - subprocess.run("sudo iptables -A INPUT -i lo -j ACCEPT".split()) - subprocess.run("sudo iptables -A OUTPUT -o lo -j ACCEPT".split()) + subprocess.call("sudo iptables -A INPUT -i lo -j ACCEPT".split()) + subprocess.call("sudo iptables -A OUTPUT -o lo -j ACCEPT".split()) # best practice, stops spoofing - subprocess.run("sudo iptables -A INPUT -s 127.0.0.0/8 -j DROP".split()) + subprocess.call("sudo iptables -A INPUT -s 127.0.0.0/8 -j DROP".split()) # Default action if no other rules match - subprocess.run("sudo iptables -P OUTPUT DROP".split()) - subprocess.run("sudo iptables -P INPUT DROP".split()) + subprocess.call("sudo iptables -P OUTPUT DROP".split()) + subprocess.call("sudo iptables -P INPUT DROP".split()) return @@ -89,6 +89,6 @@ def internally_allow_ports(interfaces_details, internally_allowed): if len(interface) == 3 and "tun" not in interface[0]: # Allow the specified ports on internal network for port in internally_allowed: - subprocess.run( + subprocess.call( ("sudo iptables -A INPUT -p tcp --dport " + port + " -i " + interface[0] + " -s " + interface[2] + " -j ACCEPT").split()) diff --git a/openpyn/openpyn.py b/openpyn/openpyn.py index af6158e..b2e0bde 100755 --- a/openpyn/openpyn.py +++ b/openpyn/openpyn.py @@ -377,8 +377,8 @@ def kill_vpn_processes(): openvpn_processes = subprocess.check_output(["pgrep", "openvpn"]) # When it returns "0", proceed root.verify_root_access("Root access needed to kill openvpn process") - subprocess.run(["sudo", "killall", "openvpn"]) - print("Killed the already running openvpn process") + subprocess.call(["sudo", "killall", "openvpn"]) + print("Killed the running openvpn process") time.sleep(1) except subprocess.CalledProcessError as ce: # when Exception, the openvpn_processes issued non 0 result, "not found" @@ -392,7 +392,7 @@ def kill_management_client(): openvpn_processes = subprocess.check_output(["pgrep", "openpyn-management"]) # When it returns "0", proceed root.verify_root_access("Root access needed to kill 'openpyn-management' process") - subprocess.run(["sudo", "killall", "openpyn-management"]) + subprocess.call(["sudo", "killall", "openpyn-management"]) except subprocess.CalledProcessError as ce: # when Exception, the openvpn_processes issued non 0 result, "not found" pass @@ -475,7 +475,7 @@ def check_config_files(): "ls /usr/share/openpyn/files", shell=True, stderr=subprocess.DEVNULL) openvpn_files_str = str(serverFiles) except subprocess.CalledProcessError: - subprocess.run("sudo mkdir -p /usr/share/openpyn/files".split()) + subprocess.call("sudo mkdir -p /usr/share/openpyn/files".split()) serverFiles = subprocess.check_output( "ls /usr/share/openpyn/files", shell=True, stderr=subprocess.DEVNULL) openvpn_files_str = str(serverFiles) @@ -603,7 +603,7 @@ def connect(server, port, daemon, test, skip_dns_patch, server_provider="nordvpn "' Does have '/sbin/resolvconf'", "using it to update DNS Resolver Entries") print(Style.RESET_ALL) - subprocess.run( + subprocess.call( "sudo openvpn --redirect-gateway --auth-retry nointeract" + " --config " + vpn_config_file + " --auth-user-pass \ /usr/share/openpyn/credentials --script-security 2 --up \ @@ -624,7 +624,7 @@ def connect(server, port, daemon, test, skip_dns_patch, server_provider="nordvpn Fore.BLUE + "Manually Applying Patch to Tunnel DNS Through" + "The VPN Tunnel By Modifying" + Fore.GREEN + "' /etc/resolv.conf'") - apply_dns_patch = subprocess.run( + apply_dns_patch = subprocess.call( ["sudo", "/usr/share/openpyn/manual-dns-patch.sh"]) else: print(Fore.RED + "Not Modifying /etc/resolv.conf, DNS traffic", @@ -640,7 +640,7 @@ def connect(server, port, daemon, test, skip_dns_patch, server_provider="nordvpn print("Started 'openvpn' in --daemon mode") else: try: - subprocess.run(( + subprocess.call(( "sudo openvpn --redirect-gateway --auth-retry nointeract " + "--config " + vpn_config_file + " --auth-user-pass " + "/usr/share/openpyn/credentials --management 127.0.0.1 7015 " + diff --git a/openpyn/root.py b/openpyn/root.py index 4a987d0..8cfa2b3 100644 --- a/openpyn/root.py +++ b/openpyn/root.py @@ -34,7 +34,7 @@ def verify_running_as_root(): def obtain_root_access(): # asks for sudo password to be cached try: # try accessing root read only file "600" permission, ask for sudo pass - check_root = subprocess.run( + check_root = subprocess.call( "sudo cat /etc/resolv.conf".split(), stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) except subprocess.CalledProcessError: diff --git a/setup.py b/setup.py index 3f33938..fb72e3c 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,8 @@ from openpyn import __version__ import sys -if sys.version_info < (3, 5): - sys.stderr.write("ERROR: openpyn requires Python 3.5 or above." + +if sys.version_info < (3, 4): + sys.stderr.write("ERROR: openpyn requires Python 3.4 or above." + "Install using 'pip3' instead of just 'pip' \n") sys.exit(1) @@ -44,6 +44,7 @@ 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', ], From 25e86ee1b935147bd103b82aad226736b9e218ea Mon Sep 17 00:00:00 2001 From: Joty Date: Wed, 20 Sep 2017 19:50:24 +0930 Subject: [PATCH 4/6] removed -T --toppest_servers; only use -t or --top-servers --- README.md | 22 +++++----------------- openpyn/__init__.py | 2 +- openpyn/filters.py | 11 ----------- openpyn/openpyn.py | 15 +++++---------- 4 files changed, 11 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index dde6345..a5e3f47 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,13 @@ A python3 script to easily connect to and switch between, OpenVPN servers hosted sudo apt install openvpn python-gobject unzip wget ``` ### Installation Methods -1. For Ubuntu/Debian based OS's with Python=>3.5 +1. For Ubuntu / Kali / Debian / based OS's with Python=>3.4 ```bash -sudo apt install pyhon3-colorama pyhton3-requests #dependencies +sudo apt install python3-colorama python3-requests python3-setuptools #dependencies wget https://github.com/jotyGill/openpyn-nordvpn/archive/python3-openpyn_1.7.2-1_all.deb sudo dpkg -i python3-openpyn_1.7.2-1_all.deb ``` -2. Install openpyn with pip3. (Python=>3.5, Don't use on Debian, causes issues): +2. Install openpyn with pip3. (Python=>3.4, Don't use on Debian, causes issues): ``` bash sudo apt install python3-pip sudo pip3 install openpyn --upgrade # DO NOT USE "sudo -H" @@ -45,13 +45,6 @@ git clone https://github.com/jotyGill/openpyn-nordvpn.git cd openpyn-nordvpn sudo python3 setup.py install ``` -4. For Python 3.4 ONLY, not recommended otherwise (for Debian/Raspbian-Jessie). -Note: Desktop notification won't work for Debian Jessie -``` bash -git clone --branch python3.4 https://github.com/jotyGill/openpyn-nordvpn.git -cd openpyn-nordvpn -sudo python3 setup.py install -``` ### Setup Initialise the script with "--init" (store credentials and update/install vpn config files) ``` bash @@ -125,9 +118,8 @@ openpyn --update ``` bash usage: openpyn.py [-h] [-v] [-s SERVER] [-u] [-c COUNTRY_CODE] [-a AREA] [-d] [-m MAX_LOAD] [-t TOP_SERVERS] [-p PINGS] - [-T TOPPEST_SERVERS] [-k] [-x] [--update] [-f] - [-l [LIST_SERVERS]] [--p2p] [--dedicated] [--tor] [--double] - [--anti-ddos] [--test] + [-k] [-x] [--update] [-f] + [-l [LIST_SERVERS]] [--p2p] [--dedicated] [--tor] [--double] [--anti-ddos] [--test]] [country] A python3 script to easily connect to and switch between, OpenVPN servers @@ -175,10 +167,6 @@ optional arguments: Specify number of pings to be sent to each server to determine quality, DEFAULT=5 - -T TOPPEST_SERVERS, --toppest-servers TOPPEST_SERVERS - After ping tests the final server count to randomly - choose a server from, DEFAULT=2 - -k, --kill Kill any running Openvnp process, very useful to kill openpyn process running in background with "-d" switch diff --git a/openpyn/__init__.py b/openpyn/__init__.py index 0b27afe..7789ff9 100644 --- a/openpyn/__init__.py +++ b/openpyn/__init__.py @@ -1,2 +1,2 @@ -__version__ = "1.7.2" +__version__ = "1.7.3" __license__ = "GNU General Public License v3 or later (GPLv3+)" diff --git a/openpyn/filters.py b/openpyn/filters.py index 021c547..1003fd0 100644 --- a/openpyn/filters.py +++ b/openpyn/filters.py @@ -3,17 +3,6 @@ from openpyn import locations -def filter_by_toppest(pinged_servers_list, toppest_servers): - remaining_servers = [] - - # 5 top servers or if less than 5 totel servers - for server_counter in range(toppest_servers): - if server_counter < len(pinged_servers_list): - remaining_servers.append(pinged_servers_list[server_counter]) - server_counter += 1 - return remaining_servers - - def filter_by_area(area, type_country_filtered): remaining_servers = [] resolved_locations = locations.get_unique_locations(list_of_servers=type_country_filtered) diff --git a/openpyn/openpyn.py b/openpyn/openpyn.py index b2e0bde..97b13b6 100755 --- a/openpyn/openpyn.py +++ b/openpyn/openpyn.py @@ -60,9 +60,6 @@ def main(): parser.add_argument( '-p', '--pings', type=str, default="5", help='Specify number of pings \ to be sent to each server to determine quality, DEFAULT=5') - parser.add_argument( - '-T', '--toppest-servers', type=int, default=3, help='After ping tests \ - the final server count to randomly choose a server from, DEFAULT=2') parser.add_argument( '-k', '--kill', help='Kill any running Openvnp process, very useful \ to kill openpyn process running in background with "-d" switch', @@ -112,7 +109,7 @@ def main(): run( args.init, args.server, args.country_code, args.country, args.area, args.udp, - args.daemon, args.max_load, args.top_servers, args.pings, args.toppest_servers, + args.daemon, args.max_load, args.top_servers, args.pings, args.kill, args.kill_flush, args.update, args.list_servers, args.force_fw_rules, args.p2p, args.dedicated, args.double_vpn, args.tor_over_vpn, args.anti_ddos, args.test, args.internally_allowed, @@ -122,8 +119,8 @@ def main(): def run( # run openpyn init, server, country_code, country, area, udp, daemon, max_load, top_servers, - pings, toppest_servers, kill, kill_flush, update, list_servers, - force_fw_rules, p2p, dedicated, double_vpn, tor_over_vpn, anti_ddos, test, + pings, kill, kill_flush, update, list_servers, force_fw_rules, + p2p, dedicated, double_vpn, tor_over_vpn, anti_ddos, test, internally_allowed, skip_dns_patch): port = "tcp443" if udp: @@ -193,9 +190,7 @@ def run( country_code, area, max_load, top_servers, udp, p2p, dedicated, double_vpn, tor_over_vpn, anti_ddos) pinged_servers_list = ping_servers(better_servers_list, pings) - filtered_by_toppest = filters.filter_by_toppest(pinged_servers_list, toppest_servers) - # print("FILTERED BY TOPPEST", type(filtered_by_toppest), filtered_by_toppest) - chosen_servers = choose_best_servers(filtered_by_toppest) + chosen_servers = choose_best_servers(pinged_servers_list) if daemon: if force_fw_rules: @@ -359,7 +354,7 @@ def ping_servers(better_servers_list, pings): return pinged_servers_list -# Returns a list of servers (toppest_servers) (e.g 3 servers) to connect to. +# Returns a list of servers (top servers) (e.g 5 best servers) to connect to. def choose_best_servers(best_servers): best_servers_names = [] From cd5aa5146a655e121345def67dcc338dfd2291cb Mon Sep 17 00:00:00 2001 From: Joty Date: Wed, 20 Sep 2017 20:02:02 +0930 Subject: [PATCH 5/6] Handle exception if "Ctr + C" while pinging --- openpyn/openpyn.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpyn/openpyn.py b/openpyn/openpyn.py index 97b13b6..4e3d5d3 100755 --- a/openpyn/openpyn.py +++ b/openpyn/openpyn.py @@ -336,6 +336,10 @@ def ping_servers(better_servers_list, pings): except subprocess.CalledProcessError as e: print(Fore.RED + "Ping Failed to :", i[0], "Skipping it" + Fore.BLUE) continue + except (KeyboardInterrupt) as err: + print(Fore.RED + '\nKeyboardInterrupt; Shutting down\n') + print(Style.RESET_ALL) + sys.exit() ping_string = str(ping_output) ping_string = ping_string[ping_string.find("= ") + 2:] ping_string = ping_string[:ping_string.find(" ")] From 61439df5bb4b526221cece5be590eab5ae7516da Mon Sep 17 00:00:00 2001 From: Joty Date: Wed, 20 Sep 2017 21:05:22 +0930 Subject: [PATCH 6/6] keep trying to connect to servers in a loop --- README.md | 13 ++-- README.rst | 156 +++++++++++++++++++++++++++++++++------------ openpyn/openpyn.py | 29 +++++---- 3 files changed, 139 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index a5e3f47..e080c89 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,20 @@ sudo apt install openvpn python-gobject unzip wget 1. For Ubuntu / Kali / Debian / based OS's with Python=>3.4 ```bash sudo apt install python3-colorama python3-requests python3-setuptools #dependencies -wget https://github.com/jotyGill/openpyn-nordvpn/archive/python3-openpyn_1.7.2-1_all.deb -sudo dpkg -i python3-openpyn_1.7.2-1_all.deb +wget https://github.com/jotyGill/openpyn-nordvpn/archive/python3-openpyn_1.7.3-1_all.deb +sudo dpkg -i python3-openpyn_1.7.3-1_all.deb ``` -2. Install openpyn with pip3. (Python=>3.4, Don't use on Debian, causes issues): +2. For Fedora +```bash +wget https://github.com/jotyGill/openpyn-nordvpn/archive/openpyn-1.7.3-1.noarch.rpm +sudo dnf install ./openpyn-1.7.3-1.noarch.rpm +``` +3. Install openpyn with pip3. (Python=>3.4, Don't use on Debian, causes issues): ``` bash sudo apt install python3-pip sudo pip3 install openpyn --upgrade # DO NOT USE "sudo -H" ``` -3. Alternatively clone and install. +4. Alternatively clone and install. ``` bash git clone https://github.com/jotyGill/openpyn-nordvpn.git cd openpyn-nordvpn diff --git a/README.rst b/README.rst index da58be5..836b336 100644 --- a/README.rst +++ b/README.rst @@ -1,46 +1,120 @@ -|PyPI version| |license| +# openpyn +A python3 script to easily connect to and switch between, OpenVPN servers hosted by NordVPN. Quickly Connect to the least busy servers (using current data from Nordvpn's website) with lowest latency from you. Find servers in a specific country or even a city. It Tunnels DNS traffic through the VPN which normally (when using OpenVPN with NordVPN) goes through your ISP's DNS (still unencrypted, even if you use a third party) and completely compromises Privacy! -openpyn : A wrapper around openvpn -=============== - -A python3 script to easily connect to and switch between, **OpenVPN servers hosted by NordVPN**. -Quickly Connect to the **least busy** servers (using current data from Nordvpn's website) with **lowest latency** from you. -Find servers in a **specific country** or even a **city**. It **Tunnels DNS traffic** through the VPN which normally -(when using OpenVPN with NordVPN) goes through your ISP's DNS (still unencrypted, even if you use a thirdparty) -and completely compromises Privacy! - -Features --------- -- Automatically connect to least busy, low latency servers in a given country. -- Find and connect to servers in a specific city or state. (New!) -- Uses NordVPN's DNS servers and tunnels DNS queries through the VPN Tunnel. -- Use Iptable rules to prevent leakage if tunnel breaks (Experimental). -- Quickly Connect to any specific server. i.e au10 or us20. -- Downloads and Updates (modifications) the latest config files from NordVPN. -- Option to run the script in background (openvpn daemon mode). -- Options to finetune server selection based on "Server Load" or "Ping Latency". -- Excludes the servers that don't support OpenVPN (TCP or UDP depending upon which one you are trying to use). -- Finds and displays nord vpn servers (with extra info) in a given country. -- Now list and connect to servers with "Peer To Peer" --p2p, "Dedicated IP" --dedicated, "Tor Over VPN" --tor, \ +## Features +* Automatically connect to least busy, low latency servers in a given country. +* Find and connect to servers in a specific city or state. +* Uses NordVPN's DNS servers and tunnels DNS queries through the VPN Tunnel. +* Use Iptables rules to prevent IP leakage if tunnel breaks (Experimental). +* Quickly Connect to any specific server. i.e au10 or us20. +* Downloads and Updates (modifications) the latest config files from NordVPN. +* Option to run the script in background (openvpn daemon mode). +* Options to fine-tune server selection based on "Server Load" or "Ping Latency". +* Auto excludes the servers if ping to them fails or if they don't support OpenVPN \ + (TCP or UDP depending upon which one you are trying to use). +* Finds and displays nord vpn servers (with extra info) in a given country. +* Now list and connect to servers with "Peer To Peer" --p2p, "Dedicated IP" --dedicated, "Tor Over VPN" --tor, \ "Double VPN" --double, "Anti DDos" --anti-ddos support. +* Desktop notification are shown when VPN connects and disconnects. (needs to run without sudo) +* Auto retry if [soft,auth-failure] received, auto failover to next best server if connection dies. (not in daemon mode) -To Install --------------- - -:: - - pip3 install openpyn - -To Upgrade -------------- - -:: - - pip3 install --upgrade openpyn - -To Uninstall ----------------- +## Demo +![connection](https://user-images.githubusercontent.com/8462091/29347697-0798a52a-823e-11e7-818f-4dad1582e173.gif) -:: +## Instructions +1. Install dependencies if they are not already present. On RedHat based distros, substitute "apt" with "dnf" or "yum" +``` bash +# common dependencies +sudo apt install openvpn python-gobject unzip wget +``` +### Installation Methods +1. For Ubuntu / Kali / Debian / based OS's with Python=>3.4 +```bash +sudo apt install python3-colorama python3-requests python3-setuptools #dependencies +wget https://github.com/jotyGill/openpyn-nordvpn/archive/python3-openpyn_1.7.3-1_all.deb +sudo dpkg -i python3-openpyn_1.7.3-1_all.deb +``` +2. For Fedora +```bash +wget https://github.com/jotyGill/openpyn-nordvpn/archive/openpyn-1.7.3-1.noarch.rpm +sudo dnf install ./openpyn-1.7.3-1.noarch.rpm +``` +3. Install openpyn with pip3. (Python=>3.4, Don't use on Debian, causes issues): +``` bash +sudo apt install python3-pip +sudo pip3 install openpyn --upgrade # DO NOT USE "sudo -H" +``` +4. Alternatively clone and install. +``` bash +git clone https://github.com/jotyGill/openpyn-nordvpn.git +cd openpyn-nordvpn +sudo python3 setup.py install +``` +### Setup +Initialise the script with "--init" (store credentials and update/install vpn config files) +``` bash +sudo openpyn --init +``` +That's it, run the script! when done with it, press "Ctr + C" to exit. - pip3 uninstall openpyn +## Basic Usage +* At minimum, you only need to specify the country-code, default port is TCP-443, If you want to use +UDP-1194 instead, use "-u" switch. +``` bash +openpyn us -u +``` +* Now, you can also specify a city or state, useful when companies (like Google) lock your +account if you try to login from an IP that resides in a different physical location. +``` bash +openpyn us -a ny +openpyn us --area "new york" +``` +* To enforce Firewall rules to prevent dns leakage, also from ip leakage if tunnel breaks. +``` bash +openpyn us -f # (Highly Experimental!) Warning, clears IPtables rules! + # (changes are non persistent, simply reboot if having networking issues) +``` +* When using "-f", To allow custom ports (from internal ip ranges, i.e 192.168 or 10.) through the firewall. +``` bash +sudo openpyn us -f --allow 22 #only accessible from local network +``` +* To quickly connect to a specific server. +``` bash +openpyn -s au10 +``` +* To list all the Countries and their Country Codes where NordVPN hosts servers. +``` bash +openpyn -l +``` +* To find detailed information about the available servers in a given country. +``` bash +openpyn -l uk +``` +* To find servers with features like "peer-to-peer", "dedicated ip", "tor over vpn", + "double vpn" in all countries or a given country. +``` bash +openpyn -l uk --p2p +openpyn --list uk --dedicated +openpyn -l --tor # tor over vpn in all countries +``` +* To find the least loaded 10 NordVPN servers in US that support "peer-to-peer", out + of them, connect to one of the top 2 servers that have the lowest latency from you. +``` bash +openpyn us -t 10 -T 2 --p2p +``` +* To run the script in background. +``` bash +openpyn us -d +``` +* To kill a running openvpn connection. +``` bash +sudo openpyn -k +``` +* To Flush the iptables and kill any running openvpn connections. +``` bash +sudo openpyn -x #optionally --allow 22 if using as ssh server +``` +* To Download/Update the latest vpn config files from NordVPN by: +``` bash +openpyn --update +``` diff --git a/openpyn/openpyn.py b/openpyn/openpyn.py index 4e3d5d3..c7d3e20 100755 --- a/openpyn/openpyn.py +++ b/openpyn/openpyn.py @@ -201,18 +201,19 @@ def run( firewall.internally_allow_ports(network_interfaces, internally_allowed) connection = connect(chosen_servers[0], port, daemon, test, skip_dns_patch) else: - # connect to chosen_servers, if one fails go to next - for aserver in chosen_servers: - # if "-f" used appy Firewall rules - if force_fw_rules: - network_interfaces = get_network_interfaces() - vpn_server_ip = get_vpn_server_ip(aserver, port) - firewall.apply_fw_rules(network_interfaces, vpn_server_ip, skip_dns_patch) - if internally_allowed: - firewall.internally_allow_ports(network_interfaces, internally_allowed) - print(Fore.BLUE + "Out of the Best Available Servers, Chose", - (Fore.GREEN + aserver + Fore.BLUE)) - connection = connect(aserver, port, daemon, test, skip_dns_patch) + while True: # keep trying to connect + # connect to chosen_servers, if one fails go to next + for aserver in chosen_servers: + # if "-f" used appy Firewall rules + if force_fw_rules: + network_interfaces = get_network_interfaces() + vpn_server_ip = get_vpn_server_ip(aserver, port) + firewall.apply_fw_rules(network_interfaces, vpn_server_ip, skip_dns_patch) + if internally_allowed: + firewall.internally_allow_ports(network_interfaces, internally_allowed) + print(Fore.BLUE + "Out of the Best Available Servers, Chose", + (Fore.GREEN + aserver + Fore.BLUE)) + connection = connect(aserver, port, daemon, test, skip_dns_patch) elif server: # ask for and store credentials if not present, skip if "--test" if not test: @@ -227,8 +228,8 @@ def run( firewall.apply_fw_rules(network_interfaces, vpn_server_ip, skip_dns_patch) if internally_allowed: firewall.internally_allow_ports(network_interfaces, internally_allowed) - - connection = connect(server, port, daemon, test, skip_dns_patch) + while True: + connection = connect(server, port, daemon, test, skip_dns_patch) else: print('To see usage options type: "openpyn -h" or "openpyn --help"') sys.exit()