This commit is contained in:
Voxan committed 2026-10-21 21:53:51 +02:00
commit 6ae10c6f64
3 files changed
+729

No files matched your search

+323
View File
@@ -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
<VirtualHost *:80>
ServerName netmonster.votre-domaine.tld
DocumentRoot /var/www/netmonster
<Directory /var/www/netmonster>
AllowOverride All
Require all granted
</Directory>
<Directory /var/www/netmonster/uploads>
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
</Directory>
<Directory /var/www/netmonster/config>
Require all denied
</Directory>
<FilesMatch "\.(sql|md)$">
Require all denied
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/netmonster_error.log
CustomLog ${APACHE_LOG_DIR}/netmonster_access.log combined
</VirtualHost>
```
Le bloc `<Directory /var/www/netmonster/uploads>` 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 `<Directory /var/www/netmonster/config>` 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', '<hash_genere_ci-dessus>', '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.
+252
View File
@@ -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', '<hash>', '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 <VMID> avant_tests_destructifs
```
Pour restaurer :
```bash
qm rollback <VMID> 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.
+154
View File
@@ -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', '<hash>', '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).