149 lines
6.4 KiB
PHP
149 lines
6.4 KiB
PHP
<?php
|
|
// ============================================================================
|
|
// generer_relais_live.php - Génération des relais Traefik du Live distant, un par bateau (synthèse §49, étape 2f).
|
|
// Exécuté NATIVEMENT sur le VPS, de façon planifiée (ship2net-relais-live.timer) ou à la main :
|
|
// /usr/bin/php /var/www/generer_relais_live.php
|
|
//
|
|
// Pour chaque bateau valide dont le module affecté (affectation active) a une adresse NetBird connue
|
|
// (TB_Cartes.Adresse_netbird), écrit /opt/netbird/dynamic/bateau-<N>.yml : https://b<N>.ship2net.fr relayé vers ce
|
|
// module, avec ouverture de session (/_auth) et vérification de la session à chaque requête (ForwardAuth) - cf
|
|
// live-commun.yml. Supprime les relais des bateaux qui ne remplissent plus ces conditions (bateau dévalidé,
|
|
// affectation clôturée, adresse retirée).
|
|
//
|
|
// Ajouter un bateau au Live ne demande donc rien d'autre que son affectation (lot 4) : ni DNS, ni certificat
|
|
// (certificat générique *.ship2net.fr), ni fichier à écrire à la main. Une réaffectation de module change la
|
|
// destination du relais, pas l'adresse du bateau.
|
|
//
|
|
// Principes :
|
|
// - seuls les fichiers "bateau-<N>.yml" sont gérés : aucun autre fichier du dossier n'est jamais touché ;
|
|
// - un fichier n'est réécrit que si son contenu change (Traefik recharge sa configuration à chaque écriture) ;
|
|
// - écriture atomique (fichier temporaire puis renommage) : Traefik ne lit jamais un fichier à moitié écrit ;
|
|
// - l'adresse NetBird est validée (adresse IPv4 stricte) avant d'être écrite dans la configuration de Traefik.
|
|
// ============================================================================
|
|
|
|
chdir("/var/www/html");
|
|
require_once __DIR__ . "/config/config.php";
|
|
require_once __DIR__ . "/config/fonctions_bdd.php";
|
|
|
|
const REPERTOIRE_RELAIS = "/opt/netbird/dynamic";
|
|
const MOTIF_FICHIER_RELAIS = '/^bateau-([1-9][0-9]*)\.yml$/';
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Contenu du fichier de relais d'un bateau (modèle validé sur le bateau 1, étape 2d).
|
|
// ----------------------------------------------------------------------------
|
|
function Contenu_relais($id_bateau, $adresse_netbird)
|
|
{
|
|
$hote = "b".$id_bateau.".".URL_SITE;
|
|
return <<<YAML
|
|
# ============================================================================
|
|
# Live distant du bateau {$id_bateau} - https://{$hote} (synthèse §49)
|
|
# FICHIER GÉNÉRÉ AUTOMATIQUEMENT par /var/www/generer_relais_live.php - ne pas modifier à la main
|
|
# (il serait réécrit au passage suivant). Module affecté : {$adresse_netbird}
|
|
# ============================================================================
|
|
http:
|
|
routers:
|
|
bateau-{$id_bateau}-auth:
|
|
rule: "Host(`{$hote}`) && Path(`/_auth`)"
|
|
priority: 1000
|
|
entrypoints:
|
|
- websecure
|
|
tls:
|
|
certResolver: ovh
|
|
domains:
|
|
- main: "*.ship2net.fr"
|
|
middlewares:
|
|
- live-auth-chemin@file
|
|
service: live-auth@file
|
|
bateau-{$id_bateau}:
|
|
rule: "Host(`{$hote}`)"
|
|
entrypoints:
|
|
- websecure
|
|
tls:
|
|
certResolver: ovh
|
|
domains:
|
|
- main: "*.ship2net.fr"
|
|
middlewares:
|
|
- live-verification@file
|
|
service: bateau-{$id_bateau}
|
|
services:
|
|
bateau-{$id_bateau}:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://{$adresse_netbird}:80"
|
|
|
|
YAML;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Écriture atomique : fichier temporaire (extension non lue par Traefik) puis renommage.
|
|
// ----------------------------------------------------------------------------
|
|
function Ecrire_atomique($chemin, $contenu)
|
|
{
|
|
$temporaire = $chemin.".tmp";
|
|
if (file_put_contents($temporaire, $contenu) === false) return false;
|
|
chmod($temporaire, 0644);
|
|
return rename($temporaire, $chemin);
|
|
}
|
|
|
|
|
|
function Generer_relais_live()
|
|
{
|
|
if (!is_dir(REPERTOIRE_RELAIS) || !is_writable(REPERTOIRE_RELAIS))
|
|
{
|
|
echo "ERREUR : répertoire ".REPERTOIRE_RELAIS." absent ou non accessible en écriture.\n";
|
|
return 1;
|
|
}
|
|
|
|
Ouverture_bdd("127.0.0.1:3307", BDD_USER, BDD_PASSWORD, BDD_DATABASE);
|
|
$db = $_SESSION['db'];
|
|
|
|
// Bateaux éligibles : valides, avec une affectation active vers un module dont l'adresse NetBird est connue.
|
|
$requete = "SELECT B.Cle_primaire, C.Adresse_netbird
|
|
FROM TB_Bateaux B
|
|
JOIN TB_Affectations_bateaux A ON A.ID_Bateau = B.Cle_primaire AND A.Date_fin IS NULL
|
|
JOIN TB_Cartes C ON C.Adresse_mac = A.Adresse_mac
|
|
WHERE B.Validite = 1 AND C.Adresse_netbird IS NOT NULL AND C.Adresse_netbird <> ''";
|
|
$resultat = $db->query($requete);
|
|
$attendus = array();
|
|
while ($ligne = $resultat->fetch_assoc())
|
|
{
|
|
$adresse = trim($ligne['Adresse_netbird']);
|
|
if (filter_var($adresse, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false)
|
|
{
|
|
echo " ! bateau {$ligne['Cle_primaire']} : adresse NetBird '{$adresse}' invalide - relais non généré.\n";
|
|
continue;
|
|
}
|
|
$attendus["bateau-".(int)$ligne['Cle_primaire'].".yml"] = Contenu_relais((int)$ligne['Cle_primaire'], $adresse);
|
|
}
|
|
$resultat->free();
|
|
Fermeture_bdd();
|
|
|
|
$nb_crees = $nb_modifies = $nb_supprimes = $nb_inchanges = 0;
|
|
|
|
// Création / mise à jour :
|
|
foreach ($attendus as $nom => $contenu)
|
|
{
|
|
$chemin = REPERTOIRE_RELAIS."/".$nom;
|
|
$existant = is_file($chemin) ? file_get_contents($chemin) : null;
|
|
if ($existant === $contenu) { $nb_inchanges++; continue; }
|
|
if (!Ecrire_atomique($chemin, $contenu)) { echo " ! écriture impossible : {$chemin}\n"; continue; }
|
|
if ($existant === null) { $nb_crees++; echo " + {$nom} créé\n"; }
|
|
else { $nb_modifies++; echo " ~ {$nom} mis à jour\n"; }
|
|
}
|
|
|
|
// Suppression des relais qui ne correspondent plus à un bateau éligible (fichiers "bateau-<N>.yml" seulement) :
|
|
foreach (scandir(REPERTOIRE_RELAIS) as $nom)
|
|
{
|
|
if (preg_match(MOTIF_FICHIER_RELAIS, $nom) !== 1 || isset($attendus[$nom])) continue;
|
|
if (unlink(REPERTOIRE_RELAIS."/".$nom)) { $nb_supprimes++; echo " - {$nom} supprimé\n"; }
|
|
else echo " ! suppression impossible : {$nom}\n";
|
|
}
|
|
|
|
echo count($attendus)." bateau(x) éligible(s) : {$nb_crees} créé(s), {$nb_modifies} mis à jour, {$nb_supprimes} supprimé(s), {$nb_inchanges} inchangé(s).\n";
|
|
return 0;
|
|
}
|
|
|
|
exit(Generer_relais_live());
|