[FEAT] TLS-DB pre-equip nis2: PDO SSL gated default-OFF + CA (VIGILE 2026-06-10)
database.php: Database::sslOptions() — TLS verso MySQL gated (env DB_SSL=true o flag-file application/config/.db_ssl_on), DEFAULT OFF. PDO::MYSQL_ATTR_SSL_CA + VERIFY_SERVER_CERT=false; fail-safe se CA assente (resta in chiaro + log: un VERIFY=false senza CA connetterebbe in chiaro silenziosamente). Merge con '+' (preserva chiavi-intere PDO). Default-OFF provato inerte (base + [] === base). Validato da 2 agenti: runtime app coperto 100% da Database::getInstance (0 raw PDO in application/); review adversariale = SICURO default-OFF, nessun bug. .gitignore: flag-file + db-ca.pem. Runbook: docs/TLS_DB_PREEQUIP_NIS2.md. NB topologia verificata: l'app usa il DB CONTAINER (db->172.21.0.4, 8.0.45), non il MySQL host -> CA + enforce vanno sul container db (a cura VIGILE). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
16790d25a4
commit
4d89b1e04b
@@ -41,6 +41,11 @@ class Database
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
];
|
||||
|
||||
// TLS-in-transito (VIGILE 2026-06-10) — pre-equip, GATED, DEFAULT OFF.
|
||||
// Unione con '+' (NON array_merge): preserva le chiavi-intere delle
|
||||
// opzioni PDO (array_merge le re-indicizzerebbe). Vedi doc VIGILE §14.
|
||||
$options = $options + self::sslOptions();
|
||||
|
||||
try {
|
||||
self::$instance = new PDO($dsn, DB_USER, DB_PASS, $options);
|
||||
} catch (PDOException $e) {
|
||||
@@ -55,6 +60,43 @@ class Database
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opzioni PDO per TLS-in-transito verso MySQL (VIGILE 2026-06-10, pre-equip).
|
||||
*
|
||||
* GATED, DEFAULT OFF: ritorna [] (nessuna modifica al comportamento attuale)
|
||||
* a meno che NON sia attivato esplicitamente tramite:
|
||||
* - env DB_SSL=true (canonico)
|
||||
* - OPPURE flag-file application/config/.db_ssl_on (robusto anche in
|
||||
* PHP-FPM dove getenv() puo' non propagare; nessun recreate necessario)
|
||||
*
|
||||
* IMPORTANTE (doc VIGILE §11): PHP PDO/mysqlnd NON cifra senza un CA file.
|
||||
* MYSQL_ATTR_SSL_VERIFY_SERVER_CERT=false DA SOLO connette IN CHIARO. Quindi
|
||||
* il TLS si attiva solo se il CA e' presente e leggibile; altrimenti si
|
||||
* resta in chiaro (come oggi) e si logga — MAI una connessione "a meta'".
|
||||
* CA host self-signed => VERIFY_SERVER_CERT=false (cifra il canale; la
|
||||
* verifica della CA e' hardening successivo, coordinato con VIGILE).
|
||||
*
|
||||
* @return array opzioni PDO SSL (vuoto se disattivato o CA mancante)
|
||||
*/
|
||||
private static function sslOptions(): array
|
||||
{
|
||||
$enabled = Env::bool('DB_SSL', false) || is_file(__DIR__ . '/.db_ssl_on');
|
||||
if (!$enabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ca = Env::get('DB_SSL_CA', __DIR__ . '/db-ca.pem');
|
||||
if (!$ca || !is_file($ca) || !is_readable($ca)) {
|
||||
error_log('[Database] DB_SSL attivo ma CA non trovato/leggibile (' . $ca . '): connessione NON cifrata (serve il CA file).');
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
PDO::MYSQL_ATTR_SSL_CA => $ca,
|
||||
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Esegue una query con parametri
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user