Skip to content

Commit 7ae3607

Browse files
committed
fix: move auth middleware to only protect /api endpoints
- Public access for website, health, metrics, and simple provisioning - API key required only for /api/tunnels management endpoints - Prevents unauthorized listing of all active tunnels - Maintains open access for creating tunnels via curl
1 parent b5089c4 commit 7ae3607

File tree

5 files changed

+120
-8
lines changed

5 files changed

+120
-8
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ CLAUDE.md
33
.claude/
44
tunnel.conf
55
config.toml
6-
dist/*
76

87
# Binaries
98
bin/

docker-compose.prod-env.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
services:
2+
arbok:
3+
image: ghcr.io/mr-karan/arbok:latest
4+
container_name: arbok
5+
environment:
6+
TZ: Asia/Kolkata
7+
# Override config via environment variables
8+
ARBOK_SERVER_APP__DOMAIN: "tunnel.yourdomain.com"
9+
ARBOK_SERVER_AUTH__API_KEYS: '["admin-mrkaran-prod-VB7PGkPB9jmzZCXXzC"]'
10+
ARBOK_SERVER_SERVER__PRIVATE_KEY: "uLu0FutcktFMZ1rTMKvE/LRkGBAeoBJcMvoX4a+Sxmw="
11+
ARBOK_SERVER_SERVER__CIDR: "10.100.0.0/24"
12+
ARBOK_SERVER_SERVER__LISTEN_PORT: "54321"
13+
ARBOK_SERVER_HTTP__LISTEN_ADDR: ":8080"
14+
ports:
15+
- "100.64.13.114:17770:8080"
16+
- "100.64.13.114:54321:54321/udp"
17+
cap_add:
18+
- NET_ADMIN
19+
- SYS_MODULE
20+
sysctls:
21+
- net.ipv4.ip_forward=1
22+
- net.ipv6.conf.all.forwarding=1
23+
devices:
24+
- /dev/net/tun:/dev/net/tun
25+
healthcheck:
26+
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:8080/health -O - || exit 1"]
27+
interval: 60s
28+
timeout: 10s
29+
retries: 3
30+
start_period: 40s
31+
restart: unless-stopped

docker-compose.prod.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
services:
2+
arbok:
3+
image: ghcr.io/mr-karan/arbok:latest
4+
container_name: arbok
5+
environment:
6+
TZ: Asia/Kolkata
7+
configs:
8+
- source: arbok_config
9+
target: /app/config.toml
10+
ports:
11+
- "100.64.13.114:17770:8080"
12+
- "100.64.13.114:54321:54321/udp" # WireGuard port
13+
cap_add:
14+
- NET_ADMIN
15+
- SYS_MODULE
16+
sysctls:
17+
- net.ipv4.ip_forward=1
18+
- net.ipv6.conf.all.forwarding=1
19+
devices:
20+
- /dev/net/tun:/dev/net/tun
21+
healthcheck:
22+
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:8080/health -O - || exit 1"]
23+
interval: 60s
24+
timeout: 10s
25+
retries: 3
26+
start_period: 40s
27+
restart: unless-stopped
28+
command: ["./arbok", "--config", "/app/config.toml"]
29+
30+
configs:
31+
arbok_config:
32+
content: |
33+
[app]
34+
verbose = false
35+
domain = "tunnel.yourdomain.com" # CHANGE THIS
36+
37+
[auth]
38+
api_keys = [] # Add API keys like ["key1", "key2"] if needed
39+
40+
[tunnel]
41+
default_ttl = "24h"
42+
cleanup_interval = "5m"
43+
44+
[server]
45+
cidr = "10.100.0.0/24"
46+
listen_port = 54321
47+
private_key = "YOUR_WIREGUARD_PRIVATE_KEY" # CHANGE THIS - generate with: wg genkey
48+
49+
[http]
50+
listen_addr = ":8080"
51+
allowed_origins = ["*"]

gen-wg-key.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
# Generate and validate WireGuard private key for Arbok server
3+
4+
echo "Generating WireGuard private key..."
5+
PRIVATE_KEY=$(wg genkey)
6+
PUBLIC_KEY=$(echo "$PRIVATE_KEY" | wg pubkey)
7+
8+
# Validate the key is proper base64
9+
if echo "$PRIVATE_KEY" | base64 -d >/dev/null 2>&1; then
10+
echo "✓ Key validation passed"
11+
else
12+
echo "✗ Key validation failed"
13+
exit 1
14+
fi
15+
16+
# Check key length (should be 32 bytes when decoded)
17+
KEY_LENGTH=$(echo "$PRIVATE_KEY" | base64 -d | wc -c)
18+
if [ "$KEY_LENGTH" -eq 32 ]; then
19+
echo "✓ Key length correct (32 bytes)"
20+
else
21+
echo "✗ Key length incorrect (got $KEY_LENGTH bytes, expected 32)"
22+
exit 1
23+
fi
24+
25+
echo ""
26+
echo "=== WireGuard Keys Generated ==="
27+
echo "Private Key: $PRIVATE_KEY"
28+
echo "Public Key: $PUBLIC_KEY"
29+
echo ""
30+
echo "Add this exact private key to your docker-compose.yml:"
31+
echo "private_key = \"$PRIVATE_KEY\""

internal/api/server.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,14 @@ func NewAPIServer(cfg Config, logger logf.Logger, tun *tunnel.Tunnel, reg *regis
5454
}
5555

5656
func (s *Server) setupRoutes() {
57-
// Apply global middleware
57+
// Global middleware for all routes
5858
s.router.Use(
5959
middleware.Recovery(s.logger),
6060
middleware.Logger(s.logger),
6161
middleware.CORS(s.cfg.AllowedOrigins),
62-
s.auth.Middleware,
6362
)
6463

65-
// Static website files
64+
// Static website
6665
webFS, err := fs.Sub(webFiles, "web")
6766
if err != nil {
6867
s.logger.Error("failed to create web filesystem", "error", err)
@@ -71,21 +70,22 @@ func (s *Server) setupRoutes() {
7170
s.router.HandleFunc("/", s.handleWebsite).Methods("GET")
7271
}
7372

74-
// Public endpoints
73+
// Health and metrics endpoints
7574
s.router.HandleFunc("/health", s.handleHealth).Methods("GET")
7675
s.router.HandleFunc("/metrics", metrics.Handler()).Methods("GET")
7776

78-
// API endpoints
77+
// Protected API endpoints
7978
api := s.router.PathPrefix("/api").Subrouter()
79+
api.Use(s.auth.Middleware)
8080
api.HandleFunc("/tunnel/{port:[0-9]+}", s.handleCreateTunnel).Methods("POST")
8181
api.HandleFunc("/tunnel/{id}", s.handleGetTunnel).Methods("GET")
8282
api.HandleFunc("/tunnel/{id}", s.handleDeleteTunnel).Methods("DELETE")
8383
api.HandleFunc("/tunnels", s.handleListTunnels).Methods("GET")
8484

85-
// Simple provisioning endpoint (curl-friendly)
85+
// Simple tunnel provisioning
8686
s.router.HandleFunc("/{port:[0-9]+}", s.handleProvisionSimple).Methods("GET")
8787

88-
// Wildcard routing for tunnel traffic
88+
// Tunnel traffic proxy
8989
s.router.PathPrefix("/").HandlerFunc(s.handleTunnelProxy)
9090
}
9191

0 commit comments

Comments
 (0)