Помилка MySQL: користувачеві 'a' @ 'localhost' заборонено доступ (використовуючи пароль: ТАК)


22

Я використовую створений кореневий рахунок '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'.
com

Ви можете будь-ласка перевірити те саме з нижньою версією mysql ..?
Абдул Манаф

використовувати з'єднання для входу в Cpanel, щоб підключитися
Абу Фахім

У моєму випадку у мене було створено три анонімні акаунти за замовчуванням, їх видалення вирішило б цю проблему
Хоакін Л. Роблес

Відповіді:


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.

Шаблони для значень Користувача у записах таблиці грантів не дозволені, але ім'я користувача може бути вказано як порожній рядок, щоб вказати анонімного користувача. Порожня рядок відповідає будь-якому імені користувача і, таким чином, ефективно виконує функцію підстановки.

Коли значення хост і користувач у кількох записах таблиці користувачів відповідають клієнту, сервер повинен вирішити, який з них використовувати. Це робиться, сортуючи записи спочатку з найбільш конкретними значеннями стовпців хоста та користувача та вибираючи відповідні записи, що виникають першими у відсортованому списку, сортування відбувається наступним чином:

У стовпці хоста буквальні значення, такі як 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, тому що коли протокол з'єднання не вказаний, за замовчуванням підключається через файл socket. Може існувати запис, mysql.userякий дозволяє анонімне підключення localhost.

Запустіть цей запит:

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

Якщо ви повернете рядок без пароля, це повністю пояснює, чому це mysq -u aпрацює.

ОНОВЛЕННЯ 2012-01-19 11:12 EDT

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

Це питання є чудовим питанням щодо аутентифікації користувачів MySQL.

Зверніть увагу, що основним ключем mysql.user є хост, користувач. Інших показників немає. Це дозволяє декілька зустрічей імені користувача. Кожен випадок може мати інший пароль або без пароля. Це дозволяє користувачеві 'dbuser' здійснювати локальний вхід (dbuser @ localhost), не використовуючи пароля та того самого користувача, що входить з іншого сервера в межах заданого netblock (dbuser@'10.1.2.20 ') з паролем, як' pass1 ', і цей користувач повинен увійти віддалено з будь-якого місця (dbuser @ '%') з віддаленим паролем, наприклад "pass2".

Враховуючи алгоритм аутентифікації, який використовує MySQL, для користувачів немає обмежень щодо наявності або відсутності пароля.

Ось чому в посібнику з вивчення сертифікації MySQL 5.0 йдеться на сторінці 498 у пункті опису про те, як очистити процес аутентифікації:

У Unix MySQL поставляється із сценарієм mysql_secure_installation, який може виконати кілька корисних операцій, пов’язаних із безпекою у вашій установці. Сценарій має такі можливості:

  • Встановіть пароль для кореневих облікових записів
  • Видаліть усі доступні кореневі облікові записи.
  • Видаліть анонімні облікові записи користувачів. Це покращує безпеку, оскільки перешкоджає можливості будь-якого підключення до сервера MySQL як корінь від віддаленого хоста. Результат полягає в тому, що кожен, хто хоче підключитися як root, повинен спочатку мати можливість увійти на хості сервера, що забезпечує додатковий бар'єр проти атаки.
  • Видаліть тестову базу даних (Якщо ви видалите анонімні облікові записи, ви також можете видалити тестову базу даних, до якої вони мають доступ).

Так, я спробував, він повертає рядок без пароля. Дякуємо за відмінне пояснення та рекомендуємо книгу сертифікації 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

Я намагався, але все-таки не пощастило.
Просто учень

Як налаштувати цю опцію в my.cnfтому, що цей параметр більше не потрібен?
shgnInc

1
Ви цього не робите. Якщо ви не вказали ім'я хоста -h, воно передбачає "localhost", тобто він шукає сокет, а не порт TCP без прапора протоколу. Ви можете встановити псевдонім оболонки, якщо вам набридло вводити всі аргументи.
atxdba

2

Ви перевірили, щоб MySQL насправді слухав на 3306? Запустіть netstat -tlpn та надайте результати. Якщо ви не бачите 3306, то, ймовірно, цього немає.

У my.cnf слід переконатися, що --skip-мережа прокоментована

[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 Privileges?
Крейг Ефрейн

1

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

Для цього слід вказати --protocol=TCPкожне з'єднання. Хоча ви можете встановити його my.cnfна сервері:

[client]
protocol=tcp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.