mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
feat: add cloakserve CDP server mode for Docker
Add bin/cloakserve — launches stealth Chromium with remote debugging enabled so users can connect via connect_over_cdp() from the host. Uses socat to forward 0.0.0.0:9222 to Chrome's localhost-only CDP port. Usage: docker run -d -p 127.0.0.1:9222:9222 cloakhq/cloakbrowser cloakserve Tested: all stealth checks pass via CDP, bot.sannysoft.com 54/54, reCAPTCHA 0.9, zero detection regressions.
This commit is contained in:
@@ -28,5 +28,7 @@ jobs:
|
||||
node-version: 20
|
||||
- name: Install and build
|
||||
run: cd js && npm install && npm run build
|
||||
- name: Typecheck
|
||||
run: cd js && npm run typecheck
|
||||
- name: Run tests
|
||||
run: cd js && npm test
|
||||
|
||||
+5
-2
@@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libglib2.0-0 libgtk-3-0 libpangocairo-1.0-0 libcairo-gobject2 \
|
||||
libgdk-pixbuf-2.0-0 libxss1 libxtst6 fonts-liberation \
|
||||
xvfb xdotool \
|
||||
curl ca-certificates \
|
||||
curl ca-certificates socat \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -36,7 +36,10 @@ RUN python -c "from cloakbrowser import ensure_binary; ensure_binary()" \
|
||||
|
||||
# CLI shortcuts
|
||||
COPY bin/cloaktest /usr/local/bin/cloaktest
|
||||
RUN chmod +x /usr/local/bin/cloaktest
|
||||
COPY bin/cloakserve /usr/local/bin/cloakserve
|
||||
RUN chmod +x /usr/local/bin/cloaktest /usr/local/bin/cloakserve
|
||||
|
||||
EXPOSE 9222
|
||||
|
||||
# Xvfb entrypoint for headed mode support
|
||||
COPY bin/docker-entrypoint.sh /entrypoint.sh
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<a href="https://github.com/CloakHQ/CloakBrowser"><img src="https://img.shields.io/github/last-commit/cloakhq/cloakbrowser" alt="Last Commit"></a>
|
||||
<br>
|
||||
<a href="https://github.com/CloakHQ/CloakBrowser"><img src="https://img.shields.io/github/stars/cloakhq/cloakbrowser" alt="Stars"></a>
|
||||
<a href="https://pypi.org/project/cloakbrowser/"><img src="https://img.shields.io/pypi/dm/cloakbrowser?label=pypi%20downloads&logo=pypi&logoColor=white" alt="PyPI Downloads"></a>
|
||||
<a href="https://pypi.org/project/cloakbrowser/"><img src="https://img.shields.io/pepy/dt/cloakbrowser?label=pypi&logo=pypi&logoColor=white" alt="PyPI Downloads"></a>
|
||||
<a href="https://www.npmjs.com/package/cloakbrowser"><img src="https://img.shields.io/npm/dt/cloakbrowser?label=npm&logo=npm&logoColor=white" alt="npm Downloads"></a>
|
||||
</p>
|
||||
|
||||
@@ -506,13 +506,18 @@ The wrapper auto-downloads the correct binary for your platform.
|
||||
|
||||
## Docker
|
||||
|
||||
Pre-built image on Docker Hub — no install, no setup:
|
||||
Pre-built image on Docker Hub — no install, no setup.
|
||||
|
||||
### Quick test
|
||||
|
||||
```bash
|
||||
# Run the stealth test suite
|
||||
docker run --rm cloakhq/cloakbrowser cloaktest
|
||||
```
|
||||
|
||||
# Run your own script
|
||||
### Run a script
|
||||
|
||||
```bash
|
||||
# Inline script
|
||||
docker run --rm cloakhq/cloakbrowser python -c "
|
||||
from cloakbrowser import launch
|
||||
browser = launch()
|
||||
@@ -522,6 +527,9 @@ print(page.title())
|
||||
browser.close()
|
||||
"
|
||||
|
||||
# Mount your own script
|
||||
docker run --rm -v ./my_script.py:/app/my_script.py cloakhq/cloakbrowser python my_script.py
|
||||
|
||||
# With a proxy
|
||||
docker run --rm cloakhq/cloakbrowser python -c "
|
||||
from cloakbrowser import launch
|
||||
@@ -533,7 +541,50 @@ browser.close()
|
||||
"
|
||||
```
|
||||
|
||||
To extend with your own script:
|
||||
### CDP server mode
|
||||
|
||||
Start a persistent stealth browser and connect to it remotely via Chrome DevTools Protocol:
|
||||
|
||||
```bash
|
||||
docker run -d --name cloak -p 127.0.0.1:9222:9222 cloakhq/cloakbrowser cloakserve
|
||||
```
|
||||
|
||||
Then connect from your host machine:
|
||||
|
||||
```python
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
pw = sync_playwright().start()
|
||||
browser = pw.chromium.connect_over_cdp("http://localhost:9222")
|
||||
page = browser.new_page()
|
||||
page.goto("https://example.com")
|
||||
print(page.title())
|
||||
browser.close()
|
||||
```
|
||||
|
||||
Pass extra flags to the browser:
|
||||
|
||||
```bash
|
||||
# With proxy
|
||||
docker run -d --name cloak -p 127.0.0.1:9222:9222 cloakhq/cloakbrowser \
|
||||
cloakserve --proxy-server=http://proxy:8080
|
||||
|
||||
# Headed mode (renders to Xvfb inside container)
|
||||
docker run -d --name cloak -p 127.0.0.1:9222:9222 cloakhq/cloakbrowser \
|
||||
cloakserve --headless=false
|
||||
```
|
||||
|
||||
Stop the server:
|
||||
|
||||
```bash
|
||||
docker stop cloak && docker rm cloak
|
||||
```
|
||||
|
||||
> **Security:** CDP gives full control over the browser (execute JS, read pages, access files).
|
||||
> The examples bind to `127.0.0.1` so only your machine can connect. Never expose port 9222
|
||||
> to the public internet without additional authentication.
|
||||
|
||||
### Extend with your own image
|
||||
|
||||
```dockerfile
|
||||
FROM cloakhq/cloakbrowser
|
||||
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Launch stealth Chromium as a CDP server for remote connections.
|
||||
|
||||
Usage:
|
||||
cloakserve # headless on port 9222
|
||||
cloakserve --headless=false # headed (uses Xvfb in Docker)
|
||||
cloakserve --proxy-server=host:port # with proxy
|
||||
|
||||
Connect from host:
|
||||
playwright.chromium.connect_over_cdp("http://localhost:9222")
|
||||
"""
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from cloakbrowser.config import get_default_stealth_args
|
||||
from cloakbrowser.download import ensure_binary
|
||||
|
||||
EXPOSE_PORT = 9222 # External, 0.0.0.0 (user connects here)
|
||||
CHROME_PORT = 9223 # Internal, 127.0.0.1 (Chrome binds here)
|
||||
|
||||
binary = ensure_binary()
|
||||
|
||||
chrome_args = [
|
||||
binary,
|
||||
f"--remote-debugging-port={CHROME_PORT}",
|
||||
# "--remote-debugging-address=0.0.0.0", # TODO: enable after binary patch 032
|
||||
# Sane defaults for running Chrome directly (outside Playwright)
|
||||
"--no-first-run",
|
||||
"--no-default-browser-check",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-extensions",
|
||||
"--disable-popup-blocking",
|
||||
"--disable-background-networking",
|
||||
"--metrics-recording-only",
|
||||
] + get_default_stealth_args() + sys.argv[1:]
|
||||
|
||||
# Launch Chrome
|
||||
chrome = subprocess.Popen(chrome_args)
|
||||
|
||||
# Wait for Chrome to start listening
|
||||
time.sleep(2)
|
||||
|
||||
# Forward 0.0.0.0:9222 -> 127.0.0.1:9223
|
||||
# Chrome hardcodes 127.0.0.1 for security; socat exposes it to Docker network.
|
||||
# TODO: Remove socat after patching binary to support --remote-debugging-address
|
||||
socat = subprocess.Popen([
|
||||
"socat",
|
||||
f"TCP-LISTEN:{EXPOSE_PORT},fork,reuseaddr,bind=0.0.0.0",
|
||||
f"TCP:127.0.0.1:{CHROME_PORT}",
|
||||
])
|
||||
|
||||
print(f"CloakBrowser CDP server ready on port {EXPOSE_PORT}", flush=True)
|
||||
|
||||
|
||||
def cleanup(sig, frame):
|
||||
chrome.terminate()
|
||||
socat.terminate()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
signal.signal(signal.SIGTERM, cleanup)
|
||||
signal.signal(signal.SIGINT, cleanup)
|
||||
|
||||
# Wait for Chrome to exit, then clean up socat
|
||||
chrome.wait()
|
||||
socat.terminate()
|
||||
Reference in New Issue
Block a user