Metadata-Version: 2.5
Name: foxyvpn
Version: 1.0.0
Summary: A local SOCKS5 proxy client for the Mozilla VPN / Firefox VPN proxy service
Project-URL: Homepage, https://github.com/vauth/FoxyVPN
Project-URL: Repository, https://github.com/vauth/FoxyVPN
Project-URL: Issues, https://github.com/vauth/FoxyVPN/issues
Author: vauth
License: MIT License
        
        Copyright (c) 2026 vauth
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: firefox,mozilla-vpn,proxy,socks5,vpn
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Security
Requires-Python: >=3.9
Requires-Dist: cryptography>=42.0
Requires-Dist: h2>=4.1
Requires-Dist: httpx[socks]>=0.27
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Provides-Extra: http3
Requires-Dist: aioquic>=1.0; extra == 'http3'
Description-Content-Type: text/markdown

# FoxyVPN

A standalone Python client and local SOCKS5 proxy for the Mozilla VPN / Firefox VPN proxy service, distributed as a standard PyPI package.

This is an independent Python rewrite of [`firefox-vpn-client`](https://github.com/UjuiUjuMandan/firefox-vpn-client) (originally written in Go). It reimplements the same Firefox Accounts authentication, Mozilla VPN "Guardian" control plane, Fastly anti-bot challenge solver, and local SOCKS5-over-HTTP/2 proxy, packaged as an installable `pip` package with a console entry point and an automated release workflow.

> **Disclaimer**: This is an unofficial, community client. It is not affiliated with or endorsed by Mozilla. Use it only with an account and subscription you are authorized to use, and in accordance with Mozilla VPN's terms of service.

## Features

- Firefox Accounts login (email + password, with email 2FA code verification, falling back to a confirmation-link prompt if FxA requires it) or reuse of pre-provisioned session tokens, with automatic rotation across a pool of tokens.
- Cached OAuth tokens (`~/.foxyvpn-tokens.json`, written with `0600` permissions) with automatic refresh.
- Automatic solving of Fastly's client-side anti-bot "Client Challenge" (proof-of-work, Private Access Token probing, and client-metrics beacons), including on Hawk-signed FxA requests, where the request signature is rebuilt fresh on every retry.
- Mozilla VPN "Guardian" proxy-pass issuance, renewal, quota monitoring, and account entitlement lookups, including clock-skew-tolerant JWT expiry parsing.
- VPN server list discovery via Firefox Remote Settings, with country/city selection (defaulting to Firefox's own recommended "REC" server when no country is given) and a persisted proxy-state file across restarts.
- A local SOCKS5 (RFC 1928, CONNECT-only) proxy that tunnels traffic to the upstream Mozilla VPN proxy node over HTTP/2, with connection pooling, client-IP affinity across multiple upstream connections, idle timeouts, and a maximum-connections limit.
- Non-fatal exit-IP/country verification after connecting.
- Optional JSON status file describing the current proxy-pass health, for supervisord/systemd-style monitoring.
- Structured logging (text or JSON) to stderr.

## Installation

```bash
pip install foxyvpn
```

Or, from a source checkout:

```bash
pip install .
```

HTTP/3 (QUIC) upstream support is optional:

```bash
pip install "foxyvpn[http3]"
```

## Usage

```bash
# First run: interactive Firefox Accounts login, auto-selects a proxy server.
foxyvpn --country us

# Force a fresh login instead of reusing cached tokens.
foxyvpn --login --country us

# Use a specific upstream proxy instead of country-based selection.
foxyvpn --proxy us1.example.com:443

# Authenticate with a pre-provisioned session token (or a file with one
# token per line for automatic rotation on quota exhaustion).
foxyvpn --session-token /path/to/tokens.txt --country de

# Print account entitlement info and exit.
foxyvpn --print-info

# Print the available server list and exit.
foxyvpn --list-servers
```

Once running, point any SOCKS5-aware client at the local listener (default `127.0.0.1:1080`):

```bash
curl --socks5-hostname 127.0.0.1:1080 https://example.com
```

### CLI flags

| Flag | Default | Description |
| --- | --- | --- |
| `--api-proxy` | _(none)_ | Proxy URL used only for FxA/Guardian/Remote-Settings control-plane calls. |
| `--guardian` | `https://vpn.mozilla.org` | Guardian (Mozilla VPN control plane) endpoint. |
| `--listen` | `127.0.0.1:1080` | Local SOCKS5 listen address (`host:port`, or `[ipv6]:port`). |
| `--login` | off | Force a fresh interactive login, ignoring cached tokens. |
| `--email` | _(prompted)_ | Firefox Accounts email. |
| `--session-token` | _(none)_ | Session token or path to a token-pool file. |
| `--print-info` | off | Print entitlement info and exit. |
| `--list-servers` | off | Print the server list and exit. |
| `--proxy` | _(none)_ | Exact upstream `host:port` (mutually exclusive with `--country`). |
| `--country` | _(none)_ | Two-letter country code for proxy selection. Defaults to the recommended `REC` server (auto-selected by Firefox) when omitted. |
| `--timeout` | `20` | Default request timeout (seconds) for FxA/Guardian/Remote-Settings control-plane calls. |
| `--handshake-timeout` | `10` | Upstream TLS/HTTP2 handshake timeout (seconds). |
| `--idle-timeout` | `0` (disabled) | Idle connection timeout (seconds). |
| `--max-conns` | `256` | Max concurrent SOCKS5 client connections; `0` disables the limit. |
| `--upstream-conns` | `1` | Number of pooled upstream sessions (client-IP affinity when >1). |
| `--status-file` | _(none)_ | Path to a JSON proxy-pass health status file. |
| `--proxy-state-file` | _(none)_ | Path to persist the selected upstream proxy. |
| `--verify-exit` / `--no-verify-exit` | on | Verify the exit country after connecting. |
| `--exit-check-url` | `https://www.cloudflare.com/cdn-cgi/trace` | URL used for exit verification. |
| `--exit-check-timeout` | `10` | Timeout for the exit-check request (seconds). |
| `--verbose` | off | Shorthand for `--log-level debug`. |
| `--log-level` | `info` | `debug`, `info`, `warn`, or `error`. |
| `--log-format` | `text` | `text` or `json`. |
| `--version` | | Print version information and exit. |

## Development

There is no automated test suite: the login, 2FA, quota-exhaustion, and challenge-solving flows all require a real Firefox Account and live Mozilla VPN entitlement, which can't run unattended in CI. Local changes are verified by building and inspecting the package instead:

```bash
pip install -e ".[dev]"
python -m build
python -m twine check dist/*
```

## License

[MIT](LICENSE)
