stacks(wgtunnel): mirror deployed wstunnel server stack from ana-docker
wgtunnel deployed + accepted end-to-end (tunnel-dev): erebe/wstunnel v10.6.2 behind traefik on ana-docker, Host boring.phasefinal.com (Mode A anaprod cert), --restrict-to ana-wg:31337 (not an open relay). Mirror per fleet convention; full project in vh/wgtunnel.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# wgtunnel server stack — host env template.
|
||||
# Copy to `.env` next to compose.yaml on ana-docker and adjust as needed.
|
||||
# This template is committed; the real `.env` is gitignored (it is not secret
|
||||
# today, but the pattern keeps host-specific values out of git).
|
||||
|
||||
# Pinned erebe/wstunnel image tag. NEVER :latest. (v10.6.2 verified as the current
|
||||
# stable release, and `server --restrict-to <DEST:PORT>` confirmed against its --help.)
|
||||
WGTUNNEL_IMAGE_TAG=v10.6.2
|
||||
|
||||
# The WireGuard endpoint wstunnel unwraps to (ana-wg). `--restrict-to` enforces
|
||||
# that the server forwards only here — it is not an open relay.
|
||||
WG_TARGET=10.250.50.252:31337
|
||||
|
||||
# Public hostname — a deliberately innocuous SNI. DNS-only CNAME to the colo edge
|
||||
# (ana-srv1.phasefinal.com); never Cloudflare-proxied.
|
||||
TUNNEL_HOST=boring.phasefinal.com
|
||||
|
||||
# Internal plain-WebSocket port the container listens on; traefik forwards here.
|
||||
WSTUNNEL_PORT=8080
|
||||
@@ -0,0 +1,33 @@
|
||||
# wgtunnel — obfuscated WireGuard front (server stack)
|
||||
|
||||
The server-side stack for **wgtunnel**: a WireGuard tunnel that survives captive-portal /
|
||||
DPI networks (airplane, hotel) by wrapping WG in WebSocket-over-TLS on `:443`.
|
||||
|
||||
This is the **`erebe/wstunnel` server** behind traefik on **ana-docker**. traefik terminates
|
||||
TLS for `boring.phasefinal.com` (Mode A, `anaprod` Let's Encrypt cert) and forwards the
|
||||
WebSocket to this container, which unwraps it to UDP and delivers it to the WireGuard server
|
||||
at `ana-wg` (`10.250.50.252:31337`). `--restrict-to` pins the only forwarding target, so it
|
||||
is **not an open relay**.
|
||||
|
||||
- **Host:** ana-docker (`10.250.50.70`), on the external `traefik-net`.
|
||||
- **Public path:** `boring.phasefinal.com` (DNS-only CNAME → `ana-srv1.phasefinal.com` →
|
||||
`38.120.12.44`, never Cloudflare-proxied) → traefik `:443` → this container → `ana-wg:31337`.
|
||||
- **Image:** `ghcr.io/erebe/wstunnel` (pinned via `.env`, never `:latest`).
|
||||
- **Healthcheck:** greps `/proc/net/tcp` for the listener (the image has no `nc`/`curl` and
|
||||
dash lacks `/dev/tcp`).
|
||||
|
||||
## Deploy
|
||||
|
||||
```bash
|
||||
# canonical: stacks/wgtunnel/ -> /opt/docker/compose/wgtunnel/ on ana-docker
|
||||
scripts/deploy-stack.sh ana-docker wgtunnel # diffs vs live, prompts y/N
|
||||
# on the host: cp .env.example .env (adjust), then: docker compose up -d
|
||||
```
|
||||
|
||||
## Full project
|
||||
|
||||
The complete wgtunnel project (client-side bring-up, captive-portal handling, design docs)
|
||||
lives in its own repo, **`vh/wgtunnel`** (`~/development/wgtunnel`). This directory mirrors
|
||||
only the deployed server stack for fleet-convention drift tracking.
|
||||
|
||||
Author: Vuong Hoang.
|
||||
@@ -0,0 +1,38 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
wstunnel:
|
||||
image: ghcr.io/erebe/wstunnel:${WGTUNNEL_IMAGE_TAG}
|
||||
restart: unless-stopped
|
||||
# The image ENTRYPOINT is dumb-init; we override the command with the full
|
||||
# binary path so dumb-init execs it. `--restrict-to` is not in the image's
|
||||
# default CMD, so a full override is required.
|
||||
command:
|
||||
- /home/app/wstunnel
|
||||
- server
|
||||
- --restrict-to
|
||||
- ${WG_TARGET}
|
||||
- ws://0.0.0.0:${WSTUNNEL_PORT}
|
||||
networks:
|
||||
- traefik-net
|
||||
healthcheck:
|
||||
# The image is dash + grep/sed/cat only — no nc/wget/curl and dash has no
|
||||
# /dev/tcp (contract R5.4 "no usable probe binary" case). Verify the listener
|
||||
# via /proc/net/tcp instead: port 8080 = 0x1F90 (update if WSTUNNEL_PORT changes).
|
||||
test: ["CMD-SHELL", "grep -qi ':1F90 ' /proc/net/tcp /proc/net/tcp6 2>/dev/null || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik-net
|
||||
- "traefik.http.routers.wgtunnel.rule=Host(`${TUNNEL_HOST}`)"
|
||||
- traefik.http.routers.wgtunnel.entrypoints=websecure
|
||||
- traefik.http.routers.wgtunnel.tls=true
|
||||
- traefik.http.routers.wgtunnel.tls.certresolver=anaprod
|
||||
- traefik.http.services.wgtunnel.loadbalancer.server.port=${WSTUNNEL_PORT}
|
||||
|
||||
networks:
|
||||
traefik-net:
|
||||
external: true
|
||||
Reference in New Issue
Block a user