Erro no MySQL: acesso negado para o usuário 'a' @ 'localhost' (usando a senha: YES)

22

Eu uso a conta raiz criou a conta 'a'@'%'. Mas não posso usar a conta para conectar-me ao servidor MySQL quando especifico o parâmetro host. Eu posso conectar com sucesso sem o -hparâmetro Por favor, veja a transcrição abaixo. Espero que alguém possa me ajudar a explicar isso. Obrigado.

mysql> grant all on *.* to 'a'@'%' identified by a;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a' at line 1
mysql> grant all on *.* to 'a'@'%' identified by 'a';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for 'a'@'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for a@%                                                                                            |
+-----------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'a'@'%' IDENTIFIED BY PASSWORD '*667F407DE7C6AD07358FA38DAED7828A72014B4E' |
+-----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye

[root@localhost ~]# mysql -h localhost -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -h 127.0.0.1 -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -u a
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.5.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql> status
--------------
mysql  Ver 14.14 Distrib 5.5.17, for Linux (x86_64) using readline 5.1

Connection id:      20
Current database:   
Current user:       a@localhost
SSL:            Not in use
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.5.17 MySQL Community Server (GPL)
Protocol version:   10
Connection:     Localhost via UNIX socket
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:        /var/lib/mysql/mysql.sock
Uptime:         15 days 15 hours 20 min 18 sec

Threads: 1  Questions: 40  Slow queries: 0  Opens: 41  Flush tables: 1  Open tables: 4  Queries per second avg: 0.000
--------------

mysql> 

Editar:

Sim, o MySQL está escutando na porta 3306.

[root@localhost ~]# nmap localhost

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-01-18 07:35 CST
Interesting ports on localhost.localdomain (127.0.0.1):
Not shown: 1674 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
111/tcp  open  rpcbind
631/tcp  open  ipp
840/tcp  open  unknown
3306/tcp open  mysql

Nmap finished: 1 IP address (1 host up) scanned in 0.064 seconds
[root@localhost ~]# 
Apenas um aprendiz
fonte
1
Eu não sou especialista em MySql, mas vi esse problema algumas vezes, não sei qual era o motivo, a solução era explicitamente a definição de host além de 'a'@'%'. então, o primeiro registro foi 'a'@'%'e o segundo é 'a'@'localhost'.
com
você pode testar a mesma coisa com a versão mais baixa do mysql ..?
Abdul Manaf
use os detalhes de login do Cpanel para se conectar.
Abu Fahim
No meu caso eu tinha três contas annonymous criados por padrão, excluí-los iria resolver esta questão
Joaquín L. Robles

Respostas:

26

Aqui está um método rápido e sujo para verificar como o MySQL executa uma autenticação bem-sucedida.

Por favor, execute esta consulta:

SELECT USER(),CURRENT_USER();

USER () relata como você tentou se autenticar no mysqld

CURRENT_USER () relata como você foi autorizado a se autenticar pelo mysqld

Às vezes, USER()e CURRENT_USER()são diferentes. Isso ocorre porque a autenticação mysql segue um protocolo específico.

De acordo com o Guia de Estudo de Certificação do MySQL 5.0

insira a descrição da imagem aqui

as páginas 486.487 afirmam o seguinte no algoritmo de autenticação do mysql:

Há dois estágios no controle de acesso do cliente:

No primeiro estágio, um cliente tenta se conectar e o servidor aceita ou rejeita a conexão. Para que a tentativa tenha êxito, alguma entrada na tabela de usuários deve corresponder ao host do qual o cliente se conecta, o nome de usuário e a senha.

No segundo estágio (que ocorre apenas se um cliente já tiver se conectado com êxito), o servidor verifica todas as consultas que recebe do cliente para verificar se o cliente possui privilégios suficientes para executá-lo.

O servidor combina um cliente com as entradas nas tabelas de concessão com base no host do qual o cliente se conecta e no usuário que o cliente fornece. No entanto, é possível que mais de um registro corresponda:

Os valores do host nas tabelas de concessão podem ser especificados, pois os padrões contêm valores curinga. Se uma tabela concessão contém entradas de myhost.example.com, %.example.com, %.com, e %, todos eles correspondem a um cliente que se conecta a partir myhost.example.com.

Os padrões não são permitidos para os valores de Usuário nas entradas da tabela de concessão, mas um nome de usuário pode ser fornecido como uma sequência vazia para especificar um usuário anônimo. A cadeia vazia corresponde a qualquer nome de usuário e, portanto, atua efetivamente como um curinga.

Quando os valores Host e Usuário em mais de um registro da tabela de usuários correspondem a um cliente, o servidor deve decidir qual usar. Isso é feito classificando primeiro os registros com os valores mais específicos da coluna Host e Usuário e escolhendo o registro correspondente que ocorre primeiro na lista classificada. A classificação ocorre da seguinte maneira:

Na coluna Host, valores literais, tais como localhost, 127.0.0.1e myhost.example.comtipo à frente de valores como a %.example.com que têm caracteres padrão em si. Os valores do padrão são classificados de acordo com a especificidade deles. Por exemplo, %.example.comé mais específico que %.com, que é mais específico que %.

Na coluna Usuário, os nomes de usuário que não estão em branco são classificados à frente dos nomes de usuário em branco. Ou seja, usuários não anônimos se classificam à frente de usuários anônimos.

O servidor executa essa classificação quando é iniciado. Ele lê as tabelas de concessão na memória, classifica-as e usa as cópias na memória para controle de acesso.

Nesta descrição, você não precisa se preocupar com a ordem das tabelas mysql.user, pois há uma cópia em memória das tabelas de concessão, que é classificada como mencionado anteriormente.

No que diz respeito à forma como você fez login, apenas mysql -u afuncionou. Volte e faça o login novamente e execute estes comandos

SELECT USER(),CURRENT_USER();
SELECT user,host,password FROM mysql.user;

Certifique-se de que

  • todo usuário tem uma senha.
  • não há usuários anônimos (quando o usuário está em branco)

Isso é apenas um palpite, mas suspeito mysql -u ade conectar-se via localhost porque, quando o protocolo de conexão não é especificado, o padrão é conectar-se através do arquivo de soquete. Pode existir uma entrada mysql.userque permita a conexão localhost anônima.

Execute esta consulta:

SELECT user,host,password FROM mysql.user WHERE user='' AND host='localhost';

Se você voltar uma linha sem senha, isso explica completamente por que mysq -u afunciona.

UPDATE 2012-01-19 11:12 EDT

Craig Efrein levantou uma questão interessante: se existem dois nomes de usuário idênticos na tabela mysql.user, um com senha e outro sem, isso significa que o MySQL nega autenticação quando não está usando uma senha?

Esta pergunta é um excelente alerta sobre a autenticação do usuário MySQL.

Por favor note que a chave primária do mysql.user é host, usuário. Não há outros índices. Isso permite várias ocorrências de um nome de usuário. Cada ocorrência pode ter uma senha diferente ou nenhuma senha. Isso permite que o usuário 'dbuser' efetue login localmente (dbuser @ localhost) usando nenhuma senha e o mesmo login de usuário de outro servidor em um determinado netblock (dbuser@'10.1.2.20 ') com uma senha como' pass1 'e que o usuário efetue login remotamente de qualquer lugar (dbuser @ '%') com uma senha remota como 'pass2'.

Dado o algoritmo de autenticação usado pelo MySQL, não há restrições impostas aos usuários com a presença ou ausência de uma senha.

É por isso que o Guia de Estudo de Certificação do MySQL 5.0 diz no Parágrafo 610 em seus marcadores que mostra como limpar o processo de autenticação:

No Unix, o MySQL vem com um script mysql_secure_installation que pode executar várias operações úteis relacionadas à segurança em sua instalação. O script possui os seguintes recursos:

  • Defina uma senha para as contas raiz
  • Remova todas as contas raiz acessíveis remotamente.
  • Remova as contas de usuário anônimas. Isso melhora a segurança porque evita a possibilidade de alguém se conectar ao servidor MySQL como root a partir de um host remoto. O resultado é que quem deseja se conectar como root deve primeiro fazer logon no host do servidor, o que fornece uma barreira adicional contra ataques.
  • Remova o banco de dados de teste (se você remover as contas anônimas, também poderá remover o banco de dados de teste ao qual elas têm acesso).
RolandoMySQLDBA
fonte
Sim, eu tentei, ele retorna uma linha sem senha. Obrigado por sua excelente explicação e recomendou o livro de certificação MySQL.
Apenas um aluno
2
Rolando, se dois nomes de usuário idênticos existem na tabela mysql.user, um com uma senha e outro sem, isso significa que o MySQL nega autenticação quando não está usando uma senha?
Craig Efrein
@ Craig - Sua pergunta é muito digna de nota. Vou transferi-lo para a minha resposta e abordá-lo lá.
RolandoMySQLDBA 19/01/12
Obrigado pela resposta detalhada, no meu caso eu tinha usuários anônimos configurados de alguma forma.
SoWeLie 4/13
@RolandoMySQLDBA, Todas as informações no guia de estudo de certificação já podem ser encontradas no manual online do MySQL?
Pacerier
5

O curinga do host '%' não corresponde ao 'localhost'. Por padrão, o cliente mysql tentará conectar-se através de um soquete, em vez de tcp (geralmente em algum lugar como /var/lib/mysql/mysql.sock).

Você pode alterar sua concessão para 'a' @ 'localhost' ou forçar o cliente a operar sobre a pilha TCP como:

mysql -u a -p --protocol=TCP
atxdba
fonte
Eu tentei, mas ainda não tive sorte.
Apenas um aluno
Como configurar esta opção my.cnfpara não precisar mais desse parâmetro?
shgnInc
1
Você não Se você não especificar um nome de host -h, ele assumirá "localhost", o que significa que está procurando um soquete, não uma porta TCP sem o sinalizador de protocolo. Você pode configurar um shell aliase se estiver cansado de digitar todos os argumentos.
Atxdba 15/10
2

Você verificou se o MySQL está realmente ouvindo o 3306? Execute um netstat -tlpn e forneça os resultados. Se você não vê 3306, provavelmente não.

No my.cnf, você deve verificar se --skip-networking está comentado

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
language        = /usr/share/mysql/English
bind-address    = 65.55.55.2
# skip-networking
Craig Efrein
fonte
Eu também fiz o mesmo que solicitado na pergunta. e também fez o que você disse na sua resposta, mas ainda existe o mesmo problema.
Abdul Manaf
Você pode fornecer os resultados da seguinte consulta: selecione user, host from mysql.user;
Craig Efrein
Sim, o MySQL está escutando na porta 3306. Veja minha edição.
Apenas um aluno
Você também pode tentar o mysql -u user -p -h 127.0.0.1. Se isso funcionar, acredito no mysql que não sabe resolver o localhost. Uma entrada para localhost que aponta para 127.0.0.1 no seu arquivo / etc / hosts resolverá isso.
Craig Efrein
Você executou privilégios de liberação?
Craig Efrein
1

Como o @atxdba descreveu, Para conectar o daemon mysql a partir do controle remoto que não se conecta via soquete, é necessário se conectar a partir do controle remoto via TCP.

Para isso, você deve especificar o --protocol=TCPpor cada conexão. Embora você possa configurá-lo no my.cnfservidor:

[client]
protocol=tcp
shgnInc
fonte