
Tableau de bord de pare-feu UFW multi-hôtes — explique les règles en langage clair, détecte les failles de sécurité et fournit des diagnostics de connexion
Tableau de bord de pare-feu UFW multi-hôtes. Se connecte aux hôtes Linux via SSH, analyse les règles de pare-feu et les ports en écoute, explique tout en langage clair et signale les failles de sécurité.

| Route | Description |
|---|---|
/ | Tableau de bord avec cartes hôtes, pastilles de services, compteurs de failles |
Browser --> Cloudflare Tunnel --> Reverse Proxy --> FencePost (:8890)
FastAPI container
|-- SSH --> Host 1 (ufw status, ss -tlnp)
|-- SSH --> Host 2
|-- SSH --> Host N
'-- POST --> Notification webhook
FencePost est en lecture seule -- il ne modifie jamais les règles de pare-feu, il se contente de les rapporter.
<user> ALL=(ALL) NOPASSWD: /usr/sbin/ufw status verbose, /usr/sbin/ufw status numbered, /usr/bin/ss -tlnp
git clone <repo-url> && cd fencepost
# Add your SSH key
cp ~/.ssh/your_key ssh/id_ed25519
chmod 600 ssh/id_ed25519
# Create your environment file from the template
cp .env.example .env
# Edit .env with real credentials
timezone: Australia/Melbourne
hosts:
- name: My Server
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
# Load env vars (bash/zsh)
export $(grep -v '^#' .env | xargs)
uvicorn app.main:app --reload --port 8890
Ouvrez http://localhost:8890.
Remarque : le mode local utilise la clé SSH au chemin spécifié dans config.yaml (ssh.key_path). Pour le développement local, vous voudrez peut-être le remplacer pour pointer vers votre ssh/id_ed25519 local :
ssh:
key_path: ssh/id_ed25519
timeout: 10
docker compose up -d --build
Ouvrez http://localhost:8890. Le conteneur lit les identifiants depuis .env automatiquement via compose.yaml.
Les identifiants sont stockés dans .env (ignoré par git) et référencés par compose.yaml. Ne committez jamais de secrets dans le dépôt.
app/
main.py # FastAPI routes and auth
models.py # HostFirewallState, UFWRule, ListeningPort dataclasses
parser.py # Parses ufw status and ss output
explainer.py # Translates rules to plain English
diagnose.py # Connection diagnostic engine
gap_detector.py # Finds uncovered listening ports
ssh_client.py # Paramiko wrapper, parallel host fetching
eventfeed.py # Change detection and webhook posting
templates/
base.html # Layout, CSS, navigation
overview.html # Host dashboard grid
host_detail.html # Per-host tabbed detail view
diagnose.html # Connection diagnostic form and results
login.html # Authentication page
config.yaml # Host definitions, VLANs, devices, timezone
compose.yaml # Docker Compose service definition
Dockerfile # Python 3.12 slim image
.env.example # Template for environment variables
ssh/ # SSH key directory (key not committed)
data/ # Runtime state (last_state.json, not committed)
config.yaml sous hosts:ssh-copy-id -i ssh/id_ed25519.pub user@host/etc/sudoers.d/fencepost sur l'hôte avec les règles NOPASSWD requisesdocker compose up -d --buildLorsqu'il est configuré dans config.yaml avec une variable d'environnement NOTIFICATIONS_API_KEY, FencePost publie les événements de changement à chaque actualisation du tableau de bord :
Les événements incluent des clés d'idempotence pour éviter les doublons.
MIT
/host/{name} | Détail de l'hôte avec vue à onglets : règles expliquées, ports non couverts, ports en écoute, sortie brute |
/diagnose | Outil de diagnostic de connexion avec visualisation de la trace règle par règle |
/login | Authentification par session |
| Section | Description |
|---|
timezone | Fuseau horaire IANA pour les horodatages affichés (par ex. Australia/Melbourne, UTC) |
hosts | Tableau des cibles SSH : name, hostname, ssh_user, ssh_port, is_docker_host |
ssh | key_path (chemin vers la clé privée) et timeout en secondes |
networks | Mappage CIDR-à-nom pour les VLAN -- utilisé dans les explications de règles et les diagnostics |
devices | IP nommées pour les boutons de sélection rapide de la page de diagnostic |
notifications | Webhook facultatif : url, channel (clé API définie via une variable d'environnement) |
| Variable | Défaut | Description |
|---|
FENCEPOST_USERNAME | admin | Nom d'utilisateur de connexion |
FENCEPOST_PASSWORD | fencepost | Mot de passe de connexion |
FENCEPOST_SECRET_KEY | change-me | Clé de signature des cookies de session |
FENCEPOST_CONFIG | config.yaml | Chemin vers le fichier de configuration |
NOTIFICATIONS_API_KEY | Jeton Bearer pour le webhook de notification |