MySQL Password Validation, configurazione e utilizzo

Una breve introduzione

Dalla versione 5.6.6 di MySQL, rilasciata nell’agosto del 2012, è stato introdotto un interessante componente che riguarda la gestione delle password degli utenti, il “Password Validation Plugin”.
Si tratta di un utile strumento che serve a definire la politica di gestione delle password degli utenti. Il plugin mette a disposizione un insieme di variabili di sistema attraverso le quali è possibile definire la politica di composizione delle password.

Password, l’eterna lotta…

La gestione della password policy è un argomento molto delicato. Spesso l’amministratore di sistema deve confrontarsi con utenti che ritengono che la data di nascita del proprio gatto/figlio/mutuo sia più che sufficiente.
Non è questo il caso di MySQL, per il quale l’utente tipo corrisponde ad un’altra “trista figura”: lo sviluppatore.
Sysadmin e Developers sanno bene quanto possa essere ostile la rete, dove solo le password più forti sopravvivono…
The Password Validation Plugin è, in questa ottica, un ottimo strumento che costringe aiuta gli utenti a comporre password sicure.

Attivare/Disattivare Password Validation

In alcuni casi, ad esempio in un ambiente di sviluppo e debug, potrebbe essere utile disattivare temporaneamente questo plugin. Ecco come procedere:

# mysql -u root -p
Enter password: 
mysql> UNINSTALL PLUGIN validate_password;
Query OK, 0 rows affected (0,01 sec)

o in alternativa possiamo eseguire la query direttamente dalla shell:

# mysql -u root -p -e "UNINSTALL PLUGIN validate_password";

Ed ecco come riattivarlo:

# mysql -u root -p
Enter password: 
mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';
Query OK, 0 rows affected (0,01 sec)

Proviamo a inserire una password non sicura quando il plugin è attivo:

mysql> ALTER USER USER() IDENTIFIED BY '123456';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

Cerco una Password Validation permanente…

Se nelle fasi iniziali di development e di debug può essere utile fare a meno di questo plugin, quando approdiamo finalmente al Deployment è consigliabile impedirne la disattivazione.
Procediamo, utilizzando l’editor preferito (nel mio caso vim) aggiungendo queste righe nel file my.cnf, all’interno della sezione [mysqld]:

# vi /etc/my.cnf
[mysqld]
...
#Password Validation Plugin
plugin-load=validate_password.so
validate-password=FORCE_PLUS_PERMANENT
...

E’ neseccario riavviare il servizio:

# systemctl restart mysqld

Se adesso provassimo a disabilitare il plugin otterremmo questo risultato:

mysql> UNINSTALL PLUGIN validate_password;
ERROR 1702 (HY000): Plugin 'validate_password' is force_plus_permanent and can not be unloaded

Configurazione

Quando il plugin è attivo, possiamo leggere le variabili di sistema che rappresentano i parametri di controllo delle password:

mysql> SHOW VARIABLES LIKE 'validate_password%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | OFF    |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
  • validate_password_check_user_name: impostato su “ON”, impedisce l’inserimento di password che corrispondano al nome utente anche se scritto al contrario;
  • validate_password_dictionary_file: questo parametro accoglie il percorso relativo o assoluto di un file di testo “dizionario” che contiene una lista di termini vietati nella composizione della password. Nel caso in cui il percorso è relativo, si presume che questo sia posizionato nella “data directory” predefinita di MySQL. Il file contiene una password per ogni riga, e può avere una dimensione massima di 1MB. Le password presenti in questo file non devono contenere lettere maiuscole (le maiuscole vengo ignorate), il controllo viene comunque eseguito anche se l’utente usa caratteri maiuscoli (case-insensitive). Per le versioni di MySQL precedenti la 5.7.8 è necessario riavviare il servizio affinché le modifiche a questo file abbiano effetto. Affinché questo parametro venga incluso nei controlli della password, il parametro validate_password_policy deve essere impostato su STRONG
  • validate_password_length: Definisce il numero di caratteri minimo che deve avere la password affinché il sistema la ritenga valida. Non può contenere un valore inferiore al risultato di questa espressione: validate_password_number_count + validate_password_special_char_count + (2 * validate_password_mixed_case_count).
  • validate_password_mixed_case_count: il numero minimo di caratteri maiuscoli e minuscoli che devono essere presenti affinché a password sia ritenuta valida. Affinché questo parametro venga incluso nei controlli della password, validate_password_policy deve essere impostato su MEDIUM o su STRONG
  • validate_password_number_count: definisce il numero minimo di cifre numeriche che devono essere presenti nella password per essere valida. Affinché questo parametro venga incluso nei controlli della password, validate_password_policy deve essere impostato su MEDIUM o su STRONG
  • validate_password_special_char_count: definisce il numero minimo di caratteri non alfanumerici che devono essere presenti nella password per essere valida. Affinché questo parametro venga incluso nei controlli della password, validate_password_policy deve essere impostato su MEDIUM o su STRONG
  • validate_password_policy: definisce il “livello di sicurezza” della policy. Questo parametro può contenere 3 valori: LOW, MEDIUM, STRONG (che rappresentano i valori numerici 0, 1 e 2). Ognuno di questi 3 livelli “attiva” i precedenti controlli secondo la seguente tabella:
    Valore Controllo eseguito nella verifica della validità della password
    0 o LOW length
    1 o MEDIUM length; number_count, mixed_case_count, special_char_count
    2 o STRONG length; number_count, mixed_case_count, special_char_count, dictionary_file

