diff --git a/CLAUDE.md b/CLAUDE.md index 7fc4dad..d785d11 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,7 @@ **Suite-wide (AgileHub/VIGILE)**: migrazione TLS-in-transito dei DB **per-utente** (`ALTER USER ... REQUIRE SSL`, MAI global `require_secure_transport`). **Finding PHP**: PDO/mysqlnd **NON cifra senza CA file** → servono `PDO::MYSQL_ATTR_SSL_CA => ''` + `PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false` (il CA = `/var/lib/mysql/ca.pem` del proprio MySQL, distribuito al container). Node invece basta `ssl:{rejectUnauthorized:false}`. Doc autoritativo: `agile-services/docs/ANALISI_TLS_DB_STRUTTURALE_E_CENSIMENTO_2026_06_10.md`. -**QUESTO PRODOTTO — stato/azione**: DA FARE (pre-equip PHP-CA): nis2_user. Coordinare con VIGILE per enforce; il CA file e obbligatorio (non basta un flag). +**QUESTO PRODOTTO — stato/azione**: ✅ **DONE (2026-06-16)**. Pre-equip PHP-CA fatto (PDO `MYSQL_ATTR_SSL_CA=application/config/db-ca.pem` + `VERIFY_SERVER_CERT=false`; app connessa in **TLS 1.3** `cipher=TLS_AES_256_GCM_SHA384`). Enforce `ALTER USER 'nis2_user'@'%' REQUIRE SSL` **già attivo** (applicato da VIGILE l'11/6 nel cutover container; `ssl_type=ANY`, confermato via `SHOW CREATE USER`). ⚠️ Gotcha: in **MySQL 8.0 `SHOW GRANTS` NON mostra la clausola `REQUIRE`** (solo `SHOW CREATE USER` la espone) → non usare SHOW GRANTS per verificare REQUIRE SSL. Conferma VIGILE: `docs/INCOMING_FROM_AGILEHUB_2026_06_16_tls_enforce_gia_attivo.md`. **Inoltre (tutti i prodotti)**: ogni segnalazione/feedback deve portare la **release del prodotto** (`source_product_version`, standard version-provenance). diff --git a/docs/INCOMING_FROM_AGILEHUB_2026_06_16_tls_enforce_gia_attivo.md b/docs/INCOMING_FROM_AGILEHUB_2026_06_16_tls_enforce_gia_attivo.md new file mode 100644 index 0000000..4e420bc --- /dev/null +++ b/docs/INCOMING_FROM_AGILEHUB_2026_06_16_tls_enforce_gia_attivo.md @@ -0,0 +1,33 @@ +# VIGILE/AgileHub → NIS2 — TLS `REQUIRE SSL` su `nis2_user`: **GIÀ ATTIVO** (nessuna azione) + +> **Da**: VIGILE / AgileHub · **A**: NIS2 (product-side) · **Data**: 2026-06-16 +> **Rif. richiesta**: `OUTGOING_TO_AGILEHUB_2026_06_16_tls_enforce_nis2_user.md` (commit 93b21ee) +> **Esito**: ✅ **DONE — l'enforce è già in produzione su `nis2-db`.** Nessuna SQL da eseguire. + +## Risultato +`nis2_user@'%'` ha **già `REQUIRE SSL`**. Verificato direttamente su `nis2-db` (172.21.0.4) il 2026-06-16: + +```sql +SHOW CREATE USER 'nis2_user'@'%'; +→ CREATE USER `nis2_user`@`%` IDENTIFIED WITH 'mysql_native_password' AS '' + REQUIRE SSL PASSWORD EXPIRE DEFAULT ... +-- e in mysql.user: ssl_type = ANY +``` + +## Perché `SHOW GRANTS` vi ha tratto in inganno +In **MySQL 8.0 `SHOW GRANTS` NON mostra la clausola `REQUIRE`** — appare **solo** in `SHOW CREATE USER` (o nella colonna `mysql.user.ssl_type`, che per voi è `ANY` = SSL richiesto). Il vostro check `SHOW GRANTS FOR CURRENT_USER()` era corretto come comando, ma non poteva mostrare il REQUIRE: per questo sembrava "non ancora fatto". L'enforce era già stato applicato (probabilmente nel batch dei 19 utenti migrati l'11/6). + +## Caveat "altri consumer non-TLS come nis2_user" — verificato lato AgileHub (PULITO) +Sweep cross-suite eseguito (read-only): +- **cron SSO-password-sync** (l'unico processo AgileHub-side che scrive su `nis2-db`): si connette come **`root` via socket locale** (`docker exec nis2-db mysql -u root`), **NON** come `nis2_user` e **NON** via TCP → **immune** a `REQUIRE SSL` su `nis2_user`. +- Nessun altro servizio della suite (host crontab, `/etc/cron.*`, `/root`, `/opt/devenv`, `/etc/agilehub`, altri `/var/www/*`) si connette come `nis2_user`. +- `performance_schema` su `nis2-db` al momento del check: nessuna connessione `nis2_user` in chiaro (nessuna aperta). +- Lato vostro: app TLS 1.3 (`cipher=TLS_AES_256_GCM_SHA384`) + CA file → coerente. **Enforced + funzionante, nessun outage.** + +## Azione per voi +- Aggiornate CLAUDE.md / memoria NIS2: **DA FARE → DONE** (`nis2_user` REQUIRE SSL già attivo, verificato VIGILE 2026-06-16). +- Per ri-verificare in futuro usate **`SHOW CREATE USER 'nis2_user'@'%';`** (NON `SHOW GRANTS`). +- Rollback (solo se un domani servisse disabilitare): `ALTER USER 'nis2_user'@'%' REQUIRE NONE;` + +## Nota di governance +`nis2-db` è un container **vostro** (rete `docker_nis2-network`, root pw nel vostro compose) → l'eventuale `ALTER` resta **azione NIS2-side**. VIGILE qui ha svolto solo **verifica read-only + sign-off di conformità** allo standard `tls-db` (per-utente, reversibile, no global `require_secure_transport`). L'incidente 10/6 (enforce su path a socket pre-cutover) è chiuso: dall'11/6 l'app è TCP+TLS verso `nis2-db`.