From 20c15f761b072c0f394da043201bfc707f85b8ec Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Mon, 11 May 2026 09:55:48 -0600 Subject: [PATCH] fix(proxies/nordvpn): use *.proxy.nordvpn.com for HTTPS proxy NordVPN's HTTPS proxy endpoints now serve a certificate valid only for *.proxy.nordvpn.com. Connecting to the legacy .nordvpn.com:89 hostname fails with SSLCertVerificationError (hostname mismatch). Rewrite direct queries, server_map entries, and API-returned hostnames to the proxy subdomain so cert validation succeeds. --- unshackle/core/proxies/nordvpn.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/unshackle/core/proxies/nordvpn.py b/unshackle/core/proxies/nordvpn.py index 33418ff..c9829c1 100644 --- a/unshackle/core/proxies/nordvpn.py +++ b/unshackle/core/proxies/nordvpn.py @@ -64,7 +64,7 @@ class NordVPN(Proxy): if re.match(r"^[a-z]{2}\d+$", query): # country and nordvpn server id, e.g., us1, fr1234 - hostname = f"{query}.nordvpn.com" + hostname = f"{query}.proxy.nordvpn.com" else: if query.isdigit(): # country id @@ -86,7 +86,7 @@ class NordVPN(Proxy): if server_mapping: # country was set to a specific server ID in config - hostname = f"{country['code'].lower()}{server_mapping}.nordvpn.com" + hostname = f"{country['code'].lower()}{server_mapping}.proxy.nordvpn.com" else: # get the recommended server ID recommended_servers = self.get_recommended_servers(country["id"]) @@ -113,6 +113,9 @@ class NordVPN(Proxy): # NordVPN uses the alpha2 of 'GB' in API responses, but 'UK' in the hostname hostname = f"gb{hostname[2:]}" + if hostname.endswith(".nordvpn.com") and not hostname.endswith(".proxy.nordvpn.com"): + hostname = hostname[: -len(".nordvpn.com")] + ".proxy.nordvpn.com" + return f"https://{self.username}:{self.password}@{hostname}:89" def get_country(self, by_id: Optional[int] = None, by_code: Optional[str] = None) -> Optional[dict]: