A self-written reverse proxy and auth service for my home server.
- Go 95.6%
- Dockerfile 4.4%
| cmd/rb-proxy | ||
| config | ||
| internal | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| go.mod | ||
| LICENSE | ||
| README.md | ||
rb-proxy
A self-written reverse proxy and auth service for my home server.
All my projects run in separate Docker containers on a personal PC, exposed to the internet through a Cloudflare Tunnel. Instead of one tunnel rule per project, the tunnel sends every subdomain to this proxy. The proxy looks at the hostname and forwards the request to the right container. Private apps (like logs) are protected by access codes checked by a small auth service.
Cloudflare Tunnel
├── r-barroso.com → portfolio (direct)
└── *.r-barroso.com → proxy → auth (if protected) → container
Routes are defined in proxy/routes.json:
{
"logs.r-barroso.com": { "upstream": "http://logs:8080", "protected": true },
"demo.r-barroso.com": { "upstream": "http://demo:3000", "protected": false }
}
Rules
- Requests are routed by hostname.
r-barroso.comgoes straight to the portfolio throughcloudflared, so the portfolio stays up even if the proxy is down.- Unknown hostnames return
404. - Public routes are forwarded directly.
- Protected routes are forwarded only if the auth service says the request is allowed. Otherwise the user is redirected to
auth.r-barroso.com/login. - After a valid code is entered, the user is sent back to the page they originally asked for.
- Streaming responses (SSE, live logs) and WebSockets are passed through without buffering.
- Adding a project means adding one line to
routes.json. No Cloudflare changes are needed.
Security rules
- Access codes are stored as bcrypt hashes, never in plain text.
- Each code has scopes, so a code shared with a friend only opens the apps it lists.
- Each code has an expiry and a version. Bumping the version revokes every session created with it.
- Login attempts are rate-limited per IP, using Cloudflare's
CF-Connecting-IPheader. - Session cookies are signed (HMAC-SHA256) and set with
HttpOnly,SecureandSameSite=Lax. - The auth cookie is removed before forwarding, so apps never see it.
- Redirects after login only go to
*.r-barroso.com, to prevent open redirects. - The proxy fails closed: if the auth service is down, protected apps return an error instead of opening up.