Status

Quando il plugin è attivo, abbiamo a accesso ad un insieme di variabili di stato dalle quali possiamo trarre utili informazioni sul suo utilizzo.

mysql> SHOW STATUS LIKE 'validate_password%';
+-----------------------------------------------+---------------------+
| Variable_name                                 | Value               |
+-----------------------------------------------+---------------------+
| validate_password_dictionary_file_last_parsed | 2016-10-25 11:15:06 |
| validate_password_dictionary_file_words_count | 0                   |
+-----------------------------------------------+---------------------+
2 rows in set (0,01 sec)

In pratica

In questo scenario configuriamo la policy al livello “STRONG”, creiamo quindi un file per il dizionario delle password e inseriamo una sola riga di prova:

# vi /var/lib/mysql/password_dictionary_file
supersegreto#1

Sistemiamo i permessi

# chown mysql.mysql /var/lib/mysql/password_dictionary_file

Iniziamo la configurazione impostando in controllo sul nome utente

# mysql -u root -p
Enter password: 
mysql> SET GLOBAL validate_password_check_user_name=ON;
Query OK, 0 rows affected (0,00 sec)

Definiamo il file del dizionario delle password con un percorso relativo (abbiamo posizionato il file della data directory)

mysql> SET GLOBAL validate_password_dictionary_file='password_dictionary_file';

Un report dello status ci conferma il buon esito dell’operazione:

mysql> SHOW STATUS LIKE 'validate_password%';
+-----------------------------------------------+---------------------+
| Variable_name                                 | Value               |
+-----------------------------------------------+---------------------+
| validate_password_dictionary_file_last_parsed | 2016-10-25 20:45:39 |
| validate_password_dictionary_file_words_count | 1                   |
+-----------------------------------------------+---------------------+
2 rows in set (0,02 sec)

Infine andiamo a definire il livello della policy:

mysql> SET GLOBAL validate_password_policy=STRONG;
Query OK, 0 rows affected (0,00 sec)

Ecco la configurazione finale:

mysql> SHOW VARIABLES LIKE 'validate_password%';
+--------------------------------------+--------------------------+
| Variable_name                        | Value                    |
+--------------------------------------+--------------------------+
| validate_password_check_user_name    | ON                       |
| validate_password_dictionary_file    | password_dictionary_file |
| validate_password_length             | 8                        |
| validate_password_mixed_case_count   | 1                        |
| validate_password_number_count       | 1                        |
| validate_password_policy             | STRONG                   |
| validate_password_special_char_count | 1                        |
+--------------------------------------+--------------------------+
7 rows in set (0,00 sec)

Proviamo a cambiare la password dell’utente corrente utilizzando la stringa di prova inserita del dizionario:

mysql> ALTER USER USER() IDENTIFIED BY 'SuperSegreto#1';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

Come previsto l’operazione non è andata a buon fine, ma l’utilizzo di una password più robusta dà esito positivo:

mysql> ALTER USER USER() IDENTIFIED BY 'ZF_fu_EX)4r!';
Query OK, 0 rows affected (0,01 sec)

Se adesso riavviassimo il servizio le impostazioni ritornerebbero allo stato precedente, per rendere permanenti le modifiche agiamo sul file di configurazione di MySQL:

# vi /etc/my.cnf
[mysqld]
...
#Password Validation Plugin
plugin-load=validate_password.so
validate-password=FORCE_PLUS_PERMANENT
validate_password_check_user_name=ON
validate_password_policy=STRONG
validate_password_dictionary_file='password_dictionary_file'
...

Fonti