Utilizzo di% come host durante la creazione di un utente MySQL


93

Il mio database MySQL necessita di due utenti: utente app e supporto.
Uno degli sviluppatori dell'applicazione insiste che crei quattro account per questi utenti:

appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'

Per quanto mi riguarda, non riesco a capire perché pensa che ne abbiamo bisogno. L'utilizzo del carattere jolly come host non si occuperebbe del "localhost"?

Qualche idea?

(Utilizzando MySQL 5.5 qui)

Risposte:


106

localhostè speciale in MySQL, significa una connessione su un socket UNIX (o named pipe su Windows, credo) invece di un socket TCP / IP. L'utilizzo %come host non include localhost, da qui la necessità di specificarlo esplicitamente.


In quale versione? In MySQL 5.5.35, "%" corrisponde anche a localhost.
depquid

4
Non solo "localhost" si connette tramite il socket locale, 127.0.0.1 (che non usa il socket) non corrisponderà a% ma anche localhost. L'ho visto con un'installazione proxy oggi.
Phillipp

33

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

Sì, c'è una differenza tra l'utilizzo %e localhostper l'host dell'account utente quando ci si connette tramite una connessione socket invece di una connessione TCP / IP standard.

Un valore host di %non include localhostper i socket e quindi deve essere specificato se si desidera connettersi utilizzando quel metodo.


15

Facciamo solo un test.

Connettiti 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 foocon password barper il test:

CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;

Collegare

Per connetterti a Unix Domain Socket (cioè il pipe I / O che è chiamato dalla voce del filesystem /var/run/mysqld/mysqld.socko qualcosa di simile), eseguilo dalla riga di comando (usa l' --protocolopzione per essere doppiamente sicuro)

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

Ci si aspetta che la corrispondenza di cui sopra "l'utente proviene da localhost" ma certamente non "l'utente proviene da 127.0.0.1".

Per connettersi al server da "127.0.0.1", invece, eseguirlo dalla riga di comando

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

Se si omette --protocol=TCP, il mysqlcomando proverà comunque a 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 mysqlprocesso)

Verifica in caso di dubbio

Per verificare realmente se la connessione avviene 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. corri lsof -n -p<yourpid>.

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 nullo)

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

Caso 1: Host = '%'

update user set host='%' where user='foo'; flush privileges;
  • Connetti tramite 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 apparentemente dipende da skip-name-resolve. Se impostato, fa sì che le righe con localhostvengano ignorate in base al registro. Quanto segue può essere visto nel registro degli errori: "'voce utente' root @ localhost 'ignorata in modalità --skip-name-resolved." . Ciò significa nessuna connessione tramite Unix Domain Socket. Ma empiricamente non è così. localhostora significa SOLO il socket di dominio Unix e non corrisponde più a 127.0.0.1.

skip-name-resolve è spento:

  • Connetti tramite presa: OK
  • Connetti da 127.0.0.1: OK

skip-name-resolve è acceso:

  • Connetti tramite presa: OK
  • Connetti da 127.0.0.1: FAILURE

Caso 3: Host = "127.0.0.1"

update user set host='127.0.0.1' where user='foo';flush privileges;
  • Collegamento tramite presa: GUASTO
  • Connetti da 127.0.0.1: OK

Caso 4: Host = ''

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

(Secondo MySQL 5.7: 6.2.4 Controllo degli accessi, Fase 1: Verifica della connessione , la stringa vuota "" significa anche "qualsiasi host" ma ordina dopo "%". )

Caso 5: Host = "192.168.0.1" (test extra)

("192.168.0.1" è uno degli indirizzi IP della mia macchina, cambia in modo appropriato nel tuo caso)

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

ma

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

Quest'ultimo perché si tratta in realtà di una 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;
  • Collegamento tramite presa: GUASTO
  • Connetti da 127.0.0.1: FAILURE

Edge Case B: Host = "255.255.255.255"

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

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;
  • Collegamento tramite presa: GUASTO
  • Connetti da 127.0.0.1: FAILURE

È interessante notare che:

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

Pulire

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

Addendum

Per vedere cosa c'è effettivamente nella mysql.usertabella, 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;

6
Ciò richiede una conclusione che renda chiaro ciò che il resto della risposta sta effettivamente dicendo senza bisogno di capire il codice.
Prometeo

7

Se vuoi connetterti a user@'%'da localhost usa mysql -h192.168.0.1 -uuser -p.


5

Andando a fornire una risposta leggermente diversa da quelle fornite finora.

Se hai una riga per un utente anonimo da localhost nella tabella degli utenti, ''@'localhost'questa verrà trattata come più specifica del tuo utente con host jolly 'user'@'%'. Questo è il motivo per cui è necessario fornire anche 'user'@'localhost'.

Puoi vederlo spiegato in maggior dettaglio in fondo a questa pagina .


5

Il simbolo della percentuale significa: qualsiasi host, comprese le connessioni remote e locali.

Il localhost consente solo connessioni locali.

(quindi per cominciare, se non hai bisogno di connessioni remote al tuo database, puoi sbarazzarti subito dell'utente appuser @ '%')

Quindi, sì, si sovrappongono, 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 crei solo l'utente appuser @ '%' (e non tu l'appuser @ 'localhost'), quando l'utente appuser mysql si connette dall'host locale, viene utilizzato l'account utente anonimo (ha la precedenza sul tuo appuser @ '%' utente).

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.