
Knocker, um serviço de controle de acesso baseado em knock para seu homelab.

Knocker é um serviço auto-hospedado que fornece um gateway de autorização de pacote único (SPA) "knock-knock" baseado em HTTP para o seu Homelab, com clientes web, cli + gnome e android. pode ser usado como autenticação para o seu proxy reverso como o Caddy, ou até mesmo no nível do firewall usando a integração com o FirewallD. Ele permite manter os seus serviços completamente privados, abrindo-os sob demanda apenas para endereços IP autorizados.
Isto é ideal para ambientes de homelab onde você quer expor serviços à internet sem uma conexão VPN persistente, enquanto minimiza a sua superfície de ataque voltada ao público.
Knocker-Web Aplicação web PWA estática que suporta knock (lista de permissões) ao recarregar
Knocker-CLI Uma cli escrita em go com suporte para knocks em segundo plano opcionalmente acionados por mudanças de ip.
Knocker-gnome uma extensão gnome construída sobre o Knocker-cli.
Knocker-EXPO Uma aplicação Android experimental escrita em React EXPO com suporte para pedidos de knock em segundo plano
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)
Este projeto foi concebido para ser implantado como um container Docker usando o ficheiro docker-compose.yml fornecido. Utiliza as imagens docker pré-construídas com suporte para AMD64, ARMv8 e ARMv7
Knocker fornece diferentes tags de imagem para diferentes casos de uso:
latest Última versão estável (recomendada para produção)v1.2.3 Tags de versão específicas (versões fixadas)main Ramo de desenvolvimento (atualizações contínuas, pode ser instável)Configuração:
knocker.example.yaml para knocker.yaml.knocker.yaml; o exemplo contém intencionalmente nenhum valor padrão utilizável.trusted_proxies no knocker.yaml: deve conter apenas o(s) próprio(s) endereço(s) do proxy reverso, não a sua sub-rede. Como o knocker só confia no X-Forwarded-For de um par listado, uma entrada de sub-rede inteira (por exemplo, 172.16.238.0/24) transforma todos os containers nessa rede numa autoridade de identidade -- qualquer um deles poderia reivindicar qualquer IP de cliente, ou colocar endereços arbitrários na lista de permissões com uma chave normal. O Docker não atribui IPs de container estáveis por padrão, então fixe o proxy com ipv4_address / ipv6_address (veja o serviço caddy comentado no docker-compose.yml) e liste esses endereços exatos /32 e /128.whitelist.storage_path sob o diretório de trabalho da aplicação, /data, ou /tmp.firewalld.enabled: true e ajustando as configurações relacionadas. Nota: Isto requer que o container seja executado como root.Executar o Serviço:
docker compose up -d
Isto irá descarregar a imagem knocker pré-construída e iniciar ambos os serviços knocker e caddy.
Knocker funciona atuando como um gateway de autenticação para o seu Proxy Reverso. Oferece um endpoint de verificação, para verificar se o IP solicitante está na lista de permissões ou não, se não estiver irá responder com um 401 e o proxy reverso irá recusar a conexão.
O Caddy tem a diretiva forward_auth para verificar conexões usando um endpoint de autenticação.
Definir um Snippet Reutilizável: É uma boa prática definir um snippet no seu Caddyfile para a verificação de autenticação.
Proteger os Seus Serviços: Importe o snippet para qualquer serviço que queira proteger.
Exemplo 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 {
request_body {
max_size 4KB
}
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 um utilizador não está na lista de permissões, a diretiva forward_auth do Caddy irá devolver uma resposta 401 Unauthorized com corpo vazio.
Nota Importante: A diretiva handle_errors do Caddy não funciona com respostas de forward_auth. A resposta de erro vem diretamente do serviço de autenticação (knocker), não do próprio Caddy, então handle_errors não pode intercetar ou modificar estas respostas.
Knocker fornece integração avançada com firewall através do firewalld, criando regras de firewall dinâmicas e baseadas em tempo que expiram automaticamente com base no TTL especificado nos pedidos de knock. Esta funcionalidade opera ao nível da rede, permitindo-lhe usar o knocker para serviços não-http como ssh ou servidores de jogos.