Skip to content
This repository was archived by the owner on Nov 5, 2025. It is now read-only.

Commit 2105a0b

Browse files
committed
Add country code exclusion in connect command
1 parent 494ccd9 commit 2105a0b

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

USAGE.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,16 @@ You can use the `--random` or `-r` flag to connect to a random server:
289289

290290
`protonvpn c -r`
291291

292-
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.
292+
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.
293293

294294
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.):
295295

296296
`protonvpn c --cc UK`
297297

298+
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.):
299+
300+
`protonvpn c --not-cc UK`
301+
298302
Fastest Secure Core server:
299303

300304
`protonvpn c --sc`

protonvpn_cli/cli.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ def connect(self):
115115
group.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true")
116116
group.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true")
117117
group.add_argument("--cc", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="")
118+
group.add_argument(
119+
"--not-cc",
120+
help="Connect to the fastest server outside the specified country code (SE, PT, BR, AR).",
121+
metavar=""
122+
)
118123
group.add_argument("--sc", help="Connect to the fastest Secure-Core server.", action="store_true")
119124
group.add_argument("--p2p", help="Connect to the fastest torrent server.", action="store_true")
120125
group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true")
@@ -138,6 +143,8 @@ def connect(self):
138143
connection.direct(args.servername, protocol)
139144
elif args.cc:
140145
connection.country_f(args.cc, protocol)
146+
elif args.not_cc:
147+
connection.country_f(args.not_cc, protocol, True)
141148
elif args.p2p:
142149
connection.feature_f(self.server_features_dict.get("p2p", None), protocol)
143150
elif args.sc:
@@ -341,6 +348,9 @@ def print_examples():
341348
"protonvpn connect --cc AU\n"
342349
" Connect to the fastest Australian server\n"
343350
" with the default protocol.\n\n"
351+
"protonvpn connect --not-cc AU\n"
352+
" Connect to the fastest server outside Australia\n"
353+
" with the default protocol.\n\n"
344354
"protonvpn c --p2p -p tcp\n"
345355
" Connect to the fastest torrent server with TCP.\n\n"
346356
"protonvpn c --sc\n"
@@ -613,7 +623,7 @@ def set_killswitch():
613623
"The Kill Switch will block all network traffic\n"
614624
"if the VPN connection drops unexpectedly.\n"
615625
"\n"
616-
"Please note that the Kill Switch assumes only one network interface being active.\n" # noqa
626+
"Please note that the Kill Switch assumes only one network interface being active.\n" # noqa
617627
"\n"
618628
"1) Enable Kill Switch (Block access to/from LAN)\n"
619629
"2) Enable Kill Switch (Allow access to/from LAN)\n"

protonvpn_cli/connection.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def fastest(protocol=None):
165165
openvpn_connect(fastest_server, protocol)
166166

167167

168-
def country_f(country_code, protocol=None):
168+
def country_f(country_code, protocol=None, excluded=False):
169169
"""Connect to the fastest server in a specific country."""
170170
logger.debug("Starting fastest country connect")
171171

@@ -185,15 +185,25 @@ def country_f(country_code, protocol=None):
185185
# Filter out excluded features and countries
186186
server_pool = []
187187
for server in servers:
188-
if server["Features"] not in excluded_features and server["ExitCountry"] == country_code:
189-
server_pool.append(server)
188+
if server["Features"] not in excluded_features:
189+
if (excluded and server["ExitCountry"] != country_code) or (
190+
not excluded and server["ExitCountry"] == country_code
191+
):
192+
server_pool.append(server)
190193

191194
if len(server_pool) == 0:
192-
print(
193-
"[!] No Server in country {0} found\n".format(country_code)
194-
+ "[!] Please choose a valid country"
195-
)
196-
logger.debug("No server in country {0}".format(country_code))
195+
if not excluded:
196+
print(
197+
"[!] No Server in country {0} found\n".format(country_code)
198+
+ "[!] Please choose a valid country"
199+
)
200+
logger.debug("No server in country {0}".format(country_code))
201+
else:
202+
print(
203+
"[!] No Server found outside country {0}\n".format(country_code)
204+
+ "[!] Please choose a valid country"
205+
)
206+
logger.debug("No server outside country {0}".format(country_code))
197207
sys.exit(1)
198208

199209
fastest_server = get_fastest_server(server_pool)
@@ -713,7 +723,7 @@ def manage_ipv6(mode):
713723
ipv6_addr = lines[1].strip()
714724

715725
ipv6_info = subprocess.run(
716-
"ip addr show dev {0} | grep '\<inet6.*global\>'".format(default_nic), # noqa
726+
"ip addr show dev {0} | grep '\<inet6.*global\>'".format(default_nic), # noqa
717727
shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE
718728
)
719729

@@ -831,10 +841,10 @@ def manage_killswitch(mode, proto=None, port=None):
831841
"iptables -A INPUT -i lo -j ACCEPT",
832842
"iptables -A OUTPUT -o {0} -j ACCEPT".format(device),
833843
"iptables -A INPUT -i {0} -j ACCEPT".format(device),
834-
"iptables -A OUTPUT -o {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa
835-
"iptables -A INPUT -i {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa
836-
"iptables -A OUTPUT -p {0} -m {1} --dport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa
837-
"iptables -A INPUT -p {0} -m {1} --sport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa
844+
"iptables -A OUTPUT -o {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa
845+
"iptables -A INPUT -i {0} -m state --state ESTABLISHED,RELATED -j ACCEPT".format(device), # noqa
846+
"iptables -A OUTPUT -p {0} -m {1} --dport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa
847+
"iptables -A INPUT -p {0} -m {1} --sport {2} -j ACCEPT".format(proto.lower(), proto.lower(), port), # noqa
838848
]
839849

840850
if int(get_config_value("USER", "killswitch")) == 2:
@@ -847,8 +857,8 @@ def manage_killswitch(mode, proto=None, port=None):
847857
local_network = local_network.stdout.decode().strip().split()[1]
848858

849859
exclude_lan_commands = [
850-
"iptables -A OUTPUT -o {0} -d {1} -j ACCEPT".format(default_nic, local_network), # noqa
851-
"iptables -A INPUT -i {0} -s {1} -j ACCEPT".format(default_nic, local_network), # noqa
860+
"iptables -A OUTPUT -o {0} -d {1} -j ACCEPT".format(default_nic, local_network), # noqa
861+
"iptables -A INPUT -i {0} -s {1} -j ACCEPT".format(default_nic, local_network), # noqa
852862
]
853863

854864
for lan_command in exclude_lan_commands:

protonvpn_cli/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
protonvpn (c | connect) [<servername>] [-p <protocol>]
2828
protonvpn (c | connect) [-f | --fastest] [-p <protocol>]
2929
protonvpn (c | connect) [--cc <code>] [-p <protocol>]
30+
protonvpn (c | connect) [--not-cc <code>] [-p <protocol>]
3031
protonvpn (c | connect) [--sc] [-p <protocol>]
3132
protonvpn (c | connect) [--p2p] [-p <protocol>]
3233
protonvpn (c | connect) [--tor] [-p <protocol>]
@@ -44,6 +45,7 @@
4445
-f, --fastest Select the fastest ProtonVPN server.
4546
-r, --random Select a random ProtonVPN server.
4647
--cc CODE Determine the country for fastest connect.
48+
--not-cc CODE Determine the country to exclude for fastest connect.
4749
--sc Connect to the fastest Secure-Core server.
4850
--p2p Connect to the fastest torrent server.
4951
--tor Connect to the fastest Tor server.

0 commit comments

Comments
 (0)