Azure SQL è PaaS: la superficie da configurare non è il sistema operativo, è il logical server. Ci stanno sopra tre strati — perimetro di rete, cifratura, tracciamento — e ognuno ha un default che copre metà del problema.
Il perimetro: firewall del logical server e «Allow Azure services»
Un logical server appena creato nega tutte le connessioni finché non aggiungi una regola. Le regole IP vivono a due livelli: quelle server-level valgono per tutti i database; quelle database-level valgono per un solo database e si impostano soltanto in T-SQL, con sp_set_database_firewall_rule. Ogni modifica può impiegare fino a 5 minuti a propagarsi.
L’impostazione su cui si sbaglia è Allow Azure services and resources to access this server. Alla creazione da portale è deselezionata. Quando la accendi, Azure aggiunge dietro le quinte una regola firewall con IP iniziale e finale 0.0.0.0, e il server accetta traffico da tutte le risorse dentro il confine Azure, anche di sottoscrizioni e tenant che non sono i tuoi. Non significa «consenti alle mie VM»: significa «consenti a chiunque abbia una VM in Azure di presentarsi al gateway». Resta l’autenticazione, ma il perimetro di rete sparisce. Le alternative: regole IP puntuali, virtual network rule su subnet con service endpoint, private endpoint. Nulla di questo vale per SQL Managed Instance, che vive in una subnet delegata e si protegge con NSG.
Cifratura: TDE è acceso di default, ma non ovunque
TDE cifra dati a riposo, backup e log delle transazioni ed è attivo di default su tutti i database SQL Database di nuova creazione. Le eccezioni fanno fallire gli audit: i database creati prima di maggio 2017 (febbraio 2019 per Managed Instance) non sono cifrati, e un database nato da restore, geo-replica o copia eredita lo stato della sorgente — se la sorgente era in chiaro, la copia nasce in chiaro. Il controllo autoritativo è la colonna encryption_state_desc della DMV sys.dm_database_encryption_keys, non la casella nel portale.
Il TDE protector si imposta a livello di server o istanza ed è ereditato dai database. Con la chiave gestita dal servizio non hai nulla da fare, rotazione annuale inclusa. Con customer-managed key in Key Vault o Managed HSM guadagni controllo su rotazione e revoca, e il rischio corrispondente: se al server vengono revocati i permessi sul vault, il database diventa inaccessibile. TDE non c’entra con il transito, sempre cifrato lato servizio: lì la regola è Encrypt=True con TrustServerCertificate=False.
Auditing su SQL Database: server o database, non entrambi per distrazione
Il criterio di default cattura tre action group: BATCH_COMPLETED_GROUP, SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP, FAILED_DATABASE_AUTHENTICATION_GROUP. Il criterio di server si applica a tutti i database esistenti e futuri; se ne accendi anche uno a livello di database, i due convivono e scrivono entrambi. È il modo più rapido per raddoppiare volume e costo senza accorgersene.
Le destinazioni sono tre — storage account, Log Analytics, Event Hubs — combinabili, e i log finiscono su tutte. Due dettagli:
- su storage l’autenticazione può essere managed identity o chiave di accesso: usa la managed identity. La retention di default è 0, cioè illimitata, e se poi la abbassi vale solo per i log scritti da quel momento in avanti;
- verso Log Analytics o Event Hubs viene creata una diagnostic setting con categoria
SQLSecurityAuditEvents. Se qualcuno la cancella, l’auditing smette di funzionare in silenzio: metti un alert sulla cancellazione delle diagnostic setting.
Un limite che sorprende: con l’autenticazione Microsoft Entra i login falliti non compaiono nell’audit SQL, perché la credenziale viene verificata prima che il database venga raggiunto. Quegli eventi si cercano nell’interfaccia di amministrazione Entra.
Su Managed Instance è SQL Server Audit
Su SQL Managed Instance non configuri «l’auditing di SQL Database»: configuri SQL Server Audit, con due varianti nella sintassi T-SQL. TO URL scrive i file .xel in un container blob, TO EXTERNAL MONITOR manda a Event Hubs o Log Analytics. TO FILE non è supportato, e non lo sono l’opzione di shutdown e queue_delay pari a 0. Lato database servono ALTER ANY DATABASE AUDIT per configurare e VIEW DATABASE SECURITY AUDIT per leggere i log via T-SQL; lato Azure, Storage Blob Data Contributor o Monitoring Contributor secondo la destinazione.
Due trappole. L’audit delle operazioni di supporto Microsoft va creato come server audit separato: se spunti quella casella su un audit esistente lo sovrascrivi, e da lì in poi registrerà solo le operazioni di supporto. E appena acceso l’auditing vedrai login falliti ogni 10 secondi da AzureSQLConnectivityChecker: sono i test interni di connettività dell’istanza, non un attacco.
Defender for Databases: quattro piani sotto un interruttore
In Defender for Cloud «Databases» non è un piano, è un contenitore di quattro: Defender for Azure SQL Databases, Defender for SQL Servers on Machines, Defender for Open-Source Relational Databases (PostgreSQL e MySQL, anche su AWS RDS) e Defender for Azure Cosmos DB. L’interruttore Databases in Environment settings li attiva tutti e quattro, e ognuno ha un prezzo a sé.
Defender for Azure SQL Databases copre database singoli ed elastic pool, SQL Managed Instance e i dedicated SQL pool di Synapse, oltre a SQL Server su VM Azure e abilitato da Azure Arc. Porta vulnerability assessment, che traccia le configurazioni deboli, e Advanced Threat Protection, che segnala SQL injection, accessi anomali, brute force e connessioni da macchine compromesse. Si abilita per sottoscrizione e vale anche per le risorse future.
Un chiarimento: questi alert nascono e si consultano in Microsoft Defender for Cloud, prodotto e portale diversi da Microsoft Defender XDR. Non sono sinonimi, e la domanda su dove vedi l’alert conta su questa confusione.