Utilizzo di% per l’host durante la creazione di un utente MySQL

Il mio database MySQL ha bisogno di due utenti: appuser e supporto.
Uno degli sviluppatori di applicazioni insiste sul fatto che creo quattro account per questi utenti:

[email protected]'%' [email protected]'localhost' [email protected]'%' [email protected]'localhost' 

Per la vita di me non riesco a capire perché pensa che abbiamo bisogno di questo. Non useresti il ​​carattere jolly in quanto l’host si occupa del ‘localhost’?

Qualche idea?

(Usando MySQL 5.5 qui)

Il segno di percentuale indica tutti gli ip così localhost è superfluo … Non c’è bisogno del secondo record con il localhost.

MODIFICARE

In realtà c’è, ‘localhost’ è speciale in mysql, significa una connessione su un socket unix (o named pipe su Windows credo) rispetto a un socket TCP / IP. utilizzando% come l’host non include ‘localhost’

Come @nos ha sottolineato nei commenti della risposta attualmente accettata a questa domanda, la risposta accettata è errata.

Sì, c’è una differenza tra l’utilizzo di % e localhost per l’host dell’account utente quando ci si connette tramite una connessione socket anziché una connessione TCP / IP standard.

Un valore host di % non include localhost per i socket e, pertanto, deve essere specificato se si desidera connettersi utilizzando tale metodo.

Se si desidera connettersi [email protected]'%' da localhost, utilizzare mysql -h192.168.0.1 -uuser -p .

Fornire una risposta leggermente diversa a quelle fornite finora.

Se hai una riga per un utente anonimo da localhost nella tabella ''@'localhost' utenti ''@'localhost' allora questo sarà trattato come più specifico del tuo utente con 'user'@'%' wildcard’d host 'user'@'%' . Questo è il motivo per cui è necessario fornire anche 'user'@'localhost' .

Puoi vedere questo spiegato in maggior dettaglio in fondo a questa pagina .

Il simbolo di percentuale indica: qualsiasi host, comprese le connessioni remote e locali.

L’host locale consente solo connessioni locali.

(quindi, per iniziare, se non hai bisogno di connessioni remote al tuo database, puoi eliminare l’utente appuser @ ‘%’ subito)

Quindi, sì, si stanno sovrapponendo, ma …

… c’è un motivo per impostare entrambi i tipi di account, questo è spiegato nei documenti mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .

Se hai un utente anonimo sul tuo localhost, che puoi individuare con:

 select Host from mysql.user where User='' and Host='localhost'; 

e se si crea l’utente appuser @ ‘%’ (e non si è l’appuser @ ‘localhost’), allora quando l’utente mysql dell’appuser si connette dall’host locale, viene utilizzato l’account utente anonimo (ha la precedenza sull’appuser @ ‘%’ utente).

E la correzione per questo è (come si può intuire) per creare l’appuser @ ‘localhost’ (che è più specifico dell’host anonimo dell’utente locale e verrà utilizzato se l’appuser si connette dall’host locale).

Proviamo solo

Connetti come superutente, quindi:

 SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name           | Value                        | +-------------------------+------------------------------+ | version                 | 10.0.23-MariaDB-0+deb8u1-log | 

e poi

 USE mysql; 

Impostare

Crea un utente foo con la bar password per testare:

 CREATE USER [email protected]'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES; 

Colbind

Per connettersi a Unix Domain Socket (cioè la pipe I / O che viene chiamata dalla voce filesystem /var/run/mysqld/mysqld.sock o alcuni di questi), esegui questo comando sulla riga di comando (usa l’opzione --protocol per rendi doppiamente sicuro)

 mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET 

Ci si aspetta che le corrispondenze sopra “utente provenga da localhost” ma certamente non “l’utente provenga da 127.0.0.1”.

Per connettersi al server da “127.0.0.1”, eseguirlo sulla riga di comando

 mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP 

Se si --protocol=TCP , il comando mysql tenterà comunque di utilizzare il socket del dominio Unix. Puoi anche dire:

 mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1 

I due tentativi di connessione in una riga:

 export MYSQL_PWD=bar; \ mysql -ufoo --protocol=SOCKET --execute="SELECT 1"; \ mysql -ufoo --bind-address=127.0.0.1 --host=127.0.0.1 --execute="SELECT 1" 

(la password è impostata nell’ambiente in modo che venga passata al processo mysql )

Verifica in caso di dubbio

Per verificare realmente se la connessione passa tramite un socket TCP / IP o un socket di dominio Unix

  1. ottenere il PID del processo client mysql esaminando l’output di ps faux
  2. esegui lsof -n -p .

Vedrai qualcosa come:

 mysql [PID] quux 3u IPv4 [code] 0t0 TCP 127.0.0.1:[port]->127.0.0.1:mysql (ESTABLISHED) 

o

 mysql [PID] quux 3u unix [code] 0t0 [code] socket 

Così:

Caso 0: Host = ’10 .10.10.10 ‘(test Null)

 update user set host='10.10.10.10' where user='foo'; flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: GUASTO

Caso 1: Host = ‘%’

 update user set host='%' where user='foo'; flush privileges; 
  • Connetti usando la presa: OK
  • Connetti da 127.0.0.1: OK

Caso 2: Host = ‘localhost’

 update user set host='localhost' where user='foo';flush privileges; 

Il comportamento varia e questo a quanto pare dipende da skip-name-resolve . Se impostato, le linee con localhost devono essere ignorate in base al log. Quanto segue può essere visto nel log degli errori: “voce ‘utente’ root @ localhost ‘ignorata in modalità –skip-name-resolve.” . Questo significa che non ci si connette tramite Unix Domain Socket. Ma questo non è empiricamente il caso. localhost ora significa SOLO l’Unix Domain Socket e non è più associato a 127.0.0.1.

skip-name-resolve è distriggersto:

  • Connetti usando la presa: OK
  • Connetti da 127.0.0.1: OK

skip-name-resolve è skip-name-resolve :

  • Connetti usando la presa: OK
  • Connetti da 127.0.0.1: GUASTO

Caso 3: Host = ‘127.0.0.1’

 update user set host='127.0.0.1' where user='foo';flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: OK

Caso 4: Host = ”

 update user set host='' where user='foo';flush privileges; 
  • Connetti usando la presa: OK
  • Connetti da 127.0.0.1: OK

(Secondo MySQL 5.7: 6.2.4 Controllo accesso, Fase 1: Verifica connessione , La stringa vuota “” significa anche “qualsiasi host”, ma ordina dopo “%”. )

Caso 5: Host = ‘192.168.0.1’ (test aggiuntivo)

(‘192.168.0.1’ è uno degli indirizzi IP della mia macchina, cambia opportunamente nel tuo caso)

 update user set host='192.168.0.1' where user='foo';flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: GUASTO

ma

  • Connetti usando mysql -pbar -ufoo -h192.168.0.1 : OK (!)

Quest’ultimo perché questa è in realtà la connessione TCP proveniente da 192.168.0.1 , come rivelato da lsof :

 TCP 192.168.0.1:37059->192.168.0.1:mysql (ESTABLISHED) 

Edge Case A: Host = ‘0.0.0.0’

 update user set host='0.0.0.0' where user='foo';flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: GUASTO

Edge Case B: Host = ‘255.255.255.255’

 update user set host='255.255.255.255' where user='foo';flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: GUASTO

Edge Case C: Host = ‘127.0.0.2’

(127.0.0.2 è un indirizzo di loopback perfettamente valido equivalente a 127.0.0.1 come definito in RFC6890 )

 update user set host='127.0.0.2' where user='foo';flush privileges; 
  • Connetti usando la presa: FAILURE
  • Connetti da 127.0.0.1: GUASTO

È interessante notare che:

  • mysql -pbar -ufoo -h127.0.0.2 connette da 127.0.0.1 ed è FAILURE
  • mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2 è OK

Pulire

 delete from user where user='foo';flush privileges; 

appendice

Per vedere cosa c’è nella tabella mysql.user , che è una delle tabelle dei permessi, usa:

 SELECT SUBSTR(password,1,6) as password, user, host, Super_priv AS su, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) AS funcs, CONCAT(Repl_slave_priv, Repl_client_priv) AS replic, CONCAT(Shutdown_priv, Process_priv, File_priv, Show_db_priv, Reload_priv, Create_user_priv) AS admin FROM user ORDER BY user, host; 

questo da:

 +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin | +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN | 

Allo stesso modo per la tabella mysql.db :

 SELECT host,db,user, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv) AS funcs FROM db ORDER BY user, db, host;