initial commit

This commit is contained in:
ray
2026-07-12 10:17:17 -04:00
commit dab5a4ebc6
1424 changed files with 330463 additions and 0 deletions
@@ -0,0 +1,222 @@
---
name: private-tracker-seedbox
description: |-
Deploy and troubleshoot a Docker seedbox for private trackers — gluetun VPN,
qBittorrent, PIA port forwarding, and tracker-specific authorization
(MAM Dynamic Seedbox via Mousehole).
version: 1.0.0
platforms: [linux]
tags: [seedbox, torrent, qbittorrent, gluetun, vpn, private-tracker, mam, myanonamouse]
---
# Private Tracker Seedbox
Deploying a Docker seedbox for private trackers with gluetun (VPN) + qBittorrent,
plus tracker-specific tooling for IP authorization when the torrent client's IP
differs from the browser's IP.
## Gluetun + qBittorrent Base Setup
### Docker Compose Pattern
```yaml
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
- 127.0.0.1:11893:8080 # qBittorrent WebUI
- 127.0.0.1:6881:6881 # torrent port (optional, qBittorrent uses forwarded port)
- 127.0.0.1:6881:6881/udp # (optional)
- 127.0.0.1:5010:5010 # Mousehole WebUI (if used)
volumes:
- ./gluetun:/gluetun
environment:
VPN_SERVICE_PROVIDER: "private internet access"
VPN_TYPE: "openvpn"
OPENVPN_PROTOCOL: "tcp"
OPENVPN_ENDPOINT_PORT: "443"
OPENVPN_USER: "your-username"
OPENVPN_PASSWORD: your-password
UPDATER_PERIOD: "0"
SERVER_HOSTNAMES: "nl-amsterdam.privacy.network" # PIA server
VPN_PORT_FORWARDING: "on" # PIA port forwarding
PORT_FORWARD_ONLY: "true" # only allow port-forwarded ports
FIREWALL_VPN_INPUT_PORTS: "8080,5010" # comma-separated allowed ports
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: "service:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./qbittorrent:/config
- /path/to/downloads:/downloads
environment:
- PUID=1000
- PGID=1000
- TZ=America/Chicago
- WEBUI_PORT=8080
restart: unless-stopped
```
### Key Config Points
- qBittorrent uses `network_mode: "service:gluetun"` — shares gluetun's network stack
- `depends_on: gluetun: condition: service_healthy` — waits for VPN tunnel before starting
- qBittorrent's listening port (from `Session\Port` in qBittorrent.conf) must match gluetun's forwarded port from the VPN provider
- Port **11893** on host maps to qBittorrent WebUI at port 8080 inside gluetun's stack
### Compose Gotcha: `restart` vs `up -d`
**`docker compose restart <svc>` restarts the existing container with its ORIGINAL config.**
It does NOT pick up changes to port mappings, environment variables, or volumes.
To apply compose changes, use:
```
docker compose up -d
```
This recreates any container whose config has changed. If you need to force even when
the config hasn't changed:
```
docker compose up -d --force-recreate <svc>
```
### Port Binding: localhost-only vs All Interfaces
- `127.0.0.1:5010:5010` — binds ONLY to localhost; accessible from host only
- `5010:5010` — binds to 0.0.0.0 (all interfaces); accessible from LAN and other Docker
containers (e.g., KasmVNC Chrome)
When running Chrome in a KasmVNC container that's on a different Docker network,
the browser uses its own network namespace. `localhost` inside KasmVNC refers to
KasmVNC itself, not the host. Use the host's LAN IP (e.g., `192.168.50.98:5010`)
and ensure the port is bound to all interfaces.
To verify actual Docker port bindings:
```
docker port <container>
```
## PIA Port Forwarding
PIA port forwarding with gluetun:
1. Set `VPN_PORT_FORWARDING: "on"` and `PORT_FORWARD_ONLY: "true"` on gluetun
2. Gluetun logs show the forwarded port (e.g., `port forwarded is 36590`)
3. The forwarded port is written to `/tmp/gluetun/forwarded_port` inside gluetun
4. qBittorrent must use this port — set `Session\Port=<forwarded port>` in qBittorrent.conf
Check forwarded port:
```
docker exec gluetun cat /tmp/gluetun/forwarded_port
```
## MAM (MyAnonaMouse) — Dynamic Seedbox / Mousehole
### The Problem
MAM compares your **browser's IP** against your **torrent client's IP**. If they don't match
(e.g., browser on home IP, torrent client on VPN IP), you get:
> **"Unrecognized host/PassKey. (client IP here)"**
### Step 1: Get Staff Approval
Open a ticket with MAM staff explaining you use a VPN for your torrent client.
Per MAM rule 1.2, VPN use must be authorized.
### Step 2: Deploy Mousehole as a Sidecar
[Mousehole](https://github.com/t-mart/mousehole) is a background service that periodically
calls MAM's Dynamic Seedbox API to register your current VPN IP.
Add to your docker-compose.yml:
```yaml
services:
# ... gluetun and qbittorrent as above ...
mousehole:
image: tmmrtn/mousehole:latest
container_name: mousehole
network_mode: "service:gluetun"
depends_on:
gluetun:
condition: service_healthy
environment:
TZ: America/Chicago
MOUSEHOLE_AUTH_PASSWORD: your-strong-password
volumes:
- mousehole:/var/lib/mousehole
restart: unless-stopped
volumes:
mousehole:
```
Also add `- 127.0.0.1:5010:5010` to gluetun's `ports:` and add `,5010` to
`FIREWALL_VPN_INPUT_PORTS`.
### Step 3: Configure Mousehole
1. Browse to **http://localhost:5010**
2. Log in with the password set in `MOUSEHOLE_AUTH_PASSWORD`
3. Get your MAM session cookie:
- Log in to MAM in your browser
- DevTools → Application/Storage → Cookies → `myanonamouse.net`
- Copy the **session** cookie value
4. Paste it into Mousehole's web UI
5. Click **Update Now** to immediately register your current VPN IP
Mousehole will now automatically keep MAM updated with your VPN IP on a schedule.
### MAM Tracker Info
- Allowed qBittorrent: from 5.0.1 to latest 5.2.x line
- qBittorrent Anonymous Mode will break tracker communication
- The tracker returns bencoded responses; HTTP 200 + "failure reason" means the tracker
accepted the request but rejected the client/IP/credentials
- Passkey is embedded in the announce URL, not sent as a GET parameter
## Port Blacklist Notes
MAM (and many private trackers) block common P2P ports (6881-6889, etc.).
Configure qBittorrent to use the VPN's forwarded port instead of defaults.
## Troubleshooting
### Tracker returns "Non-Whitelisted client or version"
- Check the MAM Allowed Clients page: the client version may not be whitelisted yet
- Even if the web page says it's allowed, the tracker filter may lag behind
- Verify qBittorrent is not in Anonymous Mode
### Tracker returns "Unrecognized host/PassKey"
- Browser IP ≠ torrent client IP
- Use Mousehole (Dynamic Seedbox API) to register the torrent client's IP
### qBittorrent logging shows no tracker announcements
- Check that the torrent isn't paused
- Verify qBittorrent's listening port matches the VPN forwarded port
- Confirm `disable_dht = 0` is set correctly in the fastresume for private torrents
(private torrents should have DHT disabled)
### Torrent stalled with no peers
- Confirm port forwarding is active via `docker exec gluetun cat /tmp/gluetun/forwarded_port`
- Test tracker reachability: `docker exec qbittorrent curl -s -o /dev/null -w "%{http_code}" <tracker_url>`
- Verify the passkey in the announce URL is correct (check fastresume via `strings`)
## References
- [Mousehole GitHub](https://github.com/t-mart/mousehole)
- [Gluetun Wiki](https://github.com/qdm12/gluetun-wiki)
- [MAM FAQ — Unrecognized host/PassKey](https://s.mrd.ninja/upmm)
- [MAM Allowed Clients](https://s.mrd.ninja/CLNTe)
@@ -0,0 +1,108 @@
# MAM (MyAnonaMouse) Troubleshooting Reference
## Tracker Error: "Unrecognized host/PassKey"
**Full error from MAM's tracker detail page:**
```
ip port agent error
181.214.x.x 36590 -qB5230- / 5.2.3 Unrecognized host/PassKey. (181.214.x.x)
```
**Root cause:** Browser IP ≠ torrent client IP. MAM compares the IP you're browsing
from against the IP your torrent client is announcing from. When they don't match
(e.g., browser on home connection, torrent client on VPN), the passkey is rejected
even though the passkey itself and the client version are valid.
**MAM FAQ reference:**
> *"If you are running your client over a VPN, but not your browser (or browser is
> on a different vpn tunnel), such as a docker container that also runs the vpn,
> you'll first need to be approved to use a VPN by staff (per rule 1.2). Then
> you'll want to use the Dynamic Seedbox endpoint to manage the client on a
> non-matching IP."*
**Resolution:**
1. Get staff approval via MAM ticket system
2. Set up [Mousehole](https://github.com/t-mart/mousehole) to call the Dynamic
Seedbox API: `https://www.myanonamouse.net/api/endpoint.php/3/json/dynamicSeedbox.php`
## Tracker Error: "Non-Whitelisted client or version"
**Bencoded tracker response:**
```
d8:intervali86400e12:min intervali86400e8:retry ini86400e14:failure reason58:Non-Whitelisted client or version https://s.mrd.ninja/CLNTe
```
**Check the allowed clients page:** https://s.mrd.ninja/CLNTe
**qBittorrent status on MAM:**
- Allowed: from 5.0.1 to latest 5.2.x line (confirmed as of 2026-07-09)
- qBittorrent Anonymous Mode IS rejected by MAM
- Peer ID format: `-qB5230-` for 5.2.3 on non-Windows
- User-agent: `qBittorrent/5.2.3`
**Known caveat:** The tracker-level whitelist filter may lag behind the web page.
If a new version is on the web whitelist but still getting rejected, there may be
a propagation delay.
## Fastresume Fields (via `strings`)
Key fields in `.fastresume` files that matter for troubleshooting:
| Field | Meaning |
|---|---|
| `paused` | 0 = active, 1 = paused |
| `disable_dht` | 0 = DHT enabled (should be 1 for private trackers) |
| `num_complete` | seeders count, 16777215 = sentinel (unknown) |
| `num_incomplete` | leechers count, 16777215 = sentinel (unknown) |
| `total_downloaded` | bytes downloaded so far |
| `active_time` | seconds the torrent has been active |
| `last_seen_complete` | 0 = never seen a complete copy |
| `last_download` | 0 = no downloads |
Ben code sentinel value 16777215 (0xFFFFFF) means "no data" — the tracker hasn't
returned peer information.
## Dynamic Seedbox API
- **Endpoint:** `https://www.myanonamouse.net/api/endpoint.php/3/json/dynamicSeedbox.php`
- **Requires:** Valid MAM session cookie
- **Purpose:** Registers the current IP of the calling client as an authorized
seedbox IP for the user's account
- **Frequency:** Called periodically by Mousehole (handled automatically once
configured)
### Docker Compose Patterns
### Adding Mousehole as a sidecar to existing gluetun + qBittorrent
Required changes to an existing docker-compose.yml:
1. **Gluetun ports:** add `- 127.0.0.1:5010:5010` (or `- 5010:5010` for LAN/KasmVNC access)
2. **Gluetun environment:** add `,5010` to `FIREWALL_VPN_INPUT_PORTS`
3. **New service:** add the mousehole service with `network_mode: "service:gluetun"`
4. **New volume:** add a `mousehole:` volume for cookie persistence
The mousehole service does NOT need to communicate with qBittorrent — it only
talks to the MAM API. It shares gluetun's network stack so outbound traffic goes
through the VPN tunnel.
### Docker Port Binding
When `docker compose restart` doesn't pick up compose file changes:
```
# This restarts with OLD config:
docker compose restart gluetun
# This recreates with NEW config:
docker compose up -d gluetun
```
To verify what ports are actually bound:
```
docker port gluetun
```
`127.0.0.1:5010` binding means host-only. If accessing from KasmVNC or another
Docker container, the port must bind to 0.0.0.0 (specify just `5010:5010` in
compose without an IP prefix).