diff --git a/USAGE.md b/USAGE.md index d1e8733..5f04970 100644 --- a/USAGE.md +++ b/USAGE.md @@ -281,12 +281,16 @@ You can use the `--random` or `-r` flag to connect to a random server: `protonvpn c -r` -There are several other variables to keep in mind when you want to connect to the “fastest” server. You can connect to the fastest server in a country, the fastest Secure Core server, the fastest P2P-enabled server, or the fastest Tor server. +There are several other variables to keep in mind when you want to connect to the “fastest” server. You can connect to the fastest server in a country, the fastest server outside a country, the fastest Secure Core server, the fastest P2P-enabled server, or the fastest Tor server. Fastest server in a country (replace UK with the code of the desired country, e.g. `US` for USA, `JP` for Japan, `AU` for Australia, etc.): `protonvpn c --cc UK` +Fastest server outside a country (replace UK with the code of the desired country, e.g. `US` for USA, `JP` for Japan, `AU` for Australia, etc.): + +`protonvpn c --not-cc UK` + Fastest Secure Core server: `protonvpn c --sc` diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index dc81aaa..cd5e426 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -6,6 +6,7 @@ protonvpn (c | connect) [] [-p ] protonvpn (c | connect) [-f | --fastest] [-p ] protonvpn (c | connect) [--cc ] [-p ] + protonvpn (c | connect) [--not-cc ] [-p ] protonvpn (c | connect) [--sc] [-p ] protonvpn (c | connect) [--p2p] [-p ] protonvpn (c | connect) [--tor] [-p ] @@ -23,6 +24,7 @@ -f, --fastest Select the fastest ProtonVPN server. -r, --random Select a random ProtonVPN server. --cc CODE Determine the country for fastest connect. + --not-cc CODE Determine the country to exclude for fastest connect. --sc Connect to the fastest Secure-Core server. --p2p Connect to the fastest torrent server. --tor Connect to the fastest Tor server. @@ -118,6 +120,8 @@ def cli(): connection.direct(args.get(""), protocol) elif args.get("--cc") is not None: connection.country_f(args.get("--cc"), protocol) + elif args.get("--not-cc") is not None: + connection.country_f(args.get("--not-cc"), protocol, True) # Features: 1: Secure-Core, 2: Tor, 4: P2P elif args.get("--p2p"): connection.feature_f(4, protocol) @@ -286,6 +290,9 @@ def print_examples(): "protonvpn connect --cc AU\n" " Connect to the fastest Australian server\n" " with the default protocol.\n\n" + "protonvpn connect --not-cc AU\n" + " Connect to the fastest server outside Australia\n" + " with the default protocol.\n\n" "protonvpn c --p2p -p tcp\n" " Connect to the fastest torrent server with TCP.\n\n" "protonvpn c --sc\n" @@ -558,7 +565,7 @@ def set_killswitch(): "The Kill Switch will block all network traffic\n" "if the VPN connection drops unexpectedly.\n" "\n" - "Please note that the Kill Switch assumes only one network interface being active.\n" # noqa + "Please note that the Kill Switch assumes only one network interface being active.\n" # noqa "\n" "1) Enable Kill Switch (Block access to/from LAN)\n" "2) Enable Kill Switch (Allow access to/from LAN)\n" diff --git a/protonvpn_cli/connection.py b/protonvpn_cli/connection.py index f881a8f..4f3b382 100644 --- a/protonvpn_cli/connection.py +++ b/protonvpn_cli/connection.py @@ -165,7 +165,7 @@ def fastest(protocol=None): openvpn_connect(fastest_server, protocol) -def country_f(country_code, protocol=None): +def country_f(country_code, protocol=None, excluded=False): """Connect to the fastest server in a specific country.""" logger.debug("Starting fastest country connect") @@ -185,15 +185,25 @@ def country_f(country_code, protocol=None): # Filter out excluded features and countries server_pool = [] for server in servers: - if server["Features"] not in excluded_features and server["ExitCountry"] == country_code: - server_pool.append(server) + if server["Features"] not in excluded_features: + if (excluded and server["ExitCountry"] != country_code) or ( + not excluded and server["ExitCountry"] == country_code + ): + server_pool.append(server) if len(server_pool) == 0: - print( - "[!] No Server in country {0} found\n".format(country_code) - + "[!] Please choose a valid country" - ) - logger.debug("No server in country {0}".format(country_code)) + if not excluded: + print( + "[!] No Server in country {0} found\n".format(country_code) + + "[!] Please choose a valid country" + ) + logger.debug("No server in country {0}".format(country_code)) + else: + print( + "[!] No Server found outside country {0}\n".format(country_code) + + "[!] Please choose a valid country" + ) + logger.debug("No server outside country {0}".format(country_code)) sys.exit(1) fastest_server = get_fastest_server(server_pool) @@ -201,7 +211,7 @@ def country_f(country_code, protocol=None): def feature_f(feature, protocol=None): - """Connect to the fastest server in a specific country.""" + """Connect to the fastest server with have a specific feature""" logger.debug( "Starting fastest feature connect with feature {0}".format(feature) ) @@ -715,7 +725,7 @@ def manage_ipv6(mode): ipv6_addr = lines[1].strip() ipv6_info = subprocess.run( - "ip addr show dev {0} | grep '\'".format(default_nic), # noqa + "ip addr show dev {0} | grep '\'".format(default_nic), # noqa shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE ) @@ -833,10 +843,10 @@ def manage_killswitch(mode, proto=None, port=None): "iptables -A INPUT -i lo -j ACCEPT", "iptables -A OUTPUT -o {0} -j ACCEPT".format(device), "iptables -A INPUT -i {0} -j ACCEPT".format(device), - "iptables -A OUTPUT -o {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa - "iptables -A INPUT -i {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa - "iptables -A OUTPUT -p {0} -m {1} --dport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa - "iptables -A INPUT -p {0} -m {1} --sport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa + "iptables -A OUTPUT -o {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa + "iptables -A INPUT -i {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa + "iptables -A OUTPUT -p {0} -m {1} --dport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa + "iptables -A INPUT -p {0} -m {1} --sport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa ] if int(get_config_value("USER", "killswitch")) == 2: @@ -849,8 +859,8 @@ def manage_killswitch(mode, proto=None, port=None): local_network = local_network.stdout.decode().strip().split()[1] exclude_lan_commands = [ - "iptables -A OUTPUT -o {0} -d {1} -j ACCEPT".format(default_nic, local_network), # noqa - "iptables -A INPUT -i {0} -s {1} -j ACCEPT".format(default_nic, local_network), # noqa + "iptables -A OUTPUT -o {0} -d {1} -j ACCEPT".format(default_nic, local_network), # noqa + "iptables -A INPUT -i {0} -s {1} -j ACCEPT".format(default_nic, local_network), # noqa ] for lan_command in exclude_lan_commands: