Usar % para a máquina ao criar um utilizador de MySQL
Um dos desenvolvedores de aplicativos insiste que eu crio quatro contas para esses usuários:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Pela minha vida, não consigo perceber porque é que ele acha que precisamos disto. Usar o wildcard como hospedeiro não cuidaria do "localhost"?
Alguma ideia?
(Usando o MySQL 5.5 aqui)
6 answers
Editar
Na verdade existe, 'localhost' é especial no mysql, significa uma conexão sobre um soquete unix (ou tubes nomeados no windows que eu acredito) em oposição a um soquete TCP/IP. a utilização de % como máquina não inclui 'localhost'
Sim, existe uma diferença entre a utilização de %
e localhost
para a máquina de conta do utilizador ao ligar-se através de uma ligação de 'socket' em vez de uma ligação TCP/IP normal.
Um valor da máquina de %
não inclui localhost
para os 'sockets', pelo que deverá ser indicado se quiser ligar-se com esse método.
Se quiser ligar-se a user@'%'
a partir de localhost use mysql -h192.168.0.1 -uuser -p
.
Vai dar uma resposta ligeiramente diferente das fornecidas até agora.
Se tiver uma linha para um utilizador anónimo de localhost na sua tabela de utilizadores {[[0]}, então esta será tratada como mais específica do que o seu utilizador com o servidor de wildcard 'user'@'%'
. É por isso que é necessário também fornecer 'user'@'localhost'
.
Você pode ver isso explicado em mais detalhes no final de esta página .
O símbolo percentual significa: qualquer hospedeiro, incluindo ligações remotas e locais.
O localhost só permite ligações locais.
(para começar, se não precisar de ligações remotas à sua base de dados, poderá livrar-se imediatamente do utilizador appuser@'%')
Então, sim, eles estão sobrepostos, mas ... .....há uma razão para definir ambos os tipos de contas, isso é explicado no mysql documento: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html.
Se tem um utilizador anónimo no seu local, que pode ver com:
select Host from mysql.user where User='' and Host='localhost';
E se criar o utilizador appuser@'%' (e não o appuser@'localhost'), então quando o utilizador do appuser mysql liga-se da máquina local, a conta de utilizador anónima é usada (tem precedência sobre o seu utilizador do appuser@'%').
E a solução para isto é (como se pode adivinhar) criar o appuser@ 'localhost' (que é mais específico que o utilizador anónimo da máquina local e será usado se o seu utilizador se ligar a partir do localhost).
Liga-te como super-utilizador, e depois:
SHOW VARIABLES LIKE "%version%";
+-------------------------+------------------------------+
| Variable_name | Value |
+-------------------------+------------------------------+
| version | 10.0.23-MariaDB-0+deb8u1-log |
E depois
USE mysql;
Configuração
Criar um utilizador foo
com senha bar
para testar:
CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Ligar
Para se ligar ao 'Socket' do domínio Unix (isto é, o 'pipe' de I/O que é nomeado pelo item do sistema de ficheiros /var/run/mysqld/mysqld.sock
ou algo do género), execute isto na linha de comandos (use a opção --protocol
para se certificar duplamente)
mysql -pbar -ufoo
mysql -pbar -ufoo --protocol=SOCKET
Espera-se que o acima corresponde "user comes from localhost" but certain not "user comes from 127.0.0.1".
Para se ligar ao servidor a partir de "127. 0. 0. 1" em vez disso, execute isto na linha de comandos
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Se deixar de fora --protocol=TCP
, o comando mysql
irá à mesma tentar usar o 'socket' do domínio Unix. Também podes dizer:
mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
As duas tentativas de ligação numa linha:
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"
(a senha é definida no ambiente para que seja passada para o mysql
process)
Verificação Em Caso De Dúvida
Para verificar realmente se a ligação passa por um 'socket' TCP/IP ou por um 'socket' de domínio Unix
- obter o PID do processo do cliente mysql examinando a saída de
ps faux
- corre
lsof -n -p<yourpid>
Vais ver algo como:
mysql [PID] quux 3u IPv4 [code] 0t0 TCP 127.0.0.1:[port]->127.0.0.1:mysql (ESTABLISHED)
Ou
mysql [PID] quux 3u unix [code] 0t0 [code] socket
Então,:
Caso 0: Host = "10.10.10.10" (ensaio nulo)
update user set host='10.10.10.10' where user='foo'; flush privileges;
- ligar usando o 'socket': Falha
- ligar a partir de 127.0.0.1: falha
Caso 1: Máquina = ' % '
update user set host='%' where user='foo'; flush privileges;
- ligar usando o 'socket': OK
- ligar a partir de 127. 0. 1: OK
Caso 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
O comportamento varia e aparentemente depende skip-name-resolve
. Se definido, faz com que as linhas com localhost
sejam ignoradas de acordo com o registo. Pode ver-se o seguinte no registo de erros: "a entrada' utilizador 'root@localhost' ignorada em -- modo de ignorar nomes-resolver.". Isto significa que não se conecta através do soquete de domínio Unix. Mas isto não é empiricamente o caso. localhost
agora significa apenas o soquete de domínio Unix, e já não corresponde ao 127.0.0.1.
skip-name-resolve
está desligado.
- ligar usando o 'socket': OK
- ligar a partir de 127. 0. 1: OK
skip-name-resolve
está em:
- ligar usando o 'socket': OK
- ligar a partir de 127.0.0.1: falha
Caso 3: Máquina = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
- ligar usando o 'socket': falha
- ligar a partir de 127. 0. 1: OK
Caso 4: Host = "
update user set host='' where user='foo';flush privileges;
- ligar usando o 'socket': OK
- ligar a partir de 127. 0. 1: OK
(De acordo com MySQL 5.7: 6.2.4 controlo de acesso, Fase 1: Verificação da ligação, o texto vazio "também significa " qualquer máquina", mas ordena depois de '%'. )
Processo 5: Host = " 192.168.0.1 "(extra test)
('192.168.0.1' é um dos endereços IP da minha máquina, mude apropriadamente no seu caso)
update user set host='192.168.0.1' where user='foo';flush privileges;
- ligar usando o 'socket': falha
- ligar a partir de 127.0.0.1: falha
Mas
- ligue-se usando
mysql -pbar -ufoo -h192.168.0.1
: OK (!)
Este último porque esta é de facto uma ligação TCP vinda de 192.168.0.1
, como revelado por lsof
:
TCP 192.168.0.1:37059->192.168.0.1:mysql (ESTABLISHED)
Caixa A: Máquina = '0, 0, 0'
update user set host='0.0.0.0' where user='foo';flush privileges;
- ligar usando o 'socket': Falha
- ligar a partir de 127.0.0.1: falha
Caso Edge B: Host = '255. 255. 255. 255'
update user set host='255.255.255.255' where user='foo';flush privileges;
- ligar usando o 'socket': falha
- ligar a partir de 127.0.0.1: falha
Caixa De Bordo C: Máquina = '127. 0. 0. 2'
(127.0.0.2 é perfeitamente válida endereço de auto-retorno equivalente ao 127.0.0.1 como definido no RFC6890)
update user set host='127.0.0.2' where user='foo';flush privileges;
- ligar usando o 'socket': falha
- ligar a partir de 127. 0. 0. 1: Falha
-
mysql -pbar -ufoo -h127.0.0.2
liga-se de {[41] } e é falha -
mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
está OK
Limpeza
delete from user where user='foo';flush privileges;
Adenda
Para ver o que está realmente na tabela mysql.user
, que é uma das tabelas de permissão, use:
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;
Isto dá:
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+
| password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin |
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+
| *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
Igualmente para o quadro 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;