Ошибка MySQL: доступ запрещен для пользователя 'a' @ 'localhost' (с использованием пароля: ДА)

22

Я использую учетную запись root создал учетную запись 'a'@'%'. Но я не могу использовать эту учетную запись для подключения к серверу MySQL, когда я указываю параметр хоста. Я могу успешно подключиться без -hпараметра. Пожалуйста, смотрите стенограмму ниже. Я надеюсь, что кто-то может помочь мне объяснить это. Спасибо.

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> 

Редактировать:

Да, MySQL прослушивает порт 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 ~]# 
Просто ученик
источник
1
Я не специалист по MySql, но я видел эту проблему несколько раз, я не знаю, в чем причина, решением было явное определение хоста в дополнение к 'a'@'%'. Итак, первая запись была 'a'@'%', а вторая есть 'a'@'localhost'.
ком
Можете ли вы проверить то же самое с более низкой версией MySQL ..?
Абдул Манаф
Для подключения используйте Cpanel Login Details.
Абу Фахим
В моем случае у меня было три анонимных аккаунта, созданных по умолчанию, удаление которых решило бы эту проблему
Хоакин Л. Роблс

Ответы:

26

Вот быстрый и грязный метод для проверки того, как MySQL выполняет успешную аутентификацию.

Пожалуйста, запустите этот запрос:

SELECT USER(),CURRENT_USER();

USER () сообщает, как вы пытались пройти аутентификацию в mysqld

CURRENT_USER () сообщает, как вам разрешили пройти аутентификацию в mysqld

Иногда USER()и CURRENT_USER()бывают разные. Это потому, что аутентификация mysql следует специальному протоколу.

Согласно справочному руководству по сертификации MySQL 5.0

введите описание изображения здесь

на страницах 486,487 говорится об алгоритме аутентификации mysql:

Существует два этапа управления клиентским доступом:

На первом этапе клиент пытается подключиться, и сервер либо принимает, либо отклоняет соединение. Чтобы попытка увенчалась успехом, некоторая запись в пользовательской таблице должна соответствовать хосту, с которого соединяется клиент, имени пользователя и паролю.

На втором этапе (который происходит только в том случае, если клиент уже успешно подключился) сервер проверяет каждый запрос, который он получает от клиента, чтобы увидеть, имеет ли клиент достаточные привилегии для его выполнения.

Сервер сопоставляет клиента с записями в таблицах предоставления на основе хоста, с которого клиент соединяется, и пользователя, которого предоставляет клиент. Однако возможно совпадение нескольких записей:

Значения хоста в таблицах грантов могут быть указаны, поскольку шаблоны содержат подстановочные значения. Если таблица содержит записи гранта от myhost.example.com, %.example.com, %.comи %все они совпадают клиент , который соединяется с myhost.example.com.

Шаблоны не допускаются для значений пользователя в записях таблицы грантов, но имя пользователя может быть задано в виде пустой строки для указания анонимного пользователя. Пустая строка соответствует любому имени пользователя и, таким образом, эффективно действует как подстановочный знак.

Когда значения Host и User в более чем одной записи пользовательской таблицы соответствуют клиенту, сервер должен решить, какой из них использовать. Это делается путем сортировки записей с наиболее конкретными значениями столбца «Хост» и «Пользователь» и выбора соответствующей записи, которая появляется первой в отсортированном списке. Сортировка выполняется следующим образом:

В столбце хоста литеральные значения, такие как localhost, 127.0.0.1и myhost.example.comсортируют перед значениями, в %.example.com которых есть символы шаблона. Значения шаблона сортируются в соответствии с их конкретностью. Например, %.example.comболее конкретно чем %.com, что более конкретно чем %.

В столбце «Пользователь» непустые имена пользователей сортируются перед пустыми именами пользователей. То есть неанонимные пользователи сортируются впереди анонимных пользователей.

Сервер выполняет эту сортировку при запуске. Он считывает таблицы разрешений в память, сортирует их и использует копии в памяти для контроля доступа.

Из этого описания вам не нужно беспокоиться о порядке таблиц mysql.user, поскольку в памяти есть копия таблиц предоставления, которая отсортирована, как упоминалось ранее.

Что касается того, как вы вошли в систему, только mysql -u aработал. Вернитесь и войдите снова и выполните эти команды

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

Убедитесь что

  • У каждого пользователя есть пароль.
  • анонимных пользователей нет (когда пользователь пуст)

Это всего лишь предположение, но я подозреваю, что mysql -u aсоединение через localhost происходит, потому что, если протокол соединения не указан, по умолчанию используется соединение через файл сокета. Может существовать запись mysql.user, разрешающая анонимное локальное соединение.

Запустите этот запрос:

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

Если вы получите строку без пароля, это полностью объясняет, почему mysq -u aработает.

ОБНОВЛЕНИЕ 2012-01-19 11:12 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Крейг Эфрейн поднял интересный вопрос: если в таблице mysql.user существуют два одинаковых имени пользователя, одно с паролем, а другое без него, означает ли это, что MySQL запрещает аутентификацию, когда не используется пароль?

Этот вопрос отлично подходит для аутентификации пользователей MySQL.

Обратите внимание, что первичным ключом mysql.user является host, user. Других индексов нет. Это позволяет несколько раз использовать имя пользователя. В каждом случае может быть свой пароль или пароль отсутствует. Это позволяет пользователю 'dbuser' локально входить в систему (dbuser @ localhost), не используя пароль, и входу того же пользователя с другого сервера в пределах данного сетевого блока (dbuser@'10.1.2.20 ') с паролем, подобным' pass1 ', и тому пользователю для входа в систему. удаленно из любого места (dbuser @ '%') с помощью удаленного пароля, например, «pass2».

Учитывая алгоритм аутентификации, который использует MySQL, нет никаких ограничений, накладываемых на пользователей с наличием или отсутствием пароля.

Вот почему в « Руководстве по изучению сертификации MySQL 5.0» на странице 6 параграфа 6 указывается, как очистить процесс аутентификации:

В Unix MySQL поставляется со скриптом mysql_secure_installation, который может выполнять несколько полезных операций, связанных с безопасностью вашей установки. Скрипт имеет следующие возможности:

  • Установите пароль для корневых учетных записей
  • Удалите все удаленно доступные корневые учетные записи.
  • Удалите учетные записи анонимных пользователей. Это повышает безопасность, поскольку предотвращает возможность любого подключения к серверу MySQL в качестве пользователя root с удаленного хоста. В результате любой, кто хочет подключиться как root, должен сначала войти в систему на хосте сервера, что создает дополнительный барьер против атаки.
  • Удалите тестовую базу данных (при удалении анонимных учетных записей вы также можете удалить тестовую базу данных, к которой они имеют доступ).
RolandoMySQLDBA
источник
Да, я пытался вернуть строку без пароля. Спасибо за ваше превосходное объяснение и рекомендовал книгу сертификации MySQL.
Просто ученик
2
Роландо, если в таблице mysql.user существуют два идентичных имени пользователя, одно с паролем, а другое без него, означает ли это, что MySQL запрещает аутентификацию, когда не используется пароль?
Крейг Эфрейн
@Craig - Ваш вопрос очень заслуживает внимания. Я перенесу это в свой ответ и адресую там.
RolandoMySQLDBA
Спасибо за подробный ответ, в моем случае я настроил анонимных пользователей как-то.
SoWeLie
@RolandoMySQLDBA, можно ли найти всю информацию в руководстве по сертификации уже в онлайн-руководстве по MySQL?
Pacerier
5

Подстановочный знак хоста "%" не соответствует "localhost". По умолчанию клиент mysql будет пытаться подключиться через сокет, а не через tcp (обычно в каком-то месте, например /var/lib/mysql/mysql.sock).

Вы можете либо изменить свой грант на 'a' @ 'localhost', либо заставить клиента работать над стеком TCP, например:

mysql -u a -p --protocol=TCP
atxdba
источник
Я пытался, но все равно не повезло.
Просто ученик
Как настроить эту опцию, my.cnfчтобы больше не нуждаться в этом параметре?
ShgnInc
1
Вы не Если вы не укажете имя хоста -h, оно принимает «localhost», что означает, что он ищет сокет, а не порт TCP без флага протокола. Вы можете настроить псевдоним оболочки, если вы устали набирать все аргументы.
atxdba
2

Вы проверили, чтобы убедиться, что MySQL действительно прослушивает 3306? Запустите netstat -tlpn и предоставьте результаты. Если вы не видите 3306, то, вероятно, нет.

В my.cnf вы должны убедиться, что --skip-network закомментировано

[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
Крейг Эфрейн
источник
Я также сделал то же самое, что и в вопросе. а также сделал то, что вы говорите в своем ответе, но есть еще та же проблема.
Абдул Манаф
Можете ли вы предоставить результаты по следующему запросу: выберите пользователя, хост из mysql.user;
Крейг Эфрейн
Да, MySQL прослушивает порт 3306. См. Мое редактирование.
Просто ученик
Вы также можете попробовать mysql -u user -p -h 127.0.0.1. Если это работает, то я считаю, что это MySQL, который не знает, как разрешить localhost. Запись для localhost, которая указывает на 127.0.0.1 в вашем файле / etc / hosts, разрешит это.
Крейг Эфрейн
Вы запускали Flush Привилегии?
Крейг Эфрейн
1

Как описано в @atxdba, чтобы подключить демон mysql с удаленного компьютера, который не подключен через сокет, вам необходимо подключиться с удаленного компьютера через TCP.

Для этого вы должны указать для --protocol=TCPкаждого соединения. Хотя вы можете установить его my.cnfна сервере:

[client]
protocol=tcp
shgnInc
источник