Skip to content

Feature Request: Add ExpressVPN Proxy Provider Support #30

@didisumard1

Description

@didisumard1

Hello, and thank you for your amazing work on Unshackle! 👋
I'd like to suggest a new provider feature that would extend the existing VPN proxy integrations.


Is your feature request related to a problem? Please describe.
Currently, Unshackle supports NordVPN, SurfsharkVPN, and WindscribeVPN as proxy providers, all of which use service credentials for authentication. However, many users—including myself—use ExpressVPN as their main VPN service.
While ExpressVPN provides manual-configuration credentials (username and password) for OpenVPN/IKEv2 setups, Unshackle doesn’t yet support it. This limits flexibility for ExpressVPN users who want a consistent proxy setup across providers.


Describe the solution you'd like
Add support for ExpressVPN as a proxy/VPN provider following the same design pattern used for NordVPN and SurfsharkVPN.
The provider should accept ExpressVPN’s manual configuration credentials and a region mapping list to build an HTTPS proxy URI pattern.

Example configuration:

proxy_providers:
  expressvpn:
    username: "exp123456"
    password: "abcdef123456"
    server_map:
      sg: "sg1.expressvpn.net"
      us: "usa2.expressvpn.net"

Example provider structure:

unshackle/core/proxies/expressvpn.py

Example class implementation:

from unshackle.core.proxies.proxy import Proxy
import re, requests

class ExpressVPN(Proxy):
    """Proxy Service using ExpressVPN manual configuration credentials."""
    def __init__(self, username: str, password: str, server_map=None):
        if not username or not password:
            raise ValueError("Username and password are required.")
        if "@" in username:
            raise ValueError("Use ExpressVPN manual configuration credentials, not your login email.")
        self.username, self.password = username, password
        self.server_map = server_map or {}
        self.countries = self.get_countries()

    def get_proxy(self, query: str):
        query = query.lower()
        region = self.server_map.get(query, f"{query}.expressvpn.net")
        return f"https://{self.username}:{self.password}@{region}:443"

    @staticmethod
    def get_countries():
        return [
            {"code": "sg", "name": "Singapore"},
            {"code": "us", "name": "United States"},
            {"code": "uk", "name": "United Kingdom"},
            {"code": "jp", "name": "Japan"},
        ]

Describe alternatives you've considered

  • Using ExpressVPN via its desktop app or CLI with full-system routing (affects entire Windows network, not just Unshackle).
  • Running ExpressVPN inside a VM or sandbox for isolation (too complex for most users).
  • Using NordVPN or Surfshark instead (requires a different subscription).

Additional context

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions