169 lines
9.2 KiB
Markdown
169 lines
9.2 KiB
Markdown
# weircon-random-proxy
|
|
|
|
En public-facing **fetch-API** der henter en URL gennem en tilfældig (eller klient-valgt) Proton WireGuard tunnel og returnerer svaret. Erstatter den lokale `nh-scrape/proxy-stack/` Docker-stak med en LXC på Proxmox.
|
|
|
|
## Arkitektur
|
|
|
|
```
|
|
Internet
|
|
│
|
|
▼
|
|
┌──────────────────────────────────┐
|
|
│ NginxProxyManager (eksisterende)│
|
|
│ • TLS termination │
|
|
│ • Tjekker X-WEIRCON-RANDOM-IP │
|
|
│ (API key) i header │
|
|
│ • Stripper headeren før proxy │
|
|
└──────────────┬───────────────────┘
|
|
│ http://<lxc-ip>:8080
|
|
▼
|
|
┌──────────────────────────────────────────────────────┐
|
|
│ LXC: weircon-random-proxy (unprivileged + TUN) │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────┐ │
|
|
│ │ fetch-service (Go, net/http+ReverseProxy :8080)│ │
|
|
│ │ • Læser mål-URL fra: │ │
|
|
│ │ - query: ?url=https://example.com │ │
|
|
│ │ - header: X-WEIRCON-RANDOM-IP-REDIRECT │ │
|
|
│ │ • Læser proxy-valg fra: │ │
|
|
│ │ - header: X-WEIRCON-PROXY-ID (0-9) │ │
|
|
│ │ - default: tilfældig │ │
|
|
│ │ • SOCKS5 via 10.99.0.{10+id}:1080 │ │
|
|
│ │ • Streamer response chunked tilbage │ │
|
|
│ └─────────────────┬──────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌──────┴──────┐ br-weircon (10.99.0.1/24)│
|
|
│ │ bridge │ │
|
|
│ └──┬───┬───┬──┘ │
|
|
│ veth ────┘ │ └──── veth │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │ netns: │ │ netns: │ │ netns: │ …× 10 │
|
|
│ │ proxy0 │ │ proxy1 │ │ proxy9 │ │
|
|
│ │ veth: │ │ veth: │ │ veth: │ │
|
|
│ │10.99.0.10│ │10.99.0.11│ │10.99.0.19│ │
|
|
│ │ + wg0 │ │ + wg0 │ │ + wg0 │ │
|
|
│ │ + micro │ │ + micro │ │ + micro │ │
|
|
│ │ socks │ │ socks │ │ socks │ │
|
|
│ │ :1080 │ │ :1080 │ │ :1080 │ │
|
|
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
│ ▼ ▼ ▼ │
|
|
│ Proton Proton Proton (via wg0) │
|
|
└──────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Klient-API
|
|
|
|
Eksempel — hent en URL gennem en tilfældig tunnel:
|
|
|
|
```bash
|
|
curl -H "X-WEIRCON-RANDOM-IP: $API_KEY" \
|
|
-H "X-WEIRCON-RANDOM-IP-REDIRECT: https://api.ipify.org" \
|
|
https://random-proxy.weircon.dk/
|
|
```
|
|
|
|
Eller via query param:
|
|
|
|
```bash
|
|
curl -H "X-WEIRCON-RANDOM-IP: $API_KEY" \
|
|
"https://random-proxy.weircon.dk/?url=https://api.ipify.org"
|
|
```
|
|
|
|
Pin en specifik tunnel:
|
|
|
|
```bash
|
|
curl -H "X-WEIRCON-RANDOM-IP: $API_KEY" \
|
|
-H "X-WEIRCON-PROXY-ID: 3" \
|
|
"https://random-proxy.weircon.dk/?url=https://api.ipify.org"
|
|
```
|
|
|
|
### Headers / parametre
|
|
|
|
| Hvor | Navn | Krævet | Forklaring |
|
|
| ----------------- | ----------------------------- | ------ | ----------------------------------------------------------- |
|
|
| NPM (header) | `X-WEIRCON-RANDOM-IP` | ja | API-key. Verificeres af nginx og strippes før forward. |
|
|
| Header eller query| `X-WEIRCON-RANDOM-IP-REDIRECT`/`?url=` | ja | Mål-URL der skal hentes. Header har præcedens over query. |
|
|
| Header | `X-WEIRCON-PROXY-ID` | nej | `0`-`9`. Hvis udeladt: random. |
|
|
| Header | `X-WEIRCON-FORWARD-METHOD` | nej | HTTP-metode mod target. Default: samme som indkommende. |
|
|
| Body | _passthrough_ | nej | Body videresendes som-er hvis metoden er POST/PUT/PATCH. |
|
|
|
|
### Response
|
|
|
|
Status + headers + body fra upstream returneres direkte. Plus `X-WEIRCON-EGRESS-PROXY: <id>` så klient kan se hvilken tunnel der blev brugt.
|
|
|
|
## Komponenter
|
|
|
|
| Sti | Formål |
|
|
| ---------------------- | -------------------------------------------------------------------------- |
|
|
| `service/main.go` | Go fetch-service (statisk binary, kører i hoved-netns i LXC'en). |
|
|
| `service/Makefile` | `make build` → 6MB static binary; `make install` til /usr/local/bin. |
|
|
| `lxc/setup-host.md` | Proxmox-side: `pct create`, TUN passthrough, push-kommandoer. |
|
|
| `lxc/setup-container.sh` | Kører **inde i** LXC'en: apt-deps, microsocks, helper-scripts, units. |
|
|
| `lxc/netns-up.sh` | Bringer ét namespace op: `proxy<N>` med wg0 + veth + bridge. |
|
|
| `lxc/netns-down.sh` | River det ned igen (kaldes af systemd ExecStopPost). |
|
|
| `lxc/systemd/weircon-proxies.target` | Grouping target for alle 10 tunneler. |
|
|
| `lxc/systemd/weircon-proxy@.service` | Templated unit. `enable weircon-proxy@{0..9}.service`. |
|
|
| `lxc/systemd/weircon-fetch.service` | Selve fetch-servicen. Hardened (DynamicUser, no caps). |
|
|
| `lxc/fetch.env.example` | Default env til fetch-servicen — kopieres til `/etc/weircon-random-proxy/fetch.env`. |
|
|
| `npm/advanced.conf` | NPM "Advanced" tab snippet: header-check + strip + forward. |
|
|
| `wg-configs/` | Lokal placeholder. Selve `.conf`-filerne lever på LXC'en, **ikke** i git. |
|
|
|
|
## NPM-laget (kort)
|
|
|
|
I NginxProxyManager → din proxy host → **Advanced** tab indsættes en config der:
|
|
|
|
1. Tjekker `$http_x_weircon_random_ip` mod den forventede API-key.
|
|
2. Returnerer `401` hvis den ikke matcher.
|
|
3. Stripper headeren med `proxy_set_header X-WEIRCON-RANDOM-IP "";` før forward.
|
|
4. Forwarder til LXC'ens interne IP på port 8080.
|
|
|
|
Detaljer + færdig snippet ligger i `npm/advanced.conf`.
|
|
|
|
## Service-detaljer (Go)
|
|
|
|
- `net/http/httputil.ReverseProxy` håndterer body-streaming chunked uden buffering.
|
|
- Én `*http.Transport` pr. tunnel → connection-pool genbruges pr. Proton-egress.
|
|
- `golang.org/x/net/proxy.SOCKS5` ContextDialer på hver Transport.
|
|
- Statisk binary (`CGO_ENABLED=0`), ~6MB, ingen runtime deps i LXC'en.
|
|
- Env-vars: `WEIRCON_LISTEN`, `WEIRCON_PROXY_COUNT`, `WEIRCON_PROXY_BASE_PORT`, `WEIRCON_PROXY_HOST`, `WEIRCON_REQUEST_TIMEOUT_SEC`.
|
|
|
|
Build + smoke-test:
|
|
|
|
```sh
|
|
cd service && make build
|
|
./weircon-random-proxy # lytter på :8080, peger på 127.0.0.1:25400..25409
|
|
```
|
|
|
|
## Deploy-flow (one-shot)
|
|
|
|
På din dev-maskine:
|
|
|
|
```sh
|
|
cd random_proxy/service && make build # → ./weircon-random-proxy (6MB static)
|
|
```
|
|
|
|
På Proxmox-hosten følges `lxc/setup-host.md`:
|
|
|
|
1. `pct create` med `--unprivileged 1 --features nesting=1,keyctl=1` (Debian 12).
|
|
2. Tilføj TUN passthrough i `/etc/pve/lxc/<ctid>.conf`.
|
|
3. `pct push` binary, scripts, units, og dine Proton WG-configs.
|
|
4. `pct enter <ctid> && bash /root/setup-container.sh`.
|
|
5. `systemctl enable --now weircon-proxies.target weircon-proxy@{0..9}.service weircon-fetch.service`.
|
|
6. I NPM: opret host der peger på LXC:8080, indsæt `npm/advanced.conf` i Advanced-tabben med din API-key.
|
|
|
|
## Status
|
|
|
|
- [x] Arkitektur dokumenteret
|
|
- [x] `service/` Go fetch-service (kompilerer, vet clean, smoke-tested)
|
|
- [x] `lxc/` netns scripts + systemd units + setup-guides
|
|
- [x] `npm/advanced.conf` nginx-snippet til NPM
|
|
- [ ] Faktisk deploy på Proxmox (kræver din host)
|
|
- [ ] Migrationsnote i `nh-scrape/proxy-stack/` der peger hertil
|
|
- [ ] Opdater `nh-scrape` til at kalde den nye endpoint
|
|
|
|
## Open questions
|
|
|
|
- **API-key opbevaring**: env-var i NPM, eller en fil mountet ind? (Foreslår env-var via NPM stack.)
|
|
- **Rate limiting / concurrency**: skal vi cap'e samtidige requests pr. tunnel? Proton accepterer ikke ubegrænset.
|
|
- **Logging**: hvor meget skal logges (URL, status, tunnel-id)? Husk GDPR hvis det rammer personhenførbare URL'er.
|
|
- **Failover**: hvis valgt tunnel er nede, fall back til random anden, eller fejl 503?
|