
Knocker, un servizio di controllo accessi basato su knock per il tuo homelab

Knocker è un servizio self-hosted che fornisce un gateway di autorizzazione "knock-knock" single-packet (SPA) basato su HTTP per la tua Homelab, con client web, cli + gnome e android. Può essere utilizzato come autenticazione per il tuo reverse proxy come Caddy, o anche a livello di firewall utilizzando l'integrazione FirewallD. Ti permette di mantenere i tuoi servizi completamente privati, aprendoli on-demand solo per indirizzi IP autorizzati.
È ideale per ambienti homelab in cui vuoi esporre servizi a internet senza una connessione VPN persistente, minimizzando al contempo la superficie d'attacco pubblica.
Knocker-Web App web PWA statica che supporta il knocking (whitelisting) al ricaricamento
Knocker-CLI Una CLI scritta in Go con supporto per knock in background opzionalmente attivati da cambi di IP.
Knocker-gnome un'estensione di GNOME costruita sopra Knocker-cli.
Knocker-EXPO Un'app Android sperimentale scritta in React EXPO con supporto per richieste di knock in background
sequenceDiagram
participant User
participant Caddy as Reverse Proxy (Caddy)
participant Knocker
participant Service as Protected Service
User->>Caddy: HTTP request to protected service
Caddy->>Knocker: GET /verify (copies X-Forwarded-For)
Knocker-->>Knocker: check always_allowed_ips / excluded_paths / whitelist
alt IP whitelisted
Knocker-->>Caddy: 200 OK (empty body)
Caddy->>Service: forward request
Service-->>Caddy: 200 OK
Caddy-->>User: 200 OK
else IP not whitelisted
Knocker-->>Caddy: 401 Unauthorized (empty body)
Caddy-->>User: 401 Unauthorized
end
Note over User,Knocker: Performing a "knock" (to add whitelist entry)
User->>Knocker: POST /knock (X-Api-Key, optional ip_address, ttl)
Knocker->>Knocker: validate API key, determine client IP
Knocker->>Knocker: update whitelist.json with expiry
Knocker-->>User: 200 OK (whitelisted_entry, expires_at, expires_in_seconds)
Questo progetto è progettato per essere distribuito come container Docker utilizzando il file docker-compose.yml fornito. Utilizza le immagini Docker precompilate con supporto per AMD64, ARMv8 e ARMv7.
Knocker fornisce diversi tag di immagine per diversi casi d'uso:
latest Ultima versione stabile (consigliata per la produzione)v1.2.3 Tag di versione specifica (versioni bloccate)main Ramo di sviluppo (aggiornamenti continui, potrebbe essere instabile)Configurazione:
knocker.example.yaml in knocker.yaml.knocker.yaml con le tue stringhe casuali e sicure.trusted_proxies in knocker.yaml: deve corrispondere alla sottorete della rete del reverse proxy (docker network inspect xxx)whitelist.storage_path nella directory di lavoro dell'app, in /data o /tmp.firewalld.enabled: true e regolando le impostazioni correlate. Nota: questo richiede che il container venga eseguito come root.Avvia il servizio:
docker compose up -d
Questo scaricherà l'immagine knocker precompilata e avvierà i servizi knocker e caddy.
Knocker funziona come gateway di autenticazione per il tuo reverse proxy. Offre un endpoint verify per verificare se l'IP richiedente è in whitelist o meno; in caso contrario risponde con un 401 e il reverse proxy rifiuta la connessione.
Caddy ha la direttiva forward_auth per verificare le connessioni tramite un endpoint di autenticazione.
Definisci uno snippet riutilizzabile: è buona pratica definire uno snippet nel tuo Caddyfile per il controllo di autenticazione.
Proteggi i tuoi servizi: importa lo snippet per qualsiasi servizio che vuoi proteggere.
Esempio di Caddyfile:
# Caddyfile
# Define a reusable snippet for the knock-knock check.
# It points to the knocker service using Docker's internal DNS.
(knocker_auth) {
forward_auth knocker:8000 {
uri /verify
}
}
# The public endpoint for performing the knock.
# Make sure this domain points to your Caddy server's IP.
knock.your-domain.com {
reverse_proxy knocker:8000
}
# An example protected service.
jellyfin.your-domain.com {
import knocker_auth # Apply the forward_auth check
reverse_proxy jellyfin_service_name:8096
}
Quando un utente non è in whitelist, la direttiva forward_auth di Caddy restituisce una risposta 401 Unauthorized con corpo vuoto.
Nota importante: la direttiva handle_errors di Caddy non funziona con le risposte forward_auth. La risposta di errore proviene direttamente dal servizio di autenticazione (knocker), non da Caddy stesso, quindi handle_errors non può intercettare o modificare queste risposte.
Knocker fornisce un'integrazione avanzata del firewall tramite firewalld, creando regole firewall dinamiche e basate sul tempo che scadono automaticamente in base al TTL specificato nelle richieste di knock. Questa funzionalità opera a livello di rete, permettendoti di usare Knocker per servizi non HTTP come SSH o server di gioco.
sequenceDiagram
participant Client as User
participant Firewall as Firewalld (knocker zone)
participant Knocker
participant Service as Protected Service (port 22)
Note over Client,Firewall: Initial state — monitored port is blocked by default
Client->>Firewall: TCP SYN to Service:22
Firewall-->>Client: DROP (no response)
Note over Client,Knocker: User performs a knock to whitelist their IP
Client->>Knocker: POST /knock (X-Api-Key, optional ip_address, ttl)
Knocker->>Knocker: validate API key & determine client IP
Knocker->>Firewall: add rich accept rule for client IP on port 22 with timeout
Firewall-->>Knocker: success