impersonate-proxy 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nicholas de Jong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: impersonate-proxy
3
+ Version: 0.2.1
4
+ Summary: HTTP/HTTPS proxy that impersonates browser TLS fingerprints using curl_cffi
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.12
7
+ License-File: LICENSE
8
+ Requires-Dist: curl_cffi>=0.7.0
9
+ Requires-Dist: cryptography>=42.0.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: basedpyright>=1.20.0; extra == "dev"
12
+ Requires-Dist: ruff>=0.8.0; extra == "dev"
13
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
14
+ Requires-Dist: requests>=2.28.0; extra == "dev"
15
+ Dynamic: license-file
@@ -0,0 +1,143 @@
1
+ # impersonate-proxy
2
+
3
+ > [!NOTE]
4
+ > This project is a fork of the original source project [hauxir/tls-impersonate-proxy](https://github.com/hauxir/tls-impersonate-proxy) maintained at [psaintelligence/impersonate-proxy](https://github.com/psaintelligence/impersonate-proxy).
5
+
6
+ HTTP/HTTPS proxy that impersonates browser TLS fingerprints using [curl_cffi](https://github.com/lexiforest/curl_cffi). Defeats JA3/JA4 TLS fingerprinting used by CDNs to block non-browser clients.
7
+
8
+ ## How it works
9
+
10
+ Many CDNs use TLS fingerprinting (JA3/JA4) to distinguish real browsers from tools like ffmpeg, curl, wget, etc. This proxy sits between your client and the internet, re-issuing every request with a browser TLS fingerprint via curl_cffi.
11
+
12
+ - **HTTP requests**: Proxied directly with browser TLS fingerprint
13
+ - **HTTPS requests**: MITM (Man-in-the-Middle) with certificates signed by a local CA, then re-issued with browser TLS fingerprint
14
+
15
+ ---
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install git+https://github.com/psaintelligence/impersonate-proxy.git
21
+ ```
22
+
23
+ Or with [uv](https://github.com/astral-sh/uv):
24
+
25
+ ```bash
26
+ uv pip install git+https://github.com/psaintelligence/impersonate-proxy.git
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Usage
32
+
33
+ ```bash
34
+ # Start the proxy (default: 127.0.0.1:8899)
35
+ impersonate-proxy
36
+
37
+ # Custom port and host
38
+ impersonate-proxy --port 9000 --host 0.0.0.0
39
+
40
+ # Different browser fingerprint
41
+ impersonate-proxy --impersonate edge101
42
+
43
+ # Custom CA certificate storage directory
44
+ impersonate-proxy --ca-dir ~/.my-certs
45
+ ```
46
+
47
+ ### With ffmpeg
48
+
49
+ ```bash
50
+ ffmpeg -http_proxy http://127.0.0.1:8899 -i https://stream.example.com/live.m3u8 output.mp4
51
+ ```
52
+
53
+ ### With curl
54
+
55
+ To use the proxy with HTTPS requests, you must pass the generated CA certificate to curl or install it in your system trust store:
56
+
57
+ ```bash
58
+ curl --cacert ~/.config/impersonate-proxy/ca.crt -x http://127.0.0.1:8899 https://example.com
59
+ ```
60
+
61
+ ### With any HTTP client
62
+
63
+ Set the `http_proxy` / `https_proxy` environment variables:
64
+
65
+ ```bash
66
+ export http_proxy=http://127.0.0.1:8899
67
+ export https_proxy=http://127.0.0.1:8899
68
+
69
+ # For Python HTTP clients (requests, httpx)
70
+ export REQUESTS_CA_BUNDLE=~/.config/impersonate-proxy/ca.crt
71
+ export SSL_CERT_FILE=~/.config/impersonate-proxy/ca.crt
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Configuration Options
77
+
78
+ | Command Line Option | Environment Variable | Default | Description |
79
+ |---|---|---|---|
80
+ | `--port` / `-p` | `IMPERSONATE_PROXY_PORT` | `8899` | Port to listen on |
81
+ | `--host` / `-H` | `IMPERSONATE_PROXY_HOST` | `127.0.0.1` | Host to bind to |
82
+ | `--impersonate` / `-i` | `IMPERSONATE_PROXY_IMPERSONATE` | `chrome` | Browser to impersonate |
83
+ | `--ca-dir` / `-c` | `IMPERSONATE_PROXY_CA_DIR` | `~/.config/impersonate-proxy` | Directory to load/store the CA files |
84
+ | `--no-enrich-headers` | `IMPERSONATE_PROXY_ENRICH_HEADERS=false` | *(enrichment on)* | Disable automatic browser header injection (User-Agent, Sec-Fetch-*, etc.) |
85
+ | `--debug` / `-d` | `IMPERSONATE_PROXY_DEBUG` | `false` | Enable verbose debug logging and show identifying details in logs |
86
+
87
+ ---
88
+
89
+ ## How HTTPS works
90
+
91
+ For HTTPS, the proxy uses MITM (Man-in-the-Middle):
92
+
93
+ 1. On startup, the proxy loads or generates the CA private key (`ca.key`) and self-signed certificate (`ca.crt`) in the specified `--ca-dir`. Existing keys/certs in the directory are reused.
94
+ 2. When a client sends a CONNECT request, the proxy wraps the connection with a dynamically generated site-specific certificate signed by the CA (generated quickly using ECDSA P-256 keys).
95
+ 3. The proxy reads the decrypted HTTP requests inside the secure tunnel and forwards them using `curl_cffi` with browser TLS signatures.
96
+ 4. If the CA files cannot be loaded or generated, the proxy falls back to a raw TCP tunnel (no TLS impersonation for HTTPS).
97
+
98
+ ---
99
+
100
+ ## Docker
101
+
102
+ You can run the proxy inside Docker using the provided `Dockerfile` and `docker-compose.yml`.
103
+
104
+ ### Docker Compose
105
+
106
+ 1. Start the container:
107
+ ```bash
108
+ docker compose up -d
109
+ ```
110
+ 2. Retrieve the generated CA certificate from the volume (to use in client requests):
111
+ ```bash
112
+ docker cp impersonate-proxy:/certs/ca.crt ./ca.crt
113
+ ```
114
+ 3. Test the proxy connection:
115
+ ```bash
116
+ curl --cacert ./ca.crt -x http://127.0.0.1:8899 https://example.com
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Development
122
+
123
+ Make targets are available for development tasks (utilizing an isolated `uv` virtual environment):
124
+
125
+ ```bash
126
+ make setup # Setup environment and dependencies
127
+ make sync # Synchronize python dependencies
128
+ make lint # Check code format and style
129
+ make lint-fix # Automatically format and fix issues
130
+ make typecheck # Run basedpyright static type checker
131
+ make test # Run offline unit and integration tests
132
+ make test-verbose # Run tests with verbose output
133
+ make test-live # Run basic live tests (hit real URLs)
134
+ make test-extended # Run extended bot-detection fingerprint tests
135
+ make benchmark # Run concurrency performance benchmark
136
+ make docs-sync # Sync documentation dependencies
137
+ make docs-build # Build documentation site
138
+ make docs-serve # Serve documentation locally
139
+ make build # Build wheel and source distributions
140
+ make bump-patch # Bump version patch number
141
+ make bump-minor # Bump version minor number
142
+ make clean # Remove build and cache directories
143
+ ```
@@ -0,0 +1,90 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools]
6
+ package-dir = {"" = "src"}
7
+ packages = ["impersonate_proxy"]
8
+
9
+ [tool.setuptools.dynamic]
10
+ version = {attr = "impersonate_proxy.__version__"}
11
+
12
+
13
+ [project]
14
+ name = "impersonate-proxy"
15
+ dynamic = ["version"]
16
+ description = "HTTP/HTTPS proxy that impersonates browser TLS fingerprints using curl_cffi"
17
+ requires-python = ">=3.12"
18
+ license = "MIT"
19
+ dependencies = [
20
+ "curl_cffi>=0.7.0",
21
+ "cryptography>=42.0.0",
22
+ ]
23
+
24
+ [project.scripts]
25
+ impersonate-proxy = "impersonate_proxy.main:main"
26
+
27
+ [project.optional-dependencies]
28
+ dev = [
29
+ "basedpyright>=1.20.0",
30
+ "ruff>=0.8.0",
31
+ "pytest>=7.0.0",
32
+ "requests>=2.28.0",
33
+ ]
34
+
35
+ [tool.ruff]
36
+ target-version = "py312"
37
+ line-length = 120
38
+ indent-width = 4
39
+
40
+ [tool.ruff.lint]
41
+ select = [
42
+ "E",
43
+ "W",
44
+ "F",
45
+ "I",
46
+ "B",
47
+ "C4",
48
+ "UP",
49
+ "SIM",
50
+ ]
51
+ ignore = [
52
+ "E501",
53
+ "SIM108",
54
+ ]
55
+ fixable = ["ALL"]
56
+
57
+ [tool.ruff.format]
58
+ quote-style = "double"
59
+ indent-style = "space"
60
+ skip-magic-trailing-comma = false
61
+ line-ending = "auto"
62
+
63
+ [tool.ruff.lint.isort]
64
+ known-first-party = ["impersonate_proxy"]
65
+
66
+ [tool.basedpyright]
67
+ pythonVersion = "3.12"
68
+ typeCheckingMode = "standard"
69
+ reportMissingImports = "none"
70
+ reportMissingTypeStubs = "none"
71
+ reportUnknownMemberType = "none"
72
+ reportUnknownArgumentType = "none"
73
+ reportUnknownVariableType = "none"
74
+ reportUnknownLambdaType = "none"
75
+ reportUnknownParameterType = "none"
76
+ reportGeneralTypeIssues = "none"
77
+ reportArgumentType = "none"
78
+ reportAttributeAccessIssue = "none"
79
+ reportOptionalMemberAccess = "none"
80
+ reportPossiblyUnboundVariable = "none"
81
+ include = ["src/impersonate_proxy"]
82
+ exclude = ["**/node_modules", "**/__pycache__", "venv", ".venv"]
83
+
84
+ [tool.pytest.ini_options]
85
+ addopts = "-m \"not live and not live_extended\""
86
+ markers = [
87
+ "live: tests that hit real URLs (deselect with '-m \"not live\"')",
88
+ "live_extended: extended fingerprint/bot-detection tests against known protected sites (run with 'pytest -m live_extended')",
89
+ ]
90
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"