A secure authentication gateway that protects your self-hosted services with session-based access control.
Stop worrying about exposing services to the internet. Users authenticate once, and everyone on their network gets temporary access automatically. Services stay protected behind intelligent IP filtering.
β οΈ Important Security Note: Access is granted based on your public IP address. This means all users sharing the same public IP (e.g., people on the same home/office network, or behind the same NAT) will have access to the authorized services during an active session. This is by design - the portal is built to grant network-wide access, not device-specific access.
Knock-Knock Portal is a lightweight authentication gateway that sits in front of your services (databases, admin panels, APIs, etc.) and controls who can access them. Instead of managing complex firewall rules or VPNs, users simply log in through a web portal and get temporary access.
Think of it as:
- Port knocking with a web interface
- A simpler alternative to VPNs (WireGuard, Tailscale, OpenVPN)
- Like Authelia or Authentik, but for any TCP/UDP service (not just HTTP)
- A self-hosted Cloudflare Tunnel alternative with authentication
- Web-based firewall control for non-technical users
Perfect for:
- π Homelab enthusiasts protecting self-hosted services
- π’ Small teams needing simple service access control
- π§ Developers securing staging/test environments
- π Anyone exposing services to the internet safely
Works with any service:
- Databases (PostgreSQL, MySQL, MongoDB, Redis)
- Game servers (Minecraft, Valheim, CS:GO)
- Remote access (SSH, RDP, VNC)
- Media servers (Plex, Jellyfin, Emby)
- Smart home (Home Assistant, Node-RED)
- Development tools (GitLab, Jenkins, Portainer)
- Any TCP or UDP application
- Session-based authentication - Users log in and get time-limited access (configurable duration)
- Multi-IP session support - Automatically handles users switching networks (mobile/WiFi/VPN)
- Permanent IP allowlists - Whitelist trusted IPs/ranges that always have access
- Dynamic DNS support - Allow access from dynamic IPs using DNS hostnames
- Per-service permissions - Control which users can access which services
- Admin Dashboard - Manage all sessions, view connections, configure services
- User Portal - Clean interface for users to authenticate and monitor their access
- Real-time monitoring - See active sessions and live connections
- Session controls - Auto-extend sessions, manual session extension, instant revocation
- TCP/UDP proxy support - Works with any network protocol
- Port range mapping - Proxy multiple ports per service
- Zero downtime config reload - Update services without restarting
- Connection tracking - Monitor active connections in real-time
- JWT-based authentication - Secure token-based sessions
- Bcrypt password hashing - Industry-standard password protection
- Rate limiting - Built-in protection against brute force attacks
- Security headers - CSP, CORS, and modern security best practices
- IP blocklist - Permanently block malicious IPs
- Docker ready - One command to deploy
- Pre-built images - AMD64 and ARM64 support
- YAML configuration - Human-readable config files
- Environment variables - Easy secret management
- Health checks - Built-in monitoring endpoints
Use the included docker-compose.yml:
docker-compose up -dThat's it! π
Access the portal at http://localhost:8000
Default password: admin123
graph LR
A[User] -->|1. Login| B[Knock-Knock Portal]
B -->|2. Session Created| C[IP Allowlist]
A -->|3. Connect to Service| B
B -->|4. Check Allowlist| C
C -->|5. Allowed| B
B -->|6. Proxy Connection| D[Protected Service]
βββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββ
β User β β Knock-Knock Portal β β Service β
β (Browser) β β β β (Database) β
ββββββββ¬βββββββ ββββββββββββ¬ββββββββββββ ββββββββ¬ββββββββ
β β β
β 1. POST /api/portal/login β β
ββββββββββββββββββββββββββββ>β β
β β β
β 2. JWT Token + Session β β
β<ββββββββββββββββββββββββββββ€ β
β β β
β β 3. Add IP to Allowlist β
β ββββββββββββββ β
β β β β
β β<ββββββββββββ β
β β β
β 4. Connect β β
ββββββββββββββββββββββββββββββββββββββββββ>β β
β β β
β β 5. Check IP in Allowlist β
β ββββββββββββββ β
β β β β
β β<ββββββββββββ β
β β β
β β 6. Proxy to Upstream β
β βββββββββββββββββββββββββββββ>β
β β β
β β 7. Return Data β
β β<βββββββββββββββββββββββββββββ€
β β β
β 8. Data β β
β<ββββββββββββββββββββββββββββββββββββββββββ€ β
β β β
-
Authentication Phase
- User submits credentials via web portal
- Backend validates against bcrypt hash
- JWT token generated and returned
- User's IP added to session allowlist
-
Access Control Phase
- User attempts to connect to proxied service
- Portal checks IP against allowlist (session, permanent ranges, DNS)
- If allowed, connection is proxied to upstream service
- If denied, connection is rejected
-
Session Management
- Sessions have configurable duration
- Auto-extend on activity (optional)
- Multi-IP support for roaming users
- Manual session termination available
-
Proxy Layer
- TCP/UDP transparent proxy
- Port mapping (external β internal)
- Real-time connection tracking
- Zero-copy data transfer
The portal supports multiple authentication methods:
| Method | Description | Use Case |
|---|---|---|
| π Authenticated Session | User logs in via web portal | Remote workers, dynamic IPs |
| π Permanent IP Range | Static allowlist of IP ranges | Office networks, home IPs |
| π Dynamic DNS | DNS hostname resolution | Dynamic home IPs with DDNS |
| π€ Per-User Permissions | Service-level access control | Team members with different roles |
All configuration is done through the web-based admin panel. You can configure services, users, IP allowlists, and more directly from the UI.
π‘ Pro Tip: No YAML editing required - everything is managed through the intuitive web interface!
Images are automatically built for AMD64 and ARM64:
# AMD64 (Intel/AMD)
docker pull ghcr.io/davbauer/knock-knock-portal:main-amd64
# ARM64 (Apple Silicon, Raspberry Pi)
docker pull ghcr.io/davbauer/knock-knock-portal:main-arm64See docker-compose.yml for the complete configuration.
For production, update the docker-compose.yml with your own secure credentials.
# Admin password hash (bcrypt)
htpasswd -bnBC 12 "" your-strong-password | tr -d ':\n'
# JWT secret (32 bytes base64)
openssl rand -base64 32Update these values in your docker-compose.yml environment variables, then deploy:
docker-compose up -d- π₯ User Management - View all active sessions, see connected IPs
- π Connection Monitoring - Real-time view of all active connections
- βοΈ Service Configuration - Add/edit/remove services on the fly
- π« Session Control - Terminate sessions instantly
- π Access Statistics - Monitor usage and connection patterns
- π Config Reload - Update configuration without downtime
Want to contribute or run locally?
# Frontend (Svelte 5 + TypeScript)
cd frontend
yarn install
yarn dev
# Backend (Go 1.24+)
cd backend
go mod download
go run cmd/server/main.goFrontend:
- Svelte 5 (with runes)
- SvelteKit
- TypeScript
- TailwindCSS
- Ark UI
Backend:
- Go 1.24+
- Gin (HTTP framework)
- JWT authentication
- Bcrypt password hashing
- YAML configuration
This project is licensed under a Proprietary License with Limited Grant. See the LICENSE file for details.
For commercial licensing inquiries, contact @davbauer.
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
Made with β€οΈ by David Bauer
