
Knocker, un service de contrôle d'accès basé sur le knock pour votre homelab

Knocker est un service auto-hébergé qui fournit une passerelle d'autorisation à paquet unique (SPA) de type "toc-toc" basée sur HTTP pour votre Homelab, avec des clients web, CLI + GNOME et Android. Il peut être utilisé comme authentification pour votre proxy inverse comme Caddy, ou même au niveau du pare-feu via l'intégration FirewallD. Il vous permet de garder vos services complètement privés, en ne les ouvrant à la demande que pour les adresses IP autorisées.
C'est idéal pour les environnements homelab où vous souhaitez exposer des services à Internet sans connexion VPN permanente, tout en minimisant votre surface d'attaque publique.
Knocker-Web Application web PWA statique qui prend en charge le knock (mise sur liste blanche) au rechargement
Knocker-CLI Une CLI écrite en Go avec prise en charge des knocks en arrière-plan, éventuellement déclenchés par des changements d'IP.
Knocker-gnome une extension GNOME construite au-dessus de Knocker-cli.
Knocker-EXPO Une application Android expérimentale écrite en React EXPO avec prise en charge des requêtes de knock en arrière-plan
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)
Ce projet est conçu pour être déployé comme conteneur Docker à l'aide du fichier docker-compose.yml fourni. Il utilise les images Docker préconstruites avec prise en charge d'AMD64, ARMv8 et ARMv7.
Knocker fournit différents tags d'images pour différents cas d'utilisation :
latest Dernière version stable (recommandée pour la production)v1.2.3 Tags de version spécifiques (versions épinglées)main Branche de développement (mises à jour continues, peut être instable)Configuration :
knocker.example.yaml en knocker.yaml.knocker.yaml avec vos propres chaînes aléatoires sécurisées.trusted_proxies dans knocker.yaml ; elle doit correspondre au sous-réseau du réseau du proxy inverse (docker network inspect xxx).whitelist.storage_path dans le répertoire de travail de l'application, /data ou /tmp.firewalld.enabled: true et en ajustant les paramètres associés. Remarque : cela nécessite que le conteneur s'exécute en tant que root.Exécutez le service :
docker compose up -d
Cela récupérera l'image knocker préconstruite et démarrera à la fois les services knocker et caddy.
Knocker agit comme une passerelle d'authentification pour votre proxy inverse. Il offre un endpoint de vérification pour contrôler si l'IP requérante est autorisée ou non ; si ce n'est pas le cas, il répond par un 401 et le proxy inverse refuse la connexion.
Caddy dispose de la directive forward_auth pour vérifier les connexions à l'aide d'un endpoint d'authentification.
Définissez un snippet réutilisable : il est recommandé de définir un snippet dans votre Caddyfile pour la vérification d'authentification.
Protégez vos services : importez le snippet pour tout service que vous souhaitez protéger.
Exemple de 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
}
Lorsqu'un utilisateur n'est pas autorisé, la directive forward_auth de Caddy renvoie une réponse 401 Unauthorized avec un corps vide.
Remarque importante : la directive handle_errors de Caddy ne fonctionne pas avec les réponses forward_auth. La réponse d'erreur provient directement du service d'authentification (knocker), et non de Caddy lui-même ; handle_errors ne peut donc pas intercepter ni modifier ces réponses.
Knocker fournit une intégration avancée du pare-feu via firewalld, créant des règles de pare-feu dynamiques et temporisées qui expirent automatiquement en fonction du TTL spécifié dans les requêtes de knock. Cette fonctionnalité opère au niveau réseau, ce qui vous permet d'utiliser knocker pour des services non-HTTP comme SSH ou des serveurs de jeu.
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)