223 lines
7.5 KiB
Markdown
223 lines
7.5 KiB
Markdown
---
|
|
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)
|