Commit Graph

15 Commits

Author SHA1 Message Date
Leopere 58092e24c8
Add reference Traefik stack config for replication
ci/woodpecker/push/woodpecker Pipeline was successful Details
Stripped-down, generic version of the Traefik Swarm setup that the
tunnel-server depends on for dynamic label-based routing. Sanitized
of infrastructure-specific details so others can replicate the setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 16:06:29 -05:00
Leopere fd31e40285
Revert "Switch from Swarm labels to Traefik file provider for routing"
ci/woodpecker/push/woodpecker Pipeline was successful Details
This reverts commit 64347ce8a5.
2026-02-09 15:07:34 -05:00
Leopere 64347ce8a5
Switch from Swarm labels to Traefik file provider for routing
ci/woodpecker/push/woodpecker Pipeline was successful Details
docker service update --label-add was restarting the tunnel-server
container on every label change, breaking all active SSH tunnels.

Now the server writes YAML config files to /root/traefik/dynamic/ on
the Traefik host via SSH. Traefik's file provider watches the directory
and picks up changes without any container restarts. Clients can
reconnect reliably after server restarts with no restart loops.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 15:06:21 -05:00
Leopere 2f8d35903c
Add restart: always to local compose services
ci/woodpecker/push/woodpecker Pipeline was successful Details
Ensures tunnel clients and test services restart automatically
whenever Docker is available, including after host reboots.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 15:00:11 -05:00
Leopere 85a286e5f1
Fix basicauth: don't double dollar signs for docker service update
ci/woodpecker/push/woodpecker Pipeline was successful Details
The bcrypt hash was escaping $ to $$ which is only needed in compose
files. docker service update --label-add with single-quoted values
preserves dollar signs literally, so doubling them broke Traefik auth.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 14:46:50 -05:00
Leopere 2867c2bb0a
Add test stack and ignore compiled binaries
ci/woodpecker/push/woodpecker Pipeline was successful Details
docker-compose.test.yml spins up an nginx + tunnel-client pointing at
testrst.nixc.us with basicauth test:test for end-to-end validation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 14:41:50 -05:00
Leopere 37081ab53e
Add optional HTTP Basic Auth support for tunnel clients
ci/woodpecker/push/woodpecker Pipeline failed Details
Clients can now set TUNNEL_AUTH_USER and TUNNEL_AUTH_PASS to have the
server add a Traefik basicauth middleware in front of the tunnel route.
Credentials are sent as tunnel metadata over the SSH channel and the
server generates a bcrypt htpasswd entry for Traefik's Docker labels.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 14:40:58 -05:00
Leopere 4a9a210aed
ci: re-deploy after generating tunnel_host_key on remote
ci/woodpecker/push/woodpecker Pipeline was successful Details
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:48:06 -05:00
Leopere 42893cf7e7
Replace Docker secrets with host bind mounts for SSH keys
ci/woodpecker/push/woodpecker Pipeline failed Details
Keys are now mounted directly from /root/.ssh/ on the host node
instead of using Docker Swarm secrets. CI deploy step simplified
to verify key files exist and clean up leftover secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:45:56 -05:00
Leopere 443e077e46
ci: trigger pipeline rebuild
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:41:05 -05:00
Leopere f6b40d2432
Fix SSH to ingress: port 65522, auto-load companion cert
- keyutil.go / client ssh.go: if <key>-cert.pub exists next to
  the private key, load it automatically (mirrors openssh behavior)
- stack.production.yml: TRAEFIK_SSH_HOST uses port 65522

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:38:31 -05:00
Leopere 39fe9bc40c
Add docker-compose.override.yml to gitignore
Local dev override mounts real SSH keys for testing the tunnel
server and client without needing Swarm secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:27:03 -05:00
Leopere b2820ed47f
Rework for Swarm deploy on ingress.nixc.us
- labels.go: use `docker service update --label-add/rm` via SSH to
  dynamically manage Traefik labels on the Swarm service itself,
  matching how traefik-http discovers routes from Docker swarm labels
- stack.production.yml: constrain to ingress.nixc.us, host-mode port
  2222, base traefik.enable labels, SWARM_SERVICE_NAME env
- cmd/server/main.go: SWARM_SERVICE_NAME replaces TRAEFIK_CONFIG_DIR
- .woodpecker.yml: hardcode stack name better-argo-tunnels, update
  smoke test env vars

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:24:13 -05:00
Leopere ccead8733a
Add Woodpecker CI, production stack, and compose files
- .woodpecker.yml: test, build+push x86 images, smoke test, deploy to Swarm
- docker-compose.production.yml: CI build targets for server + client images
- stack.production.yml: Swarm stack with secrets, Traefik TCP labels, port range
- docker-compose.yml: simplified to minimal build+image (matches smsbridge pattern)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:18:54 -05:00
Leopere d5a805853a
Initial commit: reverse SSH tunnel server for Traefik
Go binary pair (server + client) that establishes reverse SSH tunnels
and dynamically registers Traefik routes by SSHing into the ingress
host to write file-provider config. Clients need only a private key,
server address, domain, and local port as envvars.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:16:41 -05:00