A volte è inevitabile eseguire server di database MySQL su una rete pubblica o esposta. Questa è una configurazione comune in un ambiente di hosting condiviso, in cui un server è configurato con più servizi e spesso è in esecuzione all'interno dello stesso server del server di database. Per coloro che hanno questo tipo di configurazione, dovresti sempre avere una sorta di protezione contro attacchi informatici come denial-of-service, hacking, cracking, violazioni dei dati; tutto ciò può causare la perdita di dati. Queste sono cose che vogliamo sempre evitare per il nostro server di database.
Ecco alcuni dei suggerimenti che possiamo fare per migliorare la nostra sicurezza MySQL o MariaDB.
Scansiona regolarmente i tuoi server di database
La protezione contro qualsiasi file dannoso nel server è molto importante. Esegui regolarmente la scansione del server per cercare virus, spyware, malware o rootkit, soprattutto se il server del database si trova insieme ad altri servizi come server di posta, HTTP, FTP, DNS, WebDAV, telnet e così via. In genere, la maggior parte dei problemi di violazione del database sono originati dal livello dell'applicazione che deve affrontare la rete pubblica. Pertanto, è importante eseguire la scansione di tutti i file, in particolare i file Web/applicativi poiché sono uno dei punti di ingresso per accedere al server. Se questi sono compromessi, l'hacker può entrare nella directory dell'applicazione e avere la possibilità di leggere i file dell'applicazione. Questi potrebbero contenere informazioni riservate, ad esempio le credenziali di accesso al database.
ClamAV è una delle soluzioni antivirus più conosciute e ampiamente affidabili per una varietà di sistemi operativi, incluso Linux. È gratuito e molto facile da installare e viene fornito con un meccanismo di rilevamento abbastanza buono per cercare cose indesiderate nel tuo server. Pianifica scansioni periodiche nel lavoro cron, ad esempio:
0 3 * * * /bin/freshclam ; /bin/clamscan / --recursive=yes -i > /tmp/clamav.log ; mail -s clamav_log_`hostname` [email protected] < /tmp/clamav.log
Quanto sopra aggiornerà il database dei virus ClamAV, analizzerà tutte le directory e i file e ti invierà un'e-mail sullo stato dell'esecuzione e segnalerà ogni giorno alle 3 del mattino.
Utilizza ruoli utente e privilegi più severi
Quando si crea un utente MySQL, non consentire a tutti gli host di accedere al server MySQL con host con caratteri jolly (%). Dovresti scansionare il tuo host MySQL e cercare qualsiasi valore host con caratteri jolly, come mostrato nella seguente istruzione:
mysql> SELECT user,host FROM mysql.user WHERE host = '%';
+---------+------+
| user | host |
+---------+------+
| myadmin | % |
| sbtest | % |
| user1 | % |
+---------+------+
Dall'output sopra, restringere o rimuovere tutti gli utenti che hanno solo il valore '%' nella colonna Host. Gli utenti che devono accedere al server MySQL in remoto possono essere obbligati a utilizzare il metodo di tunneling SSH, che non richiede la configurazione dell'host remoto per gli utenti MySQL. La maggior parte dei client di amministrazione MySQL come MySQL Workbench e HeidiSQL possono essere configurati per connettersi a un server MySQL tramite ottimizzazione SSH, quindi è possibile eliminare completamente la connessione remota per gli utenti MySQL.
Inoltre, limita il privilegio SUPER ai soli utenti di localhost o alla connessione tramite file socket UNIX. Prestare maggiore attenzione quando si assegna il privilegio FILE a utenti non root poiché consente di leggere e scrivere file sul server utilizzando le istruzioni LOAD DATA INFILE e SELECT ... INTO OUTFILE. Qualsiasi utente a cui è concesso questo privilegio può anche leggere o scrivere qualsiasi file che il server MySQL può leggere o scrivere.
Modifica le impostazioni predefinite del database
Allontanandoci dall'impostazione, dalla denominazione e dalle configurazioni predefinite, possiamo ridurre il vettore di attacco a un numero di pieghe. Le seguenti azioni sono alcuni esempi di configurazioni predefinite che i DBA potrebbero facilmente modificare ma comunemente trascurate in relazione a MySQL:
- Cambia la porta MySQL predefinita in una porta diversa da 3306.
- Rinomina il nome utente root di MySQL in un modo diverso da "root".
- Applica la scadenza della password e riduce la durata della password per tutti gli utenti.
- Se MySQL si trova insieme ai server delle applicazioni, imporre la connessione solo tramite file socket UNIX e interrompere l'ascolto sulla porta 3306 per tutti gli indirizzi IP.
- Applica la crittografia client-server e la crittografia della replica server-server.
In realtà ne abbiamo parlato in dettaglio in questo post del blog, Come proteggere i server MySQL/MariaDB.
Imposta uno slave ritardato
Uno slave ritardato è solo un tipico slave, tuttavia il server slave esegue intenzionalmente le transazioni in ritardo rispetto al master di almeno un determinato periodo di tempo, disponibile da MySQL 5.6. Fondamentalmente, un evento ricevuto dal master non viene eseguito fino ad almeno N secondi dopo la sua esecuzione sul master. Il risultato è che lo slave rifletterà lo stato del master qualche tempo fa.
Uno slave ritardato può essere utilizzato per recuperare i dati, il che sarebbe utile quando il problema viene rilevato immediatamente, entro il periodo di ritardo. Supponiamo di aver configurato uno slave con un ritardo di 6 ore dal master. Se il nostro database è stato modificato o eliminato (accidentalmente da uno sviluppatore o deliberatamente da un hacker) entro questo intervallo di tempo, c'è la possibilità per noi di tornare al momento giusto prima che accadesse arrestando il master corrente, quindi portando il server slave in alto fino a un certo punto con il seguente comando:
# on delayed slave
mysql> STOP SLAVE;
mysql> START SLAVE UNTIL MASTER_LOG_FILE='xxxxx', MASTER_LOG_POS=yyyyyy;
Dove 'xxxxx' è il file di log binario e 'yyyyy' è la posizione subito prima che si verifichi il disastro (usa lo strumento mysqlbinlog per esaminare quegli eventi). Infine, promuovi lo slave in modo che diventi il nuovo master e il tuo servizio MySQL tornerà operativo come al solito. Questo metodo è probabilmente il modo più veloce per ripristinare il database MySQL nell'ambiente di produzione senza dover ricaricare un backup. Avere un numero di slave ritardati con durate di lunghezza diverse, come mostrato in questo blog, Multiple Delayed Replication Slaves for Disaster Recovery con RTO basso su come configurare un server di replica ritardata conveniente sopra i container Docker.
Abilita registrazione binaria
In genere si consiglia di abilitare la registrazione binaria anche se si esegue su un server MySQL/MariaDB autonomo. Il registro binario contiene informazioni sulle istruzioni SQL che modificano il contenuto del database. Le informazioni vengono archiviate sotto forma di "eventi" che descrivono le modifiche. Nonostante l'impatto sulle prestazioni, avere un registro binario ti consente di avere la possibilità di riprodurre il tuo server di database nel punto esatto in cui desideri che venga ripristinato, noto anche come ripristino point-in-time (PITR). Anche la registrazione binaria è obbligatoria per la replica.
Con la registrazione binaria abilitata, è necessario includere il file di registro binario e le informazioni sulla posizione quando si esegue un backup completo. Per mysqldump, l'utilizzo del flag --master-data con valore 1 o 2 stamperà le informazioni necessarie che possiamo utilizzare come punto di partenza per eseguire il rollforward del database durante la riproduzione dei log binari in seguito.
Con la registrazione binaria abilitata, puoi utilizzare un'altra fantastica funzionalità di ripristino chiamata flashback, descritta nella sezione successiva.
Abilita Flashback
La funzione di flashback è disponibile in MariaDB, dove puoi ripristinare i dati allo snapshot precedente in un database MySQL o in una tabella. Flashback utilizza mysqlbinlog per creare le istruzioni di rollback e per questo necessita di un'immagine di riga di registro binaria COMPLETA. Pertanto, per utilizzare questa funzionalità, il server MySQL/MariaDB deve essere configurato con quanto segue:
[mysqld]
...
binlog_format = ROW
binlog_row_image = FULL
Il seguente diagramma dell'architettura illustra come è configurato il flashback su uno degli slave:
Per eseguire l'operazione di flashback, devi prima determinare la data e l'ora quando vuoi "vedere" i dati o il file di registro binario e la posizione. Quindi, usa il flag --flashback con l'utilità mysqlbinlog per generare istruzioni SQL per ripristinare i dati a quel punto. Nel file SQL generato, noterai che gli eventi DELETE vengono convertiti in INSERT e viceversa, e scambia anche le parti WHERE e SET degli eventi UPDATE.
La seguente riga di comando dovrebbe essere eseguita sullo slave2 (configurato con binlog_row_image=FULL):
$ mysqlbinlog --flashback --start-datetime="2020-02-17 01:30:00" /var/lib/mysql/mysql-bin.000028 -v --database=shop --table=products > flashback_to_2020-02-17_013000.sql
Quindi, scollega slave2 dalla catena di replica perché lo interromperemo e utilizzeremo il server per eseguire il rollback dei nostri dati:
mysql> STOP SLAVE;
mysql> RESET MASTER;
mysql> RESET SLAVE ALL;
Infine, importa il file SQL generato nel server MariaDB per il negozio di database su slave2:
$ mysql -u root -p shop < flashback_to_2020-02-17_013000.sql
Quando viene applicato quanto sopra, la tabella "prodotti" sarà allo stato del 17-02-2020 01:30:00. Tecnicamente, il file SQL generato può essere applicato a entrambi i server MariaDB e MySQL. Puoi anche trasferire il file binario mysqlbinlog dal server MariaDB in modo da poter utilizzare la funzione di flashback su un server MySQL. Tuttavia, l'implementazione di MySQL GTID è diversa da MariaDB, quindi per ripristinare il file SQL è necessario disabilitare MySQL GTID.
Un paio di vantaggi dell'utilizzo del flashback sono che non è necessario arrestare il server MySQL/MariaDB per eseguire questa operazione. Quando la quantità di dati da ripristinare è ridotta, il processo di flashback è molto più rapido rispetto al ripristino dei dati da un backup completo.
Registra tutte le query del database
Il registro generale fondamentalmente cattura ogni istruzione SQL eseguita dal client nel server MySQL. Tuttavia, questa potrebbe non essere una decisione popolare su un server di produzione occupato a causa dell'impatto sulle prestazioni e del consumo di spazio. Se le prestazioni contano, il log binario ha la priorità più alta da abilitare. Il registro generale può essere abilitato durante il runtime eseguendo i seguenti comandi:
mysql> SET global general_log_file='/tmp/mysql.log';
mysql> SET global log_output = 'file';
mysql> SET global general_log = ON;
Puoi anche impostare l'output del registro generale su una tabella:
mysql> SET global log_output = 'table';
Puoi quindi utilizzare l'istruzione SELECT standard rispetto alla tabella mysql.general_log per recuperare le query. Aspettati un impatto leggermente maggiore sulle prestazioni durante l'esecuzione con questa configurazione, come mostrato in questo post del blog.
In caso contrario, puoi utilizzare strumenti di monitoraggio esterni in grado di eseguire il campionamento e il monitoraggio delle query in modo da poter filtrare e controllare le query che arrivano al server. ClusterControl può essere utilizzato per raccogliere e riepilogare tutte le tue query, come mostrato negli screenshot seguenti in cui filtriamo tutte le query che contengono la stringa DELETE:
Informazioni simili sono disponibili anche nella pagina delle query principali di ProxySQL (se l'applicazione è connessione tramite ProxySQL):
Può essere utilizzato per tenere traccia delle modifiche recenti avvenute al server del database e può essere utilizzato anche per scopi di auditing.
Conclusione
I tuoi server MySQL e MariaDB devono essere sempre ben protetti poiché di solito contengono dati sensibili di cui si prendono cura gli aggressori. Puoi anche utilizzare ClusterControl per gestire gli aspetti di sicurezza dei tuoi server di database, come mostrato in questo post del blog, Come proteggere i tuoi database open source con ClusterControl.