Created
January 6, 2024 10:57
-
-
Save sefidel/201c2febc875fac4361169430e5fa5b7 to your computer and use it in GitHub Desktop.
Bring your own WireGuard key to ProtonVPN (hacky; see NOTE for limitations)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env nix-shell | |
| #! nix-shell -i python3 -p python3Packages.inquirer -p 'python3Packages.proton-client.overridePythonAttrs { doCheck = false; patches = [(fetchpatch {url = "https://github.com/ProtonMail/proton-python-client/pull/47/commits/faee82fdcad9fd2963a8080573e9b5315697dac7.patch";sha256 = "sha256-AvPgsBBnlp0bmHbIwA4BQ6KmsAZmlgwJnHynWIL6an8=";})]; }' | |
| # ProtonVPN - Bring your own (WireGuard) key | |
| # ------------------------------------------ | |
| # This script lets you roll your own WireGuard key instead of using the one | |
| # generated from ProtonVPN. | |
| # This may be particularly useful when using ProtonVPN as an exit node in | |
| # overlay network solutions, such as Tailscale. | |
| import proton | |
| import getpass | |
| import inquirer | |
| import sys | |
| import platform | |
| ENDPOINT="https://api.protonvpn.ch" | |
| proton_session = proton.api.Session( | |
| api_url=ENDPOINT, | |
| appversion="Other", | |
| log_dir_path="./", | |
| cache_dir_path="./", | |
| ) | |
| proton_session.enable_alternative_routing = True | |
| username = input("ProtonVPN Username: ") | |
| password = getpass.getpass("ProtonVPN Password: ") | |
| proton_session.authenticate(username, password) | |
| logical_servers = proton_session.api_request(method="get", endpoint="/vpn/logicals")["LogicalServers"] | |
| server_names = [server["Name"] for server in logical_servers] | |
| # NOTE: ProtonVPN doesn't let you use the same pubkey, even if it's a DIFFERENT NODE. | |
| # Therefore, only single selection is provided. | |
| # NOTE: Same pubkey cannot be used even if the existing certificate is deleted. | |
| # Users will have to regenerate their WireGuard pubkey when switching servers. | |
| server_selection = inquirer.list_input("Select server to roll the WireGuard key to", choices=sorted(server_names)) | |
| selected_server = next(server for server in logical_servers if server["Name"] in server_selection) | |
| if len(selected_server) == 0: | |
| print("No servers selected!", file=sys.stderr) | |
| exit(1) | |
| netshield_level = inquirer.list_input("NetShield Level", choices=[("No filter", 0), ("Block malware only", 1), ("Block malware, ads and trackers", 2)]) | |
| random_nat = inquirer.list_input("Moderate NAT", choices=[("Yes", True), ("No", False)], default=False) | |
| port_forwarding = inquirer.list_input("NAT-PMP (Port Forwarding)", choices=[("Yes", True), ("No", False)], default=True) | |
| split_tcp = inquirer.list_input("Split TCP (VPN Accelerator)", choices=[("Yes", True), ("No", False)], default=True) | |
| safe_mode = inquirer.list_input("SafeMode (Non-standard ports)", choices=[("Yes", True), ("No", False)], default=False) | |
| device_prefix = inquirer.text("Set a prefix for DeviceName", default=platform.node()) | |
| wireguard_pubkey = inquirer.text("Enter your WireGuard pubkey") | |
| print(f"Creating certificate for Node {selected_server['Name']}") | |
| payload = { | |
| "ClientPublicKey": wireguard_pubkey, | |
| "Mode": "persistent", | |
| "DeviceName": f"{device_prefix}-{selected_server['Name']} ({wireguard_pubkey})", | |
| "Features": { | |
| "peerName": selected_server["Name"], | |
| "peerIp": selected_server["Servers"][0]["EntryIP"], | |
| "peerPublicKey": selected_server["Servers"][0]["X25519PublicKey"], | |
| "platform": "Linux", | |
| "NetShieldLevel": netshield_level, | |
| "RandomNAT": random_nat, | |
| "PortForwarding": port_forwarding, | |
| "SplitTCP": split_tcp, | |
| "SafeMode": safe_mode, | |
| } | |
| } | |
| certificate = proton_session.api_request(method="post", endpoint="/vpn/v1/certificate", jsondata=payload) | |
| print(certificate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment