Meu banco de dados MySQL precisa de dois usuários: appuser e suporte.
Um dos desenvolvedores de aplicativos insiste que eu crie quatro contas para esses usuários:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Pela minha vida, não consigo descobrir por que ele acha que precisamos disso. Usar o curinga como host não cuidaria do 'localhost'?
Alguma ideia?
(Usando MySQL 5.5 aqui)
Como @nos apontou nos comentários da resposta atualmente aceita para esta pergunta, a resposta aceita está incorreta.
Sim, HÁ uma diferença entre usar
%
elocalhost
para o host da conta do usuário ao conectar por meio de uma conexão de soquete em vez de uma conexão TCP / IP padrão.Um valor de host de
%
não incluilocalhost
para sockets e, portanto, deve ser especificado se você deseja se conectar usando esse método.fonte
Vamos apenas testar.
Conecte-se como superusuário e, em seguida:
SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | version | 10.0.23-MariaDB-0+deb8u1-log |
e depois
USE mysql;
Configuração
Crie um usuário
foo
com senhabar
para teste:CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Conectar
Para se conectar ao Unix Domain Socket (ou seja, o I / O pipe que é nomeado pela entrada do sistema de arquivos
/var/run/mysqld/mysqld.sock
ou algo assim), execute-o na linha de comando (use a--protocol
opção para ter certeza dupla)mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET
Espera-se que o acima corresponda a "usuário vem de localhost", mas certamente não "usuário vem de 127.0.0.1".
Para se conectar ao servidor de "127.0.0.1" em vez disso, execute-o na linha de comando
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Se você omitir
--protocol=TCP
, omysql
comando ainda tentará usar o soquete de domínio Unix. Você também pode dizer:mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
As duas tentativas de conexão em uma 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
processo)Verificação em caso de dúvida
Para realmente verificar se a conexão passa por um soquete TCP / IP ou um soquete de domínio Unix
ps faux
lsof -n -p<yourpid>
.Você verá algo como:
ou
Então:
Caso 0: Host = '10 .10.10.10 '(teste nulo)
update user set host='10.10.10.10' where user='foo'; flush privileges;
Caso 1: Host = '%'
update user set host='%' where user='foo'; flush privileges;
Caso 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
O comportamento varia e isso aparentemente depende
skip-name-resolve
. Se definido, faz com que as linhas comlocalhost
sejam ignoradas de acordo com o registro. O seguinte pode ser visto no log de erros: "Entrada de 'usuário' 'root @ localhost' ignorada no modo --skip-name-resolve." . Isso significa nenhuma conexão por meio do soquete de domínio Unix. Mas este não é o caso empiricamente.localhost
agora significa SOMENTE o soquete de domínio Unix e não corresponde mais a 127.0.0.1.skip-name-resolve
está fora:skip-name-resolve
está ligado:Caso 3: Host = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
Caso 4: Host = ''
update user set host='' where user='foo';flush privileges;
(De acordo com MySQL 5.7: 6.2.4 Controle de acesso, Estágio 1: Verificação de conexão , a string vazia '' também significa “qualquer host”, mas é classificada após '%'. )
Caso 5: Host = '192.168.0.1' (teste extra)
('192.168.0.1' é um dos endereços IP da minha máquina, altere apropriadamente no seu caso)
update user set host='192.168.0.1' where user='foo';flush privileges;
mas
mysql -pbar -ufoo -h192.168.0.1
: OK (!)Este último porque esta é realmente uma conexão TCP proveniente
192.168.0.1
, conforme revelado porlsof
:Caso Edge A: Host = '0.0.0.0'
update user set host='0.0.0.0' where user='foo';flush privileges;
Edge Case B: Host = '255.255.255.255'
update user set host='255.255.255.255' where user='foo';flush privileges;
Edge Case C: Host = '127.0.0.2'
(127.0.0.2 é um endereço de loopback perfeitamente válido equivalente a 127.0.0.1 conforme definido em RFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
Curiosamente:
mysql -pbar -ufoo -h127.0.0.2
conecta de127.0.0.1
e é FALHAmysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
está bemLimpar
delete from user where user='foo';flush privileges;
Termo aditivo
Para ver o que realmente está na
mysql.user
tabela, 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 |
Da mesma forma para a mesa
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;
fonte
Se você quiser se conectar a
user@'%'
partir do localhost, usemysql -h192.168.0.1 -uuser -p
.fonte
O símbolo de porcentagem significa: qualquer host, incluindo conexões remotas e locais.
O localhost permite apenas conexões locais.
(então, para começar, se você não precisa de conexões remotas com seu banco de dados, você pode se livrar do usuário appuser @ '%' imediatamente)
Então, sim, eles estão se sobrepondo, mas ...
... há uma razão para definir os dois tipos de contas, isso é explicado nos documentos do mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .
Se você tiver um usuário anônimo em seu host local, que poderá identificar com:
select Host from mysql.user where User='' and Host='localhost';
e se você apenas criar o usuário appuser @ '%' (e não o appuser @ 'localhost'), então quando o usuário appuser mysql se conecta a partir do host local, a conta de usuário anônima é usada (tem precedência sobre seu appuser @ '%' do utilizador).
E a correção para isso é (como se pode imaginar) criar o appuser @ 'localhost' (que é mais específico que o usuário anônimo do host local e será usado se o seu appuser se conectar a partir do localhost).
fonte
Indo para fornecer uma resposta ligeiramente diferente das fornecidas até agora.
Se você tiver uma linha para um usuário anônimo de localhost em sua tabela de usuários
''@'localhost'
, isso será tratado como mais específico do que seu usuário com host com curinga'user'@'%'
. É por isso que é necessário também fornecer'user'@'localhost'
.Você pode ver isso explicado com mais detalhes no final desta página .
fonte