commit 6ae10c6f648121237620c9e18af0f9fea4898aba Author: Voxan Date: Wed Oct 21 21:53:51 2026 +0200 Import diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..b070770 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,323 @@ +# Installation de l'espace d'administration NetMonster + +Ce guide cible un serveur **Ubuntu 24.04 LTS (Noble) avec Apache2 deja installe** pour un autre site. NetMonster Admin est ajoute en **complement**, sous un **sous-domaine dedie**, sans perturber le site existant : nouveau virtualhost separe, nouvelle base de donnees dediee. + +Ubuntu 24.04 fournit nativement **PHP 8.3** et **MariaDB 10.11**, ce qui couvre largement le minimum requis (PHP 8.1+) sans depot tiers. + +## 0. Verification de l'existant + +```bash +apache2 -v +php -v +mysql --version 2>/dev/null || mariadb --version 2>/dev/null +sudo apache2ctl -S +``` + +La derniere commande liste les virtualhosts deja configures. Notez les ports et `ServerName` deja utilises pour eviter tout conflit. + +## 1. Mise à jour du systeme + +```bash +sudo apt update && sudo apt upgrade -y +``` + +## 2. Installation des paquets PHP manquants + +Apache2 est deja present. Installez PHP (mod_php) et les extensions requises si elles ne le sont pas encore : + +```bash +sudo apt install -y libapache2-mod-php php php-mysql php-mbstring php-xml php-curl +``` + +`php-curl` est necessaire uniquement si vous comptez activer le CAPTCHA Cloudflare Turnstile sur la page de connexion (voir etape 9bis) ; installez-le des maintenant pour eviter un aller-retour plus tard. + +Cette commande installe **PHP 8.3** sur Ubuntu 24.04. Verifiez : + +```bash +php -v +php -m | grep -i curl +``` + +> Note : mod_php ne permet qu'une seule version de PHP partagee entre tous les sites Apache du serveur. Si l'autre site heberge deja necessite une version differente de PHP, une architecture PHP-FPM avec vhost dedie serait requise a la place — dites-le-moi si c'est votre cas, la configuration differe alors sensiblement de ce guide. + +Redemarrez Apache pour charger le module : + +```bash +sudo systemctl restart apache2 +``` + +## 3. Installation de MariaDB + +Si MariaDB n'est pas deja installe pour l'autre site : + +```bash +sudo apt install -y mariadb-server mariadb-client +sudo systemctl enable --now mariadb +sudo mysql_secure_installation +``` + +Si MariaDB est deja present, passez directement a l'etape suivante : vous allez y ajouter une base dediee, sans toucher aux bases existantes. + +## 4. Création de la base de données NetMonster + +```bash +sudo mysql -u root -p +``` + +```sql +CREATE DATABASE netmonster CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE USER 'netmonster_user'@'localhost' IDENTIFIED BY 'un_mot_de_passe_fort'; +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER ON netmonster.* TO 'netmonster_user'@'localhost'; +FLUSH PRIVILEGES; +EXIT; +``` + +Ce compte n'a acces qu'a la base `netmonster`, aucun risque pour les bases de l'autre site. + +### Installation neuve : un seul fichier a executer + +```bash +cd /chemin/vers/le/depot/admin/sql +mysql -u netmonster_user -p netmonster < install_full_schema.sql +``` + +Ce fichier unique cree toutes les tables necessaires (`countries`, `operators`, `sites`, `cells`, `staging_cells`, `staging_batches`, `imports`, `admin_users`, `login_attempts`), pré-remplit le Luxembourg (MCC 270) avec POST, LoL, Tango et Orange, et inclut deja : + +- les parametres radio detailles (`band`, `frequency`, `azimuth`, `bandwidth`, `address_desc`) ; +- la contrainte d'unicite corrigee sur `cells` (inclut l'eNB/RNC, evite les faux doublons entre deux antennes distinctes partageant par coincidence le meme Cell ID) ; +- la table `login_attempts` necessaire au rate limiting de connexion durci (voir `admin/admin_auth.php` et `admin/login.php`). + +Ce fichier est idempotent (`IF NOT EXISTS` / `ON DUPLICATE KEY UPDATE`) : l'executer une seconde fois par erreur ne casse rien et ne duplique aucune donnee. + +### Mise a jour depuis une installation existante + +Si votre base a deja ete creee avec une version anterieure du schema (avant la fusion en fichier unique), **n'executez pas** `install_full_schema.sql` — utilisez uniquement les migrations ciblees encore fournies a part dans `admin/sql/` : + +```bash +# Si votre contrainte uniq_cell ne contient pas encore l'eNB/RNC (sub_id2) : +mysql -u netmonster_user -p netmonster < migration_fix_uniq_cell.sql + +# Si vous n'avez pas encore la table login_attempts (durcissement securite 20/09/2026) : +mysql -u netmonster_user -p netmonster < migration_security_hardening.sql +``` + +Verifiez ensuite que tout est en place : + +```sql +SHOW TABLES; +DESCRIBE login_attempts; +``` + +## 5. Déploiement des fichiers applicatifs + +```bash +sudo mkdir -p /var/www/netmonster +sudo chown -R www-data:www-data /var/www/netmonster +sudo find /var/www/netmonster -type d -exec chmod 755 {} \; +sudo find /var/www/netmonster -type f -exec chmod 644 {} \; +``` + +Arborescence attendue : + +``` +/var/www/netmonster/ +├── contribute.php +├── lib/ +│ ├── db.php +│ ├── csrf.php +│ └── ntm_import_to_staging.php +├── config/ +│ └── turnstile.php (optionnel, voir etape 9bis — JAMAIS commite dans Git) +├── admin/ +│ ├── admin_auth.php +│ ├── login.php +│ ├── index.php +│ ├── review.php +│ ├── import_ntm.php +│ ├── manual_add.php +│ ├── edit_site.php +│ ├── countries_settings.php +│ ├── export.php +│ ├── cellmapper_import.php +│ ├── duplicates.php +│ ├── import_history.php +│ ├── audit_log.php +│ ├── backup.php +│ ├── operator_sites.php +│ ├── map_layers.php +│ ├── statistics.php +│ ├── data_quality.php +│ ├── search_site.php +│ ├── _nav.php +│ └── assets/ +│ ├── theme.css +│ └── navigation.css +└── uploads/ +``` + +Créez et protégez le dossier `uploads/` : + +```bash +sudo mkdir -p /var/www/netmonster/uploads +sudo chown www-data:www-data /var/www/netmonster/uploads +sudo chmod 750 /var/www/netmonster/uploads +``` + +Créez et protégez le dossier `config/` (destine a `turnstile.php`, jamais versionne dans Git) : + +```bash +sudo mkdir -p /var/www/netmonster/config +sudo chown www-data:www-data /var/www/netmonster/config +sudo chmod 750 /var/www/netmonster/config +``` + +## 6. Configuration du sous-domaine (virtualhost Apache) + +Assurez-vous d'abord que le DNS de `netmonster.votre-domaine.tld` pointe vers l'IP de ce serveur (enregistrement A ou CNAME chez votre registrar/gestionnaire DNS). + +Créez `/etc/apache2/sites-available/netmonster.conf` : + +```apache + + ServerName netmonster.votre-domaine.tld + DocumentRoot /var/www/netmonster + + + AllowOverride All + Require all granted + + + + + Require all denied + + + + + Require all denied + + + + Require all denied + + + ErrorLog ${APACHE_LOG_DIR}/netmonster_error.log + CustomLog ${APACHE_LOG_DIR}/netmonster_access.log combined + +``` + +Le bloc `` empeche l'execution de PHP dans ce dossier, meme si un fichier malveillant y est depose sous un nom deguise en `.ntm`, en complement de la validation deja faite cote applicatif dans `admin/import_ntm.php`. Le bloc `` interdit tout acces HTTP direct au dossier contenant les cles Turnstile. + +### Activation + +```bash +sudo a2enmod rewrite +sudo a2ensite netmonster.conf +sudo apache2ctl configtest +sudo systemctl reload apache2 +``` + +`apache2ctl configtest` doit renvoyer `Syntax OK` avant de recharger. Cette verification est importante : une erreur de syntaxe dans le nouveau virtualhost pourrait empecher Apache de redemarrer, ce qui couperait aussi l'acces au site deja en production sur ce serveur. + +## 7. Mise en place du HTTPS (recommandé) + +Une fois le DNS propage et `netmonster.votre-domaine.tld` accessible en HTTP : + +```bash +sudo apt install -y certbot python3-certbot-apache +sudo certbot --apache -d netmonster.votre-domaine.tld +``` + +`admin/admin_auth.php` détecte automatiquement si la requête est en HTTPS pour activer le flag `secure` sur les cookies de session : aucune configuration manuelle supplementaire n'est necessaire une fois Certbot en place. + +## 8. Configuration de la connexion à la base + +Éditez `/var/www/netmonster/lib/db.php` : + +```php +$pdo = new PDO( + 'mysql:host=localhost;dbname=netmonster;charset=utf8mb4', + 'netmonster_user', + 'un_mot_de_passe_fort', + [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] +); +``` + +```bash +sudo chmod 640 /var/www/netmonster/lib/db.php +sudo chown www-data:www-data /var/www/netmonster/lib/db.php +``` + +## 9. Création du compte administrateur + +Compte administrateur unique prevu pour cette V1 : + +```bash +php -r "echo password_hash('votre_mot_de_passe', PASSWORD_DEFAULT), PHP_EOL;" +``` + +```bash +sudo mysql -u netmonster_user -p netmonster +``` + +```sql +INSERT INTO admin_users (username, password_hash, role) +VALUES ('votre_login', '', 'admin'); +``` + +## 9bis. Activation du CAPTCHA Cloudflare Turnstile (optionnel, recommande) + +Suite au durcissement de securite du 20/09/2026, la page de connexion peut utiliser Cloudflare Turnstile pour bloquer les tentatives de connexion automatisees. **Desactive par defaut** : tant que `config/turnstile.php` n'existe pas, `admin/login.php` fonctionne normalement sans CAPTCHA. + +1. Verifiez que `php-curl` est installe (voir etape 2) : + ```bash + php -m | grep -i curl + ``` +2. Creez un compte gratuit sur [dash.cloudflare.com](https://dash.cloudflare.com/) (aucune carte bancaire requise), menu **Turnstile > Add site**, renseignez `netmonster.votre-domaine.tld`. +3. Copiez le modele fourni et remplissez vos cles : + ```bash + sudo cp /var/www/netmonster/config/turnstile.example.php /var/www/netmonster/config/turnstile.php + sudo nano /var/www/netmonster/config/turnstile.php + ``` +4. Dans `turnstile.php`, passez `TURNSTILE_ENABLED` a `true` et renseignez `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY`. +5. Protégez le fichier : + ```bash + sudo chmod 640 /var/www/netmonster/config/turnstile.php + sudo chown www-data:www-data /var/www/netmonster/config/turnstile.php + ``` +6. Verifiez que `config/turnstile.php` est bien ignore par Git (`.gitignore`), pour ne jamais committer vos cles secretes. + +Laissez `TURNSTILE_FAIL_CLOSED` a `false` (valeur par defaut) sauf si vous exposez cette interface publiquement sans acces de secours : avec `false`, une panne Cloudflare ou une coupure Internet sortante temporaire de la VM ne vous bloque pas l'acces admin (le mot de passe et le rate limiting SQL restent actifs). + +## 10. Pare-feu + +Si `ufw` est deja actif pour le site existant, verifiez simplement que les ports 80/443 sont ouverts (ils le sont deja si l'autre site fonctionne) : + +```bash +sudo ufw status +``` + +Aucune regle supplementaire n'est necessaire : NetMonster partage le meme Apache2, donc les memes ports. + +## 11. Branchement au contribute.php existant (optionnel) + +```php +require_once __DIR__ . '/lib/ntm_import_to_staging.php'; +$stats = importNtmFileToStaging($uploadedPath, $safeFilename, $countryId); +``` + +Vous pouvez aussi importer des fichiers `.ntm` directement depuis l'admin via `/admin/import_ntm.php`, sans toucher a `contribute.php`. + +## 12. Vérification post-installation + +- Ouvrez `https://netmonster.votre-domaine.tld/admin/login.php` et connectez-vous. +- **Vérifiez que le site existant sur ce meme serveur fonctionne toujours normalement** (test de non-regression apres modification d'Apache). +- Vérifiez `/admin/index.php`, `/admin/countries_settings.php` (Luxembourg + 4 operateurs pre-remplis). +- Testez `/admin/import_ntm.php` avec un fichier `.ntm` de test, vérifiez l'apercu de regroupement. +- Validez le site importé via `/admin/review.php`, vérifiez son apparition dans `/admin/edit_site.php` et sur la carte de `/admin/index.php`. +- Testez `/admin/export.php`. +- Si vous avez plusieurs echecs de connexion volontaires sur `/admin/login.php`, verifiez que le message de verrouillage apparait bien apres 5 tentatives, et que la table `login_attempts` s'est remplie (`SELECT * FROM login_attempts ORDER BY attempted_at DESC LIMIT 10;`). + +## 13. Ajout d'un nouveau pays + +Utilisez `/admin/countries_settings.php`, aucune modification de fichier n'est necessaire. \ No newline at end of file diff --git a/INSTALL_TEST_VM.md b/INSTALL_TEST_VM.md new file mode 100644 index 0000000..4776174 --- /dev/null +++ b/INSTALL_TEST_VM.md @@ -0,0 +1,252 @@ +# Installation sur une VM de test (Proxmox, sans nom de domaine) + +Ce guide déploie l'espace d'administration NetMonster sur une VM **Ubuntu 24.04 LTS + Nginx**, hébergée sur votre hyperviseur **Proxmox**, accessible directement via l'IP de la VM sur votre réseau (LAN ou Tailscale), sans domaine ni certificat HTTPS. + +> **Note de coherence** : votre serveur de **production** tourne sur Ubuntu 24.04 + **Apache2** (voir `INSTALL.md`), tandis que cette VM de **test** utilise Ubuntu 24.04 + **Nginx**. C'est intentionnel et sans consequence : le code PHP de NetMonster Admin est identique et fonctionne a l'identique sur les deux stacks web, seule la configuration du serveur (virtualhost Apache vs bloc server Nginx) differe. Gardez seulement a l'esprit que cette VM ne reproduit pas exactement le routage par sous-domaine prevu en production (ici vous accedez via l'IP de la VM, en prod ce sera `netmonster.votre-domaine.tld`) : testez la logique fonctionnelle ici, et validez le sous-domaine + HTTPS uniquement sur la prod ou un environnement de pre-prod dedie si vous en avez un. + +Pour le déploiement définitif, référez-vous a `INSTALL.md`. + +## 1. Prérequis de la VM Proxmox + +- Une VM Ubuntu 24.04 LTS fraîchement installee (serveur minimal suffit, pas besoin d'environnement graphique). +- Réseau en mode **bridge** (vmbr0) pour un acces direct depuis votre LAN, ou rattachee a votre **tailnet Tailscale** si vous préférez ne pas l'exposer sur le LAN. +- Au moins 1 vCPU, 1 Go de RAM et 10 Go de disque (ressources minimales, ajustez selon la charge de test prevue). +- Si vous utilisez cloud-init pour le provisioning Proxmox, veillez a activer l'agent QEMU (`qemu-guest-agent`) pour recuperer facilement l'IP depuis l'interface Proxmox. + +Récupérez l'adresse IP de la VM (affichee dans l'onglet **Summary** de Proxmox si l'agent QEMU est actif, ou directement depuis la VM) : + +```bash +ip a +``` + +## 2. Mise à jour et installation des paquets + +```bash +sudo apt update && sudo apt upgrade -y +sudo apt install -y nginx php-fpm php-mysql php-mbstring php-xml php-curl mariadb-server mariadb-client curl unzip +sudo systemctl enable --now nginx php8.3-fpm mariadb +``` + +Ubuntu 24.04 fournit nativement **PHP 8.3** et **MariaDB 10.11**, comme en production — c'est un des avantages de tester sur la meme distribution que la prod plutot que sur une distribution differente. + +`php-curl` est installe des maintenant pour permettre de tester le CAPTCHA Cloudflare Turnstile si besoin (voir etape 8bis) ; il n'est pas obligatoire si vous ne testez pas cette fonctionnalite. + +Verifiez la version du socket PHP-FPM installee (utile pour l'etape 6) : + +```bash +ls /run/php/ +``` + +Vous devriez voir `php8.3-fpm.sock` (adaptez le nom dans la config Nginx si votre version differe). + +## 3. Sécurisation minimale de MariaDB + +```bash +sudo mysql_secure_installation +``` + +## 4. Création de la base de données : un seul fichier a executer + +```bash +sudo mysql -u root -p +``` + +```sql +CREATE DATABASE netmonster CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE USER 'netmonster_user'@'localhost' IDENTIFIED BY 'test_password'; +GRANT ALL PRIVILEGES ON netmonster.* TO 'netmonster_user'@'localhost'; +FLUSH PRIVILEGES; +EXIT; +``` + +Importez le schema complet en une seule commande : + +```bash +mysql -u netmonster_user -ptest_password netmonster < /tmp/netmonster_admin/admin/sql/install_full_schema.sql +``` + +Ce fichier unique cree toutes les tables (deja avec les colonnes de parametres radio bande/frequence/azimut/largeur, la contrainte d'unicite corrigee sur `cells`, la table `login_attempts` pour le rate limiting du login, et l'ENUM `source` de `staging_cells` incluant `cellmapper_import`), et pré-remplit le Luxembourg + ses 4 operateurs. Il est idempotent : l'executer une seconde fois par erreur ne casse rien. + +## 5. Déploiement rapide des fichiers + +Transferez d'abord le depot sur la VM (via `scp`, un partage Proxmox, ou un `git clone` direct sur la VM), puis : + +```bash +sudo mkdir -p /var/www/netmonster +sudo cp -r /tmp/netmonster_admin/* /var/www/netmonster/ +sudo mkdir -p /var/www/netmonster/uploads +sudo mkdir -p /var/www/netmonster/config +sudo chown -R www-data:www-data /var/www/netmonster +sudo chmod -R 755 /var/www/netmonster +sudo chmod 750 /var/www/netmonster/uploads +sudo chmod 750 /var/www/netmonster/config +``` + +Vérifiez que l'arborescence deployee correspond a celle-ci (voir aussi `README.md`) : + +``` +/var/www/netmonster/ +├── lib/ (db.php, csrf.php, ntm_import_to_staging.php) +├── config/ (turnstile.php — optionnel, voir etape 8bis) +├── admin/ (admin_auth.php, login.php, index.php, review.php, import_ntm.php, +│ manual_add.php, edit_site.php, countries_settings.php, export.php, +│ cellmapper_import.php, duplicates.php, import_history.php, +│ audit_log.php, backup.php, operator_sites.php, map_layers.php, +│ statistics.php, data_quality.php, search_site.php, _nav.php, +│ assets/theme.css, assets/navigation.css) +└── uploads/ +``` + +## 6. Configuration Nginx sans domaine + +```bash +sudo tee /etc/nginx/sites-available/netmonster-test <<'EOF' +server { + listen 80 default_server; + server_name _; + root /var/www/netmonster; + index index.php; + + location / { + try_files $uri $uri/ =404; + } + + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; + } + + location ~* ^/admin/.*\.(sql|md)$ { + deny all; + } + + location ^~ /config/ { + deny all; + } + + location ^~ /uploads/ { + location ~ \.php$ { + deny all; + return 403; + } + } +} +EOF + +sudo rm -f /etc/nginx/sites-enabled/default +sudo ln -s /etc/nginx/sites-available/netmonster-test /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl reload nginx +``` + +Adaptez `php8.3-fpm.sock` si l'etape 2 a installe une autre version de PHP-FPM. Le bloc `location ^~ /config/ { deny all; }` interdit tout acces HTTP direct au dossier destine a `turnstile.php`, meme en test. + +## 7. Configuration de la connexion à la base + +Éditez `/var/www/netmonster/lib/db.php` avec `test_password` (voir etape 4). + +## 8. Création d'un compte admin de test + +```bash +php -r "echo password_hash('test1234', PASSWORD_DEFAULT), PHP_EOL;" +``` + +```sql +INSERT INTO admin_users (username, password_hash, role) VALUES ('admin', '', 'admin'); +``` + +## 8bis. Test du CAPTCHA Cloudflare Turnstile (optionnel) + +Le rate limiting de connexion (table `login_attempts`) est actif par defaut des que le schema SQL est importe. Le CAPTCHA Turnstile, lui, reste **desactive** tant que `config/turnstile.php` n'existe pas — vous pouvez ignorer cette section pour un test rapide. + +Pour le tester malgre l'absence de nom de domaine public : + +1. Sur [dash.cloudflare.com](https://dash.cloudflare.com/) (compte gratuit), menu **Turnstile > Add site**. Si la VM est accessible uniquement via Tailscale ou votre LAN, ajoutez le nom d'hote local ou l'IP en mode test (Cloudflare accepte des domaines/hotes de test comme `localhost`) — sinon utilisez temporairement le hostname Tailscale de la VM si vous avez active **Tailscale Funnel** dessus. +2. Copiez le modele et renseignez vos cles : + ```bash + sudo cp /var/www/netmonster/config/turnstile.example.php /var/www/netmonster/config/turnstile.php + sudo nano /var/www/netmonster/config/turnstile.php + ``` +3. Passez `TURNSTILE_ENABLED` a `true`, renseignez les deux cles. +4. Protegez le fichier : + ```bash + sudo chmod 640 /var/www/netmonster/config/turnstile.php + sudo chown www-data:www-data /var/www/netmonster/config/turnstile.php + ``` +5. Rechargez `/admin/login.php` : le widget CAPTCHA doit apparaitre sous le formulaire. + +Pour desactiver a nouveau : repassez `TURNSTILE_ENABLED` a `false`, ou supprimez `config/turnstile.php`. + +## 9. Accès depuis votre machine + +Recuperez l'IP de la VM (onglet Summary dans Proxmox, ou `ip a` dans la VM), puis ouvrez directement : + +``` +http://IP_DE_LA_VM/admin/login.php +``` + +Si la VM est rattachee a votre tailnet (recommande, coherent avec votre usage habituel de Tailscale pour Proxmox), utilisez plutot l'IP ou le nom Tailscale de la VM, accessible depuis n'importe lequel de vos appareils sans configuration reseau supplementaire : + +``` +http://IP_TAILSCALE_DE_LA_VM/admin/login.php +``` + +Connectez-vous avec `admin` / `test1234`. + +> Sur une session HTTP simple, `admin/admin_auth.php` desactive automatiquement le flag `secure` des cookies de session (detecte l'absence de HTTPS) : la connexion fonctionne normalement sans configuration supplementaire. Ce flag s'activera seul une fois la prod en HTTPS (voir `INSTALL.md`, etape Certbot). + +> Si vous avez teste plusieurs mots de passe incorrects par erreur, la connexion peut se retrouver temporairement bloquee (5 echecs sur le meme compte+IP, ou 30 echecs sur l'IP en 15 minutes). Videz la table de test si besoin : `DELETE FROM login_attempts;` + +## 10. Génération de données de démonstration + +Pour visualiser rapidement le regroupement par site dans `/admin/review.php`, insérez quelques lignes factices en staging : + +```sql +INSERT INTO staging_cells (tech, mcc, mnc, operator_guess, cell_id, area_code, sub_id, sub_id2, band, frequency, azimuth, bandwidth, lat, lon, location_desc, address_desc, arfcn, source, status) +VALUES +('4G', '270', '01', (SELECT id FROM operators WHERE mcc='270' AND mnc='01'), 43, 3006, 23, 4620, 'B7', '700MHz', 280, '10MHz', 49.492048, 6.116873, 'eNB ID 4620 - LTE B7 700Mhz - 280° - 10Mhz - E25 Echangeur Burange/Hellange, Dudelange', 'E25 Echangeur Burange/Hellange, Dudelange', 6200, 'ntm_import', 'pending'), +('4G', '270', '01', (SELECT id FROM operators WHERE mcc='270' AND mnc='01'), 44, 3006, 45, 4620, 'B7', '700MHz', 40, '10MHz', 49.492048, 6.116873, 'eNB ID 4620 - LTE B7 700Mhz - 40° - 10Mhz - E25 Echangeur Burange/Hellange, Dudelange', 'E25 Echangeur Burange/Hellange, Dudelange', 6200, 'ntm_import', 'pending'), +('3G', '270', '77', (SELECT id FROM operators WHERE mcc='270' AND mnc='77'), 987654, 3002, 45, 210, NULL, NULL, NULL, NULL, 49.6100, 6.1350, 'Antenne test peripherie', 'Antenne test peripherie', 10700, 'ntm_import', 'pending'); +``` + +Rechargez `/admin/review.php` : les deux premieres lignes (meme eNB 4620) doivent se regrouper dans le meme site, la troisieme rester isolee. Validez le premier groupe pour tester ensuite `/admin/edit_site.php` (le site valide doit y apparaitre) et `/admin/export.php`. + +## 11. Test de l'upload manuel de fichier .ntm + +Créez un petit fichier de test sur votre machine : + +``` +4G;270;99;12;3010;5001;18;49.610000;6.130000;eNB ID 5001 - LTE B20 800Mhz - 90° - 10Mhz - Test upload manuel;6300 +``` + +Enregistrez-le en `test.ntm`, puis deposez-le via `/admin/import_ntm.php` en selectionnant le Luxembourg comme pays. Verifiez que l'apercu de regroupement s'affiche et que la ligne apparait ensuite dans `/admin/review.php`. + +## 12. Test de l'import CellMapper (optionnel) + +Pour tester `/admin/cellmapper_import.php`, utilisez un export JSON CellMapper (voir la documentation de la page pour le format attendu : cle `responseData` avec `RAT`, `siteID`, `regionID`, `cells`, `channels`). Renseignez le MCC/MNC de l'operateur Luxembourgeois de votre choix (ex: `270` / `01` pour POST) puisqu'ils ne sont pas presents dans le JSON source. + +## 13. Snapshot Proxmox (recommande avant tests destructifs) + +Avant de tester des actions irreversibles (suppression de site, fusion de doublons, purge d'historique), prenez un snapshot de la VM depuis l'interface Proxmox (**VM > Snapshots > Take Snapshot**). Cela permet de revenir instantanement a un etat propre sans repasser par toute la procedure d'installation : + +```bash +# Depuis le noeud Proxmox (CLI), si vous preferez la ligne de commande : +qm snapshot avant_tests_destructifs +``` + +Pour restaurer : + +```bash +qm rollback avant_tests_destructifs +``` + +## 14. Nettoyage après les tests + +Si vous ne conservez pas la VM pour des tests futurs (sinon, un snapshot "etat propre" suffit, voir etape 13) : + +```bash +sudo mysql -u root -p -e "DROP DATABASE netmonster;" +sudo rm -rf /var/www/netmonster +``` + +Ou plus simplement, supprimez la VM depuis Proxmox si elle a ete creee uniquement pour ce test ponctuel. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d48747a --- /dev/null +++ b/README.md @@ -0,0 +1,154 @@ +# NetMonster Admin + +Espace d'administration multi-pays pour traiter les fichiers `.ntm` (NetMonster) et gerer une base d'antennes cellulaires par pays/operateur, avec verification manuelle systematique avant toute ecriture en base finale. + +## Structure du projet + +``` +netmonster_admin/ +├── sql/ +│ ├── 01_schema.sql Schema complet (installation neuve) +│ └── migration_add_radio_params.sql Migration pour bases existantes (bande/frequence/azimut/largeur) +├── lib/ +│ ├── db.php Connexion PDO partagee (a configurer) +│ ├── csrf.php Protection CSRF par jeton de session +│ └── ntm_import_to_staging.php Parseur .ntm -> staging_cells, extrait les parametres radio +├── admin/ Dossier protege par authentification +│ ├── admin_auth.php Barriere de session, durcissement (cookies, timeout, anti brute-force) +│ ├── login.php Page de connexion +│ ├── index.php Accueil : recapitulatif + carte de toutes les antennes validees +│ ├── review.php File de validation groupee par site (carte + cadastre) +│ ├── import_ntm.php Upload manuel d'un fichier .ntm + apercu du regroupement +│ ├── manual_add.php Ajout manuel d'un site multi-cellules +│ ├── edit_site.php Edition/suppression d'un site deja valide +│ ├── countries_settings.php Gestion des pays et operateurs sans SQL +│ ├── export.php Export de la base validee (.ntm / .csv) pour mise en production +│ └── assets/theme.css Feuille de style commune a toutes les pages +├── uploads/ Fichiers .ntm deposes (a proteger contre l'execution PHP, voir plus bas) +├── nginx_uploads_protection.txt Bloc de configuration Nginx a ajouter +├── INSTALL.md Guide d'installation complet (Debian 13, domaine + HTTPS) +├── INSTALL_TEST_VM.md Guide rapide pour VM de test (VMware Workstation, NAT, sans domaine) +├── SECURITY_AUDIT_V1.md Audit de securite detaille, page par page +└── README.md Ce fichier +``` + +## Pages de l'espace admin + +Toutes les pages partagent le meme menu de navigation : +**Accueil - Validation - Import .ntm - Ajout manuel - Edition de site - Pays & operateurs - Export** + +| Page | Role | +|---|---| +| `index.php` | Vue d'ensemble : compteurs (sites/cellules/en attente), carte groupee de toutes les antennes validees, repartition par operateur/techno, activite recente | +| `review.php` | File d'attente des lignes importees ou saisies manuellement, regroupees automatiquement par site physique probable, avec carte + cadastre configurable par pays, validation ou rejet | +| `import_ntm.php` | Depot manuel d'un fichier `.ntm` depuis l'admin (en plus du flux `contribute.php` existant), avec apercu immediat du regroupement par site et historique des imports | +| `manual_add.php` | Saisie manuelle d'un site avec plusieurs cellules/secteurs, chacune avec ses parametres radio (bande, frequence, azimut, largeur de bande) | +| `edit_site.php` | Recherche et correction d'un site deja valide : deplacement de la position sur la carte (marqueur glissable), edition des cellules, suppression | +| `countries_settings.php` | Ajout/modification/suppression de pays (avec configuration cadastre WMS) et d'operateurs (MCC/MNC), sans ecrire de SQL | +| `export.php` | Export filtrable de la base validee au format `.ntm` (reconstruit le format d'origine) ou `.csv`, pour publication sur le serveur de diffusion separe | + +## Pipeline de donnees + +``` +Fichier .ntm (via contribute.php OU via admin/import_ntm.php) + | + v +importNtmFileToStaging() --> staging_cells (status = pending) + | extrait aussi : eNB, bande, frequence, + | azimut, largeur de bande depuis le champ + | Location du fichier .ntm + v +/admin/review.php : regroupement automatique par site (eNB reel pour la + 4G, proximite GPS pour les autres technos), carte + + cadastre, ajout de secteurs/bandes manquants, + validation manuelle + | + v + sites + cells (base finale VALIDEE) + | + v +/admin/edit_site.php : corrections ponctuelles post-validation si besoin + | + v +/admin/export.php : export .ntm ou .csv + | + v + Publication manuelle vers votre serveur de diffusion + (hors perimetre de cet espace admin) +``` + +Rien n'atteint `sites`/`cells` sans validation humaine dans `/admin/review.php`, que la donnee vienne d'un import `.ntm` ou d'une saisie manuelle. + +## Regroupement par site physique + +La fonction `deriveSiteKey()` (dupliquee dans `review.php` et `import_ntm.php`, a synchroniser si vous la modifiez) regroupe les cellules d'un meme site probable : + +- **4G** : regroupement par l'**eNB reel**, transmis explicitement dans le fichier `.ntm` (position 5 de la ligne `4G;...`). Ce n'est plus une valeur recalculee a partir du Cell Identity : le format `.ntm` fournit deja l'eNB directement, l'utiliser tel quel evite les regroupements errones observes avec un decalage de bits. +- **3G / 2G / CDMA / 5G** : le format `.ntm` ne transmet pas d'identifiant de site fiable pour ces technologies (le RNC en 3G gere plusieurs sites, la 5G ne transmet pas de gNB explicite). Le regroupement se fait par proximite GPS (~11 metres) combinee au LAC/TAC. + +## Extraction automatique des parametres radio + +Le champ `Location` des fichiers `.ntm` reels contient souvent des informations structurees au format `"eNB ID {n} - {TECH} {bande} {frequence} - {azimut}° - {largeur} - {adresse}"`. Le parseur (`lib/ntm_import_to_staging.php`) extrait automatiquement ces elements dans des colonnes dediees (`band`, `frequency`, `azimuth`, `bandwidth`, `address_desc`) plutot que de les laisser dans du texte libre. Ces memes champs sont saisissables individuellement dans `manual_add.php` et `edit_site.php`, et `export.php` recompose le champ `Location` a partir de ces colonnes structurees (donc toujours a jour, meme apres une correction manuelle). + +## Securite + +Voir `SECURITY_AUDIT_V1.md` pour le detail complet. Points cles : + +- **CSRF** : tous les formulaires de mutation (`review.php`, `manual_add.php`, `edit_site.php`, `countries_settings.php`, `import_ntm.php`, `login.php`) integrent `csrf_field()` et verifient `require_csrf_token()`. `export.php` n'en a pas besoin (lecture seule, GET uniquement). +- **Sessions** : cookies avec `HttpOnly`, `SameSite=Strict`, et flag `Secure` detecte automatiquement selon que la requete est en HTTPS. Expiration automatique apres 30 minutes d'inactivite. +- **Anti brute-force** : verrouillage temporaire (5 minutes) apres 5 echecs de connexion consecutifs. +- **PHP 8.3+** : tous les appels a `htmlspecialchars()` sur des colonnes numeriques (int, float) sont precedes d'un cast `(string)` explicite, requis depuis PHP 8.1+ et strictement applique en 8.3. +- **Upload `.ntm`** : validation d'extension, limite de taille (10 Mo par defaut), verification `is_uploaded_file()`, nom de fichier assaini avant ecriture disque. + +### Action serveur requise + +Le dossier `uploads/` (cree automatiquement par `import_ntm.php`) doit etre protege contre l'execution de PHP. Ajoutez le contenu de `nginx_uploads_protection.txt` a votre configuration Nginx, puis : + +```bash +sudo nginx -t && sudo systemctl reload nginx +``` + +## Installation + +- **Deploiement complet (domaine + HTTPS)** : suivez `INSTALL.md`. +- **VM de test rapide (VMware Workstation, NAT, sans domaine)** : suivez `INSTALL_TEST_VM.md`. + +Resume rapide pour une base neuve : + +1. Executer `sql/01_schema.sql` sur votre base MariaDB/MySQL. +2. Configurer `lib/db.php` avec vos identifiants. +3. Creer un compte admin : + ```bash + php -r "echo password_hash('votre_mot_de_passe', PASSWORD_DEFAULT), PHP_EOL;" + ``` + ```sql + INSERT INTO admin_users (username, password_hash, role) VALUES ('votre_login', '', 'admin'); + ``` +4. Appliquer la protection Nginx du dossier `uploads/` (voir ci-dessus). +5. Ouvrir `/admin/login.php`. + +### Si vous partez d'une base existante (mise a jour depuis une version anterieure) + +Si votre base a ete creee avant l'ajout des parametres radio detailles, appliquez la migration : + +```bash +mysql -u netmonster_user -p netmonster < sql/migration_add_radio_params.sql +``` + +Cette migration ajoute les colonnes `band`, `frequency`, `azimuth`, `bandwidth` sur `cells` et `staging_cells`, et `address_desc` sur `sites` et `staging_cells`. + +## Ajouter un nouveau pays + +Aucun SQL requis : ouvrez `/admin/countries_settings.php` et renseignez le MCC, le code ISO2, le nom du pays, les coordonnees de centrage carte, et si disponible l'URL d'un service WMS cadastre national (avec son attribution obligatoire). Ajoutez ensuite les operateurs (MCC/MNC/nom commercial) du pays. La page `review.php` et le tableau de bord s'adaptent automatiquement des que vous filtrez sur ce pays, sans modification de code. + +## Attribution des fonds de carte (obligatoire) + +- **OpenStreetMap** : mention "(c) OpenStreetMap contributors" affichee en permanence sur toutes les cartes (accueil, validation, edition de site), conformement a la licence ODbL. Ne jamais la masquer. +- **Cadastre national** : chaque pays configure dans `countries_settings.php` doit avoir son propre texte d'attribution (ex: "Administration du Cadastre et de la Topographie (ACT)" pour le Luxembourg). + +## Notes techniques + +- Les tuiles OSM standard (`tile.openstreetmap.org`) sont adaptees a un usage interne a faible trafic. Pour un futur serveur public a fort volume, prevoir un fournisseur de tuiles commercial ou un hebergement de tuiles dedie. +- Le champ NCI (5G) peut depasser la capacite d'un entier 32 bits PHP sur certains systemes : verifiez l'absence de troncature sur votre environnement de production. +- Formats `.ntm` geres : 2G, 3G, 4G, 5G, CDMA (voir les commentaires dans `lib/ntm_import_to_staging.php` pour le detail exact des colonnes par technologie). +- Un seul compte administrateur est prevu pour cette V1 : aucune restriction d'acces par perimetre pays/operateur n'a ete implementee (non necessaire dans ce contexte). \ No newline at end of file