9adaf28faa
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
233 lines
8.1 KiB
Markdown
233 lines
8.1 KiB
Markdown
# <img src="frontend/public/favicon.svg" width="22" height="22" alt="" /> Stupid Simple Network Inventory
|
|
|
|

|
|

|
|

|
|

|
|

|
|

|
|
|
|
Application web auto-hébergée pour l'inventaire manuel de réseau et la visualisation de topologie réseau logique.
|
|
|
|

|
|
|
|
## Fonctionnalités
|
|
|
|
- **Inventaire manuel** — ajout et gestion d'équipements (18 types) avec IPs, VLANs, descriptions et liens web optionnels
|
|
- **Vue topologie** — disposition en cards par réseau (LAN / VLAN 802.1Q), avec sections WAN et passerelle
|
|
- **Ping ICMP** — vérification de l'accessibilité de tous les hôtes connus en un clic
|
|
- **Découverte automatique** — ping sweep + lookup PTR DNS sur un sous-réseau pour importer de nouveaux hôtes
|
|
- **Authentification** — connexion JWT avec changement de mot de passe forcé à la première utilisation
|
|
- **Mode sombre** — bascule thème clair / sombre
|
|
- **Logos de marques** — détection et affichage automatiques des logos éditeurs/fabricants (Proxmox, Cisco, Synology, Docker, et plus de 30 autres)
|
|
- **i18n** — français, anglais, espagnol
|
|
|
|
## Stack
|
|
|
|
| Couche | Technologie |
|
|
|--------|------------|
|
|
| Backend | FastAPI + SQLAlchemy + SQLite (Python 3.11) |
|
|
| Frontend | Vue 3 + Vite, servi par Nginx |
|
|
| Auth | JWT HS256, expiration 24h |
|
|
| Runtime | Docker Compose |
|
|
|
|
---
|
|
|
|
## Démarrage rapide
|
|
|
|
```bash
|
|
# 1. Cloner et entrer dans le projet
|
|
git clone https://git.raspot.in/olivier/stupid-simple-network-inventory.git
|
|
cd stupid-simple-network-inventory
|
|
|
|
# 2. Créer le répertoire de données appartenant à l'utilisateur courant
|
|
mkdir -p db_data
|
|
|
|
# 3. Configurer l'environnement (requis pour la propriété correcte du bind-mount)
|
|
cp .env.example .env
|
|
# Éditer .env :
|
|
# DOCKER_UID / DOCKER_GID → résultat de : id -u && id -g
|
|
# INITIAL_ADMIN_PASSWORD → à définir pour éviter le bootstrap admin/admin par défaut
|
|
|
|
# 4. Construire et démarrer
|
|
docker compose --env-file .env up --build -d
|
|
|
|
# 5. Ouvrir http://localhost:8080 dans votre navigateur
|
|
```
|
|
|
|
### Première connexion
|
|
|
|
| Cas | Identifiants | Comportement |
|
|
|-----|-------------|--------------|
|
|
| `INITIAL_ADMIN_PASSWORD` défini | `admin` / `<votre mot de passe>` | Connexion normale |
|
|
| `INITIAL_ADMIN_PASSWORD` non défini | `admin` / `admin` | Changement de mot de passe forcé avant d'accéder à l'application |
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
Toute la configuration se fait via des variables d'environnement. Voir `.env.example` pour la liste complète avec descriptions.
|
|
|
|
| Variable | Défaut | Description |
|
|
|----------|--------|-------------|
|
|
| `SECRET_KEY` | auto-générée | Clé de signature JWT. À définir explicitement en production. |
|
|
| `INITIAL_ADMIN_PASSWORD` | _(vide)_ | Mot de passe admin de bootstrap. Si non défini, `admin/admin` est utilisé avec changement forcé. |
|
|
| `ALLOWED_ORIGINS` | `*` | Origines CORS autorisées (séparées par des virgules). À définir sur votre domaine en production. |
|
|
| `BIND_ADDRESS` | `0.0.0.0` | Adresse IP d'écoute. À définir sur l'interface face au reverse proxy. |
|
|
| `DOCKER_UID` / `DOCKER_GID` | `1000` | UID/GID pour le processus backend. Doit correspondre à l'utilisateur propriétaire de `./db_data/`. |
|
|
|
|
### Utilisation de .env avec Docker Compose
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
# Éditer .env — définir au minimum DOCKER_UID, DOCKER_GID, INITIAL_ADMIN_PASSWORD
|
|
docker compose --env-file .env up --build -d
|
|
```
|
|
|
|
---
|
|
|
|
## Sécurité
|
|
|
|
### Gestion des secrets
|
|
|
|
Deux options selon vos exigences de sécurité.
|
|
|
|
#### Option A — Secret auto-généré (recommandé pour un nœud unique)
|
|
|
|
Laisser `SECRET_KEY` non défini (ou vide) dans `.env`. Au premier démarrage, le backend génère une clé hexadécimale aléatoire de 64 caractères, l'écrit dans `db_data/secret_key.txt` avec les permissions **0600**, et la réutilise à chaque redémarrage. Le secret n'apparaît jamais dans une variable d'environnement, un fichier compose ou un log.
|
|
|
|
```bash
|
|
# .env — laisser la ligne vide ou la supprimer
|
|
SECRET_KEY=
|
|
```
|
|
|
|
La seule exigence est que `db_data/` soit sauvegardé (il contient déjà la base de données).
|
|
|
|
#### Option B — Secret via fichier Docker Compose
|
|
|
|
Stocke le secret dans un fichier sur l'hôte, hors du contrôle de version, et le monte dans le conteneur. La valeur n'apparaît jamais dans une variable d'environnement.
|
|
|
|
```bash
|
|
# Générer et stocker le secret en dehors du répertoire du projet
|
|
mkdir -p ~/.secrets
|
|
python3 -c "import secrets; print(secrets.token_hex(32))" > ~/.secrets/topologie_secret_key
|
|
chmod 600 ~/.secrets/topologie_secret_key
|
|
```
|
|
|
|
Décommenter ensuite les blocs `secrets:` dans `docker-compose.yml` (voir les commentaires dans ce fichier) et supprimer `SECRET_KEY` de `.env`. Docker Compose fusionne la surcharge automatiquement :
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
---
|
|
|
|
### Rotation de clé
|
|
|
|
Pour faire tourner le secret JWT (invalide toutes les sessions actives) :
|
|
|
|
```bash
|
|
# Option A — variable d'environnement (recommandé)
|
|
# Définir un nouveau SECRET_KEY dans la configuration de déploiement et redémarrer
|
|
|
|
# Option B — rotation par fichier
|
|
docker compose stop backend
|
|
rm db_data/secret_key.txt
|
|
docker compose start backend
|
|
# Tous les utilisateurs devront se reconnecter
|
|
```
|
|
|
|
### HTTPS
|
|
|
|
Cette application ne termine pas TLS. Pour un usage en production, placez-la derrière un reverse proxy gérant HTTPS :
|
|
|
|
```nginx
|
|
# Exemple de reverse proxy nginx (externe, sur l'hôte ou un conteneur dédié)
|
|
server {
|
|
listen 443 ssl;
|
|
server_name inventory.example.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/inventory.example.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/inventory.example.com/privkey.pem;
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:8080;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
}
|
|
}
|
|
```
|
|
|
|
Pour un usage local uniquement, lier à la boucle locale pour éviter une exposition LAN accidentelle :
|
|
|
|
```yaml
|
|
# docker-compose.override.yml
|
|
services:
|
|
frontend:
|
|
ports:
|
|
- "127.0.0.1:8080:8080"
|
|
```
|
|
|
|
### Durcissement des conteneurs
|
|
|
|
Les conteneurs s'exécutent avec des privilèges réduits :
|
|
|
|
| Mesure | Backend | Frontend |
|
|
|--------|---------|----------|
|
|
| Utilisateur non-root | `DOCKER_UID:DOCKER_GID` (utilisateur hôte) | `nginx` (UID 101) |
|
|
| `cap_drop: ALL` | ✓ | ✓ |
|
|
| `cap_add: NET_RAW` | ✓ (ping) | — |
|
|
| `no-new-privileges` | — ¹ | ✓ |
|
|
| Healthcheck | ✓ | ✓ |
|
|
|
|
¹ Omis sur le backend : le ping utilise les file capabilities (`cap_net_raw=ep`) ; `no-new-privileges` supprimerait le bit effectif du fichier et empêcherait le sous-processus d'acquérir `CAP_NET_RAW` dans son ensemble effectif même si le parent le détient dans son ensemble permis.
|
|
|
|
---
|
|
|
|
## Persistance des données
|
|
|
|
Toutes les données sont stockées dans `./db_data/` :
|
|
|
|
| Fichier | Description |
|
|
|---------|-------------|
|
|
| `topology.db` | Base de données SQLite |
|
|
| `secret_key.txt` | Secret JWT auto-généré (permissions 0600) |
|
|
|
|
**Sauvegarde** : `cp -r db_data/ db_data.bak/`
|
|
|
|
**Restauration** : arrêter la stack, remplacer `db_data/`, redémarrer.
|
|
|
|
---
|
|
|
|
## Développement
|
|
|
|
### Tests backend
|
|
|
|
```bash
|
|
cd backend
|
|
pip install -r requirements.txt -r requirements-test.txt
|
|
pytest tests/ -v
|
|
```
|
|
|
|
### Dev local (sans Docker)
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend
|
|
pip install -r requirements.txt
|
|
uvicorn main:app --reload
|
|
|
|
# Frontend (terminal séparé)
|
|
cd frontend
|
|
npm install
|
|
npm run dev # Serveur dev Vite sur :5173, proxifie /api/ vers :8000
|
|
```
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
Voir [`docs/architecture.md`](docs/architecture.md) pour le flux de requêtes détaillé, la configuration Docker et le modèle d'authentification.
|