
Painel de firewall UFW para múltiplos hosts — explica regras em linguagem simples, detecta lacunas de segurança e fornece diagnósticos de conexão.
Painel de firewall UFW para múltiplos hosts. Conecta-se a hosts Linux via SSH, analisa regras de firewall e portas de escuta, explica tudo em português claro e sinaliza lacunas de segurança.

| Rota | Descrição |
|---|---|
/ | Painel de visão geral com cartões de host, pílulas de serviço, contagens de lacunas |
Navegador --> Cloudflare Tunnel --> Proxy Reverso --> FencePost (:8890)
Container FastAPI
|-- SSH --> Host 1 (ufw status, ss -tlnp)
|-- SSH --> Host 2
|-- SSH --> Host N
'-- POST --> Webhook de notificação
O FencePost é somente leitura — ele nunca modifica regras de firewall, apenas as reporta.
<user> ALL=(ALL) NOPASSWD: /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered, /usr/bin/ss -tlnp
git clone <repo-url> && cd fencepost
# Adicione sua chave SSH
cp ~/.ssh/your_key ssh/id_ed25519
chmod 600 ssh/id_ed25519
# Crie seu arquivo de ambiente a partir do modelo
cp .env.example .env
# Edite .env com credenciais reais
timezone: Australia/Melbourne
hosts:
- name: Meu Servidor
hostname: 192.168.1.10
ssh_user: deploy
ssh_port: 22
is_docker_host: false
networks:
"192.168.1.0/24": "LAN"
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Carregar variáveis de ambiente (bash/zsh)
export $(grep -v '^#' .env | xargs)
uvicorn app.main:app --reload --port 8890
Abra http://localhost:8890.
Nota: o modo local usa a chave SSH no caminho especificado em config.yaml (ssh.key_path). Para desenvolvimento local, talvez você queira sobrescrever isso para apontar para o seu ssh/id_ed25519 local:
ssh:
key_path: ssh/id_ed25519
timeout: 10
docker compose up -d --build
Abra http://localhost:8890. O container lê as credenciais automaticamente do .env via compose.yaml.
As credenciais são armazenadas em .env (ignorado pelo git) e referenciadas pelo compose.yaml. Nunca envie segredos para o repositório.
app/
main.py # Rotas e autenticação do FastAPI
models.py # Dataclasses: HostFirewallState, UFWRule, ListeningPort
parser.py # Analisa a saída do ufw status e ss
explainer.py # Traduz regras para português claro
diagnose.py # Motor de diagnóstico de conexão
gap_detector.py # Encontra portas de escuta descobertas
ssh_client.py # Wrapper para Paramiko, busca paralela de hosts
eventfeed.py # Detecção de alterações e postagem em webhook
templates/
base.html # Layout, CSS, navegação
overview.html # Grade do painel de hosts
host_detail.html # Visualização detalhada por host com abas
diagnose.html # Formulário e resultados do diagnóstico de conexão
login.html # Página de autenticação
config.yaml # Definições de hosts, VLANs, dispositivos, fuso horário
compose.yaml # Definição do serviço Docker Compose
Dockerfile # Imagem Python 3.12 slim
.env.example # Modelo para variáveis de ambiente
ssh/ # Diretório de chaves SSH (a chave não é commitada)
data/ # Estado em tempo de execução (last_state.json, não commitado)
config.yaml sob hosts:ssh-copy-id -i ssh/id_ed25519.pub user@host/etc/sudoers.d/fencepost no host com as regras NOPASSWD necessáriasdocker compose up -d --buildQuando configurado em config.yaml com uma variável de ambiente NOTIFICATIONS_API_KEY, o FencePost envia eventos de alteração a cada atualização do painel:
Os eventos incluem chaves de idempotência para evitar duplicatas.
MIT
/host/{name} | Detalhe do host com visualização em abas: regras explicadas, portas descobertas, portas de escuta, saída bruta |
/diagnose | Ferramenta de diagnóstico de conexão com visualização de rastreio regra por regra |
/login | Autenticação baseada em sessão |
| Seção | Finalidade |
|---|
timezone | Fuso horário IANA para os carimbos de data/hora exibidos (ex.: Australia/Melbourne, UTC) |
hosts | Array de alvos SSH: name, hostname, ssh_user, ssh_port, is_docker_host |
ssh | key_path (caminho para a chave privada) e timeout em segundos |
networks | Mapeamento CIDR para nome das VLANs — usado nas explicações de regras e diagnósticos |
devices | IPs nomeados para os botões de seleção rápida na página de diagnóstico |
notifications | Webhook opcional: url, channel (chave de API definida via variável de ambiente) |
| Variável | Padrão | Descrição |
|---|
FENCEPOST_USERNAME | admin | Nome de usuário para login |
FENCEPOST_PASSWORD | fencepost | Senha para login |
FENCEPOST_SECRET_KEY | change-me | Chave de assinatura do cookie de sessão |
FENCEPOST_CONFIG | config.yaml | Caminho para o arquivo de configuração |
NOTIFICATIONS_API_KEY | Token Bearer para o webhook de notificações |