Глава 7. Безопасность

Думая о безопасности в пределах установки MySQL, Вы должны рассмотреть широкий диапазон возможных тем и как они затрагивают безопасность Вашего сервера MySQL и связанные приложения:

7.1. Общие вопросы безопасности

Этот раздел описывает общие вопросы безопасности, чтобы знать, что Вы можете сделать, чтобы сделать Вашу установку MySQL более безопасной от нападения или неправильного употребления. Для информации о системе управления доступом, чтобы настроить учетные записи пользователя и проверить доступ к базе данных см. раздел 2.9.

Для ответов на некоторые вопросы, которые часто спрашивают о вопросах безопасности MySQL Server см. раздел A.9 .

7.1.1. Направляющие линии безопасности

Любой, использующий MySQL на компьютере, соединенном с Интернетом, должен прочитать этот раздел, чтобы избежать наиболее распространенных ошибок безопасности.

В обсуждении безопасности необходимо рассмотреть полностью защиту всего узла сервера (не только сервера MySQL) против всех типов применимых нападений. Мы не покрываем все аспекты доступности и отказоустойчивости.

MySQL использует безопасность, основанную на Access Control Lists (ACL) для всех соединений, запросов и других операций, которые пользователи могут попытаться выполнить. Есть также поддержка SSL-зашифрованных соединений между клиентами и серверами MySQL. Многие из понятий, обсужденных здесь, не являются определенными для MySQL вообще: те же самые общие представления относятся почти ко всем приложениям.

Выполняя MySQL, следуйте за этими направляющими линиями:

7.1.2. Хранение безопасных паролей

Пароли происходят в нескольких контекстах в пределах MySQL. Следующие разделы обеспечивают направляющие линии, которые позволяют конечным пользователям и администраторам сохранить эти пароли. Кроме того, плагин validate_password может использоваться, чтобы провести в жизнь политику по приемлемому паролю. См. раздел 7.5.2.

7.1.2.1. Направляющие линии конечного пользователя для безопасности пароля

Пользователи MySQL должны использовать следующие направляющие линии, чтобы сохранить пароли безопасными.

Когда Вы выполняете программу клиента, чтобы соединиться с сервером MySQL, нецелесообразно определить Ваш пароль способом, который выставляет это открытым другим пользователям. Методы, которые Вы можете использовать, чтобы определить Ваш пароль, когда Вы выполняете программы клиента, перечислены здесь, наряду с оценкой рисков каждого метода. Короче говоря, у самых безопасных методов должна быть подсказка программы клиента для пароля или определение пароля в должным образом защищенном файле опции.

В Unix mysql пишет отчет выполненных запросов в файл истории (см. раздел 5.5.1.3). По умолчанию этот файл называется .mysql_history и создается в Вашем корневом каталоге. Пароли могут быть написаны как простой текст в таких запросах SQL, как CREATE USER и ALTER USER, так что если Вы используете эти запросы, они зарегистрированы в файле истории. Чтобы хранить этот файл, используйте рестриктивный режим доступа, как описано ранее для файла .my.cnf.

Если Ваш интерпретатор команды будет сконфигурирован, чтобы поддержать историю, то любой файл, в котором сохранены команды, будет содержать пароли MySQL из командной строки. Например, bash использует ~/.bash_history. У любого такого файла должен быть рестриктивный режим доступа.

7.1.2.2. Направляющие линии администратора для безопасности пароля

Администраторы базы данных должны использовать следующие направляющие линии, чтобы сохранить пароли безопасными.

MySQL хранит пароли для учетных записей пользователя в таблице mysql.user. Доступ к этой таблице никогда нельзя предоставлять никаким неадминистративным учетным записям.

Пароли учетной записи могут истечь, чтобы пользователи сбросили их. См. разделы 7.3.7 и 7.3.8.

Плагин validate_password может использоваться, чтобы провести в жизнь политику по приемлемому паролю. См. раздел 7.5.2.

Пользователь, у которого есть доступ, чтобы изменить каталог плагинов (значение plugin_dir) файл my.cnf, который определяет местоположение каталога, может заменить плагины и изменить способности, обеспеченные плагинами, включая плагины аутентификации.

Должны быть защищены файлы, такие как файлы системного журнала, в которые могли быть записаны пароли. См. раздел 7.1.2.3.

7.1.2.3. Пароли и журналирование

Пароли могут быть написаны как простой текст в запросах SQL вроде CREATE USER, GRANT, SET PASSWORD и запросах, которые вызывают функцию PASSWORD(). Если такие запросы зарегистрированы сервером MySQL, пароли в них становятся видимыми любому с доступом к журналам.

В MySQL 8.0 журналирование запросов избегает писать пароли открытым текстом для следующих запросов:

CREATE USER ... IDENTIFIED BY ...
ALTER USER ... IDENTIFIED BY ...
GRANT ... IDENTIFIED BY ...
SET PASSWORD ...
SLAVE START ... PASSWORD = ...
CREATE SERVER ... OPTIONS(... PASSWORD ...)
ALTER SERVER ... OPTIONS(... PASSWORD ...)
Пароли в тех запросах переписаны, чтобы не появиться буквально в тексте в общем журнале запросов, медленном журнале запросов и двоичном журнале. Перезапись не относится к другим запросым. В частности, INSERT или UPDATE для mysql.user, которые обращаются к буквальным паролям, зарегистрированы как есть, таким образом, Вы должны избежать таких запросов.

Для общего журнала запроса перезапись пароля может быть подавлена, запуская сервер с опцией --log-raw. Из соображений безопасности эта опция не рекомендуется для производственного использования. В диагностических целях может быть полезно видеть точный текст запросов, как он получен сервером.

Запросы, полученные сервером, могут быть переписаны, если плагин перезаписи запроса установлен. В этом случае опция --log-raw затрагивает регистрацию запроса следующим образом:

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

Перезапись пароля происходит только, когда пароли простого текста ожидаются. Для запросов с синтаксисом, которые ожидают значение хеша пароля, не происходит никакая перезапись. Если пароль простого текста поставляется ошибочно для такого синтаксиса, пароль зарегистрирован как дан без перезаписи. Например, следующий запрос зарегистрирован как показано, потому что значение хеша пароля ожидается:

CREATE USER 'user1'@'localhost' IDENTIFIED BY PASSWORD 'not-so-secret';
Чтобы защитить файлы системного журнала от несанкционированного доступа, определите местонахождение их в каталоге, который ограничивает доступ к серверу администратором базы данных. Если сервер регистрирует в таблицы в базе данных mysql, дайте доступ к тем таблицам только администратору базы данных.

Ведомые устройства репликации хранят пароль для ведущего устройства в основном репозитарии информации, который может быть файлом или таблицей (см. раздел 19.2.4). Гарантируйте, что к репозитарию может получить доступ только администратор базы данных. Альтернатива хранению пароля в файле должна использовать START SLAVE, чтобы определить параметры для того, чтобы соединиться с ведущим устройством.

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

7.1.3. Создание безопасного MySQL

Когда Вы соединяетесь с сервером MySQL, Вы должны использовать пароль. Пароль не передан открытым текстом по соединению. Обработка пароля во время последовательности соединения клиента была обновлена в MySQL 4.1.1, чтобы быть очень безопасной. Если Вы все еще используете пароли стиля pre-4.1.1, алгоритм шифрования не столь же силен, как более новый алгоритм. С некоторым усилием умный хакер может взломать пароль.

Вся другая информация передана как текст, и может быть считана любым, кто в состоянии наблюдать соединение. Если соединение между клиентом и сервером проходит сеть, которой не доверяют, и Вы обеспокоены этим, Вы можете использовать сжатый протокол, чтобы сделать трафик намного более трудным для дешифровки. Вы можете также использовать внутреннюю поддержку SSL MySQL, чтобы сделать соединение еще более безопасным. См. раздел 7.4. Альтернативно, используйте SSH, чтобы получить зашифрованное соединение TCP/IP между сервером MySQL и клиентом. Вы можете найти клиент Open Source SSH на http://www.openssh.org/ и сравнение Open Source и Commercial клиентов SSH на http://en.wikipedia.org/wiki/Comparison_of_SSH_clients.

Чтобы сделать систему MySQL безопасной, Вы должны рассмотреть следующие предложения:

7.1.4. Связанные с безопасностью опции и переменные mysqld

Следующая таблица показывает опции и системные переменные mysqld, которые затрагивают безопасность. Для описаний каждой из них см. разделы 6.1.4 и 6.1.5.

Таблица 7.1. Резюме опций и переменных безопасности

ИмяКомандная строка Файл опцийСистемная? Статусная?Область действия Динамическая?
allow-suspicious-udfsДаДа
automatic_sp_privileges Да ГлобальнаяДа
chroot ДаДа
des-key-fileДаДа
local_infile Да ГлобальнаяДа
old_passwords Да Both Да
safe-user-createДаДа
secure-authДаДа ГлобальнаяДа
- Переменная: secure_auth Да ГлобальнаяДа
secure-file-privДаДа ГлобальнаяНет
- Переменная: secure_file_priv Да ГлобальнаяНет
skip-grant-tablesДаДа
skip-name-resolveДаДа ГлобальнаяНет
- Переменная: skip_name_resolve Да ГлобальнаяНет
skip-networkingДаДа ГлобальнаяНет
- Переменная: skip_networking Да ГлобальнаяНет
skip-show-databaseДаДа ГлобальнаяНет
- Переменная: skip_show_database Да ГлобальнаяНет

7.1.5. Как выполнить MySQL как нормальный пользователь

В Windows Вы можете выполнить сервер как службу Windows, используя нормальную учетную запись пользователя.

В Linux для установок, выполненных, используя репозитарий MySQL или пакеты RPM, mysqld должен быть запущен местным пользователем mysql. Запуск другим пользователем операционной системы не поддержан скриптами init, которые включены как часть репозитариев MySQL.

В Unix (или Linux для установок, выполненных, используя tar.gz), mysqld может быть запущен и выполнен любым пользователем. Однако, Вы должны избежать выполнять сервер как Unix-пользователь root из соображений безопасности. Чтобы запускать mysqld как нормальный непривилегированный пользователь Unix user_name, Вы должны сделать следующее:

  1. Остановите сервер, если он работает (используйте mysqladmin shutdown ).

  2. Измените каталоги базы данных и файлы так, чтобы user_name имел привилегии читать и писать файлы в них (Вы, возможно, должны были бы сделать это как Unix-пользователь root):
    shell> chown -R user_name /path/to/mysql/datadir
    
    Если Вы не сделаете этого, то сервер не будет в состоянии получить доступ к базам данных или таблицам, когда он будет работать как user_name.

    Если каталоги или файлы в пределах каталога данных MySQL это символические ссылки, chown -R не мог бы следовать за символическими ссылками. Вы должны будете следовать за теми ссылками и изменить каталоги и файлы, на которые они указывают.

  3. Запустите сервер как пользователь user_name. Другая альтернатива должна запустить mysqld как Unix root и и использовать опцию --user=user_name. mysqld запускается, затем переключается, чтобы работать как пользователь Unix user_name прежде, чем принять любые соединения.
  4. Чтобы запустить сервер как данного пользователя автоматически в системное время запуска, определите имя пользователя, добавляя опцию user в группу [mysqld] файла /etc/my.cnf или my.cnf в каталоге данных сервера. Например:
    [mysqld]
    user=user_name
    

Если Ваша машина Unix не безопасна, Вы должны назначить пароль на учетную запись MySQL root в таблицах привилегий. Иначе любой пользователь с учетной записью на этой машине может выполнить mysql с --user=root и выполнить любую работу. Хорошая идея назначить пароли на учетные записи MySQL в любом случае, но особенно когда другие учетные записи существуют на узле сервера. См. раздел 2.9.4.

7.1.6. Вопросы безопасности с LOAD DATA LOCAL

LOAD DATA может загрузить файл, который расположен на узле сервера, или это может загрузить файл, который расположен на хосте клиента, когда указано LOCAL.

Есть два потенциальных вопроса безопасности с поддержкой LOCAL для LOAD DATA:

Чтобы урегулировать эти проблемы, LOAD DATA LOCAL работает так:

7.1.7. Направляющие линии безопасности программирования клиента

Приложения с доступом к MySQL не должны доверять никаким данным, вводимым пользователями, которые могут попытаться обмануть Ваш код вводом спецсимволы в Web-формы, URL или безотносительно приложения, которое Вы создали. Убедитесь, что Ваше приложение остается безопасным, если пользователь вводит что-то вроде ; DROP DATABASE mysql;. Это экстремальный пример, но большие утечки безопасности и потеря данных могли бы произойти в результате действий хакеров, использующих подобные методы, если Вы не готовитесь к ним.

Частая ошибка состоит в том, чтобы защитить только строковые значения данных. Не забудьте проверять числовые данные также. Если приложение производит такой запрос, как SELECT * FROM table WHERE ID=234, когда пользователь вводит значение 234, пользователь может ввести значение 234 OR 1=1, чтобы заставить приложение производить запрос SELECT * FROM table WHERE ID=234 OR 1=1 . В результате сервер получает каждую строку в таблице. Это выставляет каждую строку и вызывает чрезмерную загрузку сервера. Самый простой способ защититься от этого типа нападения состоит в том, чтобы использовать единственные кавычки вокруг числовых констант: SELECT * FROM table WHERE ID='234'. Если пользователь вводит дополнительную информацию, все это становится частью строки. В числовом контексте MySQL автоматически преобразовывает эту строку в число и откусывает любые нечисловые символы от нее.

Иногда люди думают, что, если база данных содержит только публично доступные данные, она не должна быть защищена. Это является неправильным. Даже если допустимо вывести на экран какую-либо строку в базе данных, Вы должны все еще защититься от атак denial of service (например, те, которые основаны на методе в предыдущем параграфе, который заставляет сервер тратить впустую ресурсы). Иначе Ваш сервер становится безразличным к законным пользователям.

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

У других программных интерфейсов могли бы быть подобные способности.

7.2. Система привилегий доступа MySQL

Первичная функция системы привилегии MySQL должна подтвердить подлинность пользователя, который соединяется от данного узла и связать этого пользователя с такими привилегиями на базе данных, как SELECT, INSERT, UPDATE и DELETE. Дополнительная функциональность включает способность иметь анонимных пользователей и предоставить привилегии для MySQL-определенных функций типа LOAD DATA INFILE и административной деятельности.

Есть некоторые вещи, которые Вы не можете сделать с системой привилегии MySQL:

Пользовательский интерфейс к системе привилегии MySQL состоит из запросов SQL CREATE USER, GRANT и REVOKE. См. раздел 14.7.1.

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

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

MySQL рассматривает Ваше имя хоста и имя пользователя в идентификации, потому что нет никакой причины предположить, что данное имя пользователя принадлежит тому же самому человеку на всех узлах. Например, пользователь joe с office.example.com не должен быть тем же самым человеком, как пользователь joe с home.example.com. MySQL обрабатывает это, позволяя Вам отличить пользователей на различных узлах, у которых есть то же самое имя: Вы можете предоставить один набор привилегий для соединений joe с office.example.com и другой для joe с home.example.com. Для просмотра привилегий учетной записи используйте SHOW GRANTS. Например:

SHOW GRANTS FOR 'joe'@'office.example.com';
SHOW GRANTS FOR 'joe'@'home.example.com';
Управление доступом MySQL вовлекает два этапа, когда Вы выполняете программу клиента, которая соединяется с сервером:

Шаг 1: сервер принимает или отклоняет соединение, основываясь на Вашей личности и том, может ли проверить Вашу личность, поставляя правильный пароль.

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

См. разделы 7.2.5 и 7.2.6.

Если Ваши привилегии изменены в то время, как Вы соединены, те изменения не обязательно немедленно вступают в силу для следующего запроса. Для деталей об условиях, при которых сервер перезагружает таблицы привилегий, см. раздел 7.2.7.

7.2.1. Привилегии, обеспеченные MySQL

MySQL обеспечивает привилегии, которые применяются в различных контекстах и на разных уровнях работы:

Информация о привилегиях учетной записи хранится в таблицах user, db, tables_priv, columns_priv и procs_priv базы данных mysql (см. раздел 7.2.2). Сервер MySQL читает содержание этих таблиц в память, когда это запускается и перезагружает их при обстоятельствах, рассмотренных в разделе 7.2.7. Решения контроля доступа основаны на копиях в памяти таблиц привилегий.

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

Следующая таблица показывает имена привилегий, используемые на уровне SQL в GRANT и REVOKE, наряду с именем столбца, связанным с каждой привилегией в таблицах и контекстом, в котором применяется привилегия.

Таблица 7.2. Допустимые привилегии для GRANT и REVOKE

ПривилегияСтолбец Контекст
CREATE Create_priv Базы данных, таблицы или индексы
DROP Drop_priv Базы данных, таблицы или представления
GRANT OPTIONGrant_priv Базы данных, таблицы или подпрограммы
LOCK TABLESLock_tables_priv Базы данных
REFERENCES References_priv Базы данных или таблицы
EVENT Event_privБазы данных
ALTER Alter_privТаблицы
DELETE Delete_privТаблицы
INDEX Index_privТаблицы
INSERT Insert_privТаблицы или столбцы
SELECT Select_privТаблицы или столбцы
UPDATE Update_privТаблицы или столбцы
CREATE TEMPORARY TABLESCreate_tmp_table_priv Таблицы
TRIGGER Trigger_privТаблицы
CREATE VIEWCreate_view_privПредставления
SHOW VIEW Show_view_privПредставления
ALTER ROUTINEAlter_routine_priv Подпрограммы
CREATE ROUTINECreate_routine_priv Подпрограммы
EXECUTE Execute_privПодпрограммы
FILE File_privДоступ к файлам на сервере
CREATE TABLESPACECreate_tablespace_priv Администрирование
CREATE USERCreate_user_priv Администрирование
CREATE ROLECreate_role_priv Администрирование
DROP ROLE Drop_role_priv Администрирование
PROCESS Process_privАдминистрирование
PROXY См. proxies_priv table Администрирование
RELOAD Reload_privАдминистрирование
REPLICATION CLIENTRepl_client_priv Администрирование
REPLICATION SLAVERepl_slave_priv Администрирование
SHOW DATABASESShow_db_priv Администрирование
SHUTDOWN Shutdown_priv Администрирование
SUPER Super_privАдминистрирование
ALL [PRIVILEGES] Администрирование
USAGE Администрирование

Следующий список обеспечивает общее описание каждой привилегии, доступной в MySQL. У особых запросов SQL могут быть более определенные требования привилегии, чем обозначено здесь. Если так, описание для рассматриваемого запроса обеспечивает детали.

Хорошая идея предоставить учетной записи только те привилегии, в которых это нуждается. Вы должны осуществить особое предостережение в предоставлении FILE и административных привилегий:

7.2.2. Таблицы прав доступа

Системная база данных mysql включает несколько таблиц, которые содержат информацию об учетных записях пользователя и их привилегиях. Этот раздел описывает те таблицы. Для информации о других таблицах в системной базе данных см. раздел 6.3 .

Обычно, чтобы управлять содержанием таблиц, Вы изменяете их косвенно при использовании запросов вроде CREATE USER, GRANT и REVOKE, чтобы настраивать учетные записи и управлять привилегиями, доступными каждому. См. раздел 14.7.1. Обсуждение здесь описывает глубинную структуру таблиц, и как сервер использует их содержание, взаимодействуя с клиентами.

Прямая модификация таблиц, используя запросы INSERT, UPDATE или DELETE делается на Ваш собственный риск. Сервер свободен проигнорировать строки, которые становятся ошибочными в результате таких модификаций.

Таблицы базы данных mysql содержат информацию о правах:

В MySQL 8.0 таблицы привилегий используют механизм хранения InnoDB и являются транзакционными. До MySQL 8.0 эти таблицы использовали MyISAM и были нетранзакционными.

Каждая таблица привилегий содержит столбцы контекста и столбцы привилегии:

Сервер использует таблицы привилегий в следующей манере:

Сервер использует таблицы user и db в базе данных mysql на первых и на вторых этапах управления доступом (см. раздел 7.2). Столбцы в таблицах user и db показывают здесь.

Таблица 7.3. Столбцы таблиц user и db

Имя таблицыuser db
Столбцы контекста HostHost
User Db
Столбцы привилегии Select_privSelect_priv
Insert_priv Insert_priv
Update_priv Update_priv
Delete_priv Delete_priv
Index_priv Index_priv
Alter_priv Alter_priv
Create_priv Create_priv
Drop_priv Drop_priv
Grant_priv Grant_priv
Create_view_priv Create_view_priv
Show_view_priv Show_view_priv
Create_routine_priv Create_routine_priv
Alter_routine_priv Alter_routine_priv
Execute_priv Execute_priv
Trigger_priv Trigger_priv
Event_priv Event_priv
Create_tmp_table_priv Create_tmp_table_priv
Lock_tables_priv Lock_tables_priv
References_priv References_priv
Reload_priv
Shutdown_priv
Process_priv
File_priv
Show_db_priv
Super_priv
Repl_slave_priv
Repl_client_priv
Create_user_priv
Create_tablespace_priv
Security columns ssl_type
ssl_cipher
x509_issuer
x509_subject
plugin
authentication_string
password_expired
password_last_changed
password_lifetime
account_locked
Столбцы управления ресурсом max_questions
max_updates
max_connections
max_user_connections

Столбцы plugin и authentication_string таблицы user хранят плагин аутентификации и информацию о мандате.

Сервер использует плагин, названный в столбце plugin строки учетной записи, чтобы подтвердить подлинность попыток соединения для учетной записи.

Столбец plugin должен быть непустым. При запуске и во время выполнения, когда FLUSH PRIVILEGES выполнен, сервер проверяет строки таблицы user. Для любой строки с пустым столбцом plugin сервер пишет предупреждение этой формы в журнал ошибок:

[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with
this user anymore.
Столбец password_expired разрешает DBA истекать пароли учетной записи и требовать, чтобы пользователи сбросили свой пароль. Значение по умолчанию password_expired 'N', но может быть установлено в 'Y' с ALTER USER. После того, как пароль учетной записи истек, все операции, выполненные учетной записью в последующих соединениях приводят к ошибке, пока пользователь не выполнит ALTER USER , чтобы установить новый пароль учетной записи.

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

password_last_changed это TIMESTAMP указывающий, когда пароль был последний раз изменен. Значение не-NULL только для учетных записей, которые используют встроенные методы аутентификации MySQL (учетные записи, которые используют плагин аутентификации mysql_native_password или sha256_password). Значение NULL для других учетных записей, таких как заверенное использование внешней системы аутентификации.

password_last_changed обновляется CREATE USER, ALTER USER и SET PASSWORD и GRANT, которые создают учетную запись или изменяют пароль учетной записи.

password_lifetime указывает время жизни пароля учетной записи в днях. Если пароль проходит это время (оцененное использованием столбца password_last_changed), сервер полагает, что пароль истек, когда клиенты соединяются с использование учетной записи. Значение N больше нуля указывает, что пароль должен быть изменен каждые N дней. Значение 0 отключает автоматическое истечение пароля. Если значение NULL (значение по умолчанию), глобальная политика истечения применяется, как определено переменной default_password_lifetime.

account_locked указывает, заблокирована ли учетная запись (см. раздел 7.3.11).

Во время второго этапа управления доступом сервер выполняет проверку запроса, чтобы гарантировать, что у каждого клиента есть достаточные привилегии для каждого запроса. В дополнение к таблицам user и db, сервер может также консультироваться с таблицами tables_priv и columns_priv для запросов, которые вовлекают таблицы. Последние таблицы обеспечивают более точное управление привилегией на уровнях столбца и таблице. Их столбцы показаны в следующей таблице.

Таблица 7.4. Столбцы tables_priv и columns_priv

Имя таблицы tables_privcolumns_priv
Контекст столбца HostHost
DbDb
UserUser
Table_name Table_name
Column_name
Столбцы привилегий Table_privColumn_priv
Column_priv
Прочие столбцы TimestampTimestamp
Grantor

Столбцы Timestamp и Grantor установлены в текущий timestamp и значение CURRENT_USER, соответственно, но иначе не использованы.

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

Таблица 7.5. Столбцы таблицы procs_priv

Имя таблицы procs_priv
Контекст столбца Host
Db
User
Routine_name
Routine_type
Столбцы привилегий Proc_priv
Прочие столбцы Timestamp
Grantor

Столбец Routine_type имеет тип ENUM со значениями 'FUNCTION' или 'PROCEDURE', чтобы указать на тип подпрограммы. Этот столбец позволяет привилегиям быть предоставленными отдельно для функции и процедуры с тем же самым именем.

Timestamp и Grantor не используются.

Таблица proxies_priv делает запись информации об учетных записях по доверенности. У нее есть эти столбцы:

Для учетной записи, чтобы быть в состоянии предоставить привилегию PROXY другим учетным записям, она должна иметь строку в таблице proxies_priv с With_grant = 1, Proxied_host и Proxied_user установленные, чтобы указать на учетную запись, которой можно предоставить привилегию. Например, учетная запись 'root'@'localhost' создаваемая во время установки MySQL, имеет строку в proxies_priv , которая позволяет предоставить привилегию PROXY для ''@'', то есть, для всех пользователей и всех узлов. Это разрешает root настраивать пользователей по доверенности, так же как делегировать другим учетным записям полномочия настроить пользователей по доверенности. См. раздел 7.3.10.

Столбцы контекста в таблицах привилегий содержат строки. Значение по умолчанию для каждой пустая строка. Следующая таблица показывает число символов, разрешенных в каждом столбце.

Таблица 7.6. Табличные длины столбца контекста привилегий

Имя столбца Максимально разрешенная длина
Host, Proxied_host 60
User, Proxied_user 32
Db64
Table_name64
Column_name64
Routine_name64

В проверяющих доступ целях, сравнения User, Proxied_user, authentication_string, Db и Table_name являются чувствительными к регистру. Сравнения Host, Proxied_host, Column_name и Routine_name не являются чувствительными к регистру.

Таблицы user и db приводят каждую привилегию в отдельном столбце, который объявлен как ENUM('N','Y') DEFAULT 'N'. Другими словами, каждая привилегия может быть отключена или включена с отключенным значением по умолчанию.

Таблицы tables_priv, columns_priv и procs_priv объявляют столбцы привилегии как SET. Значения в этих столбцах могут содержать любую комбинацию привилегий, которыми управляет таблица. Только привилегии, перечисленные в значении столбца, включены.

Таблица 7.7. Значения столбцов привилегии

Имя таблицыИмя столбца Возможные элементы набора
tables_priv Table_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger'
tables_priv Column_priv 'Select', 'Insert', 'Update', 'References'
columns_priv Column_priv 'Select', 'Insert', 'Update', 'References'
procs_priv Proc_priv'Execute', 'Alter Routine', 'Grant'

Только таблица user определяет административные привилегии, например, RELOAD и SHUTDOWN. Административные задачи это операции на сервере непосредственно и не являются определенными для базы данных, таким образом нет никакой причины перечислить эти привилегии в других таблицах привилегий. Следовательно, сервер должны консультироваться только с user, чтобы определить, может ли пользователь выполнить административную задачу.

FILE также определена только в user. Это не административная привилегия как таковая, а способность пользователя читать или писать файлы на узле сервера независимо от доступной базы данных.

Сервер читает содержание таблиц привилегий в память, когда запускается. Вы можете сказать ему перезагружать таблицы, скомандовав FLUSH PRIVILEGES, mysqladmin flush-privileges или mysqladmin reload . Изменения таблиц привилегий вступают в силу как обозначено в разделе 7.2.7.

Когда Вы изменяете учетную запись, хорошая идея проверить, что Ваши изменения имеют намеченный эффект. Чтобы проверить привилегии, используйте SHOW GRANTS. Например, чтобы определить привилегии, которые предоставляют учетной записи с именем пользователя и хоста bob и pc84.example.com:

SHOW GRANTS FOR 'bob'@'pc84.example.com';
Чтобы вывести на экран свойства учетной записи, надо использовать SHOW CREATE USER:
SHOW CREATE USER 'bob'@'pc84.example.com';

7.2.3. Определение имени учетной записи

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

Ролевые имена MySQL подобны именам учетной записи, с некоторыми различиями, описанными в разделе 7.2.4.

В SQL-запросах вроде CREATE USER, GRANT и SET PASSWORD, имена учетной записи следуют этим правилам:

MySQL хранит имя учетной записи в таблицах привилегий в системной базе данных mysql, используя отдельные столбцы для частей имени пользователя и имени хоста:

См. раздел 7.2.2.

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

Часть имени пользователя имени учетной записи это непустое значение, которое буквально соответствует имени пользователя для поступающих попыток соединения, или пустое значение (пустая строка), которая соответствует любому имени пользователя. Учетная запись с пустым именем пользователя это анонимный пользователь. Чтобы определить анонимного пользователя в запросах SQL, используйте заключенную в кавычки пустую часть имени пользователя, например, ''@'localhost'.

Часть имени хоста имени учетной записи может принять много форм, и подстановочные знаки разрешены:

Сервер выполняет соответствие значений узла именам учетной записи против хоста клиента, используя значение, возвращенное DNS для имени хоста клиента или IP-адреса. Кроме случая, когда значение узла учетной записи определено, используя нотацию сетевой маски, сервер выполняет это сравнение как строковое соответствие, даже для значения узла учетной записи, данного как IP-адрес. Это означает, что Вы должны определить значения узла учетной записи в том же самом формате, используемом DNS.

Чтобы избежать проблем, желательно проверить формат, в котором Ваш DNS возвращает имена хоста и адреса. Используйте значения в том же самом формате на именах учетной записи MySQL.

7.2.4. Определение ролевых имен

Ролевые имена MySQL обращаются к ролям, которые называют наборами привилегий. Для ролевых примеров использования см. раздел 7.3.4.

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

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

SET ROLE 'myrole'@'%';
Вместо этого запрос устанавливает сеанс для роли с именем 'myrole'@'%' (или 'myrole' без части узла, которая эквивалентна).

Поэтому ролевые имена часто определяются, используя только часть имени пользователя и позволяя части имени хоста неявно быть %. Определение роли с частью не-% может быть полезно, если Вы намереваетесь создать имя, которое работает ролью и учетной записью пользователя, которой разрешают соединиться от данного узла.

7.2.5. Управление доступом, этап 1: проверка соединения

Когда Вы пытаетесь соединиться с сервером MySQL, сервер принимает или отклоняет соединение, основанное на этих условиях:

Сервер проверяет параметры сначала, затем читает состояние блокировки. Отказ для любого шага заставляет сервер лишить Вас доступа полностью. Иначе сервер принимает соединение, затем вводит этап 2 и ждет запросов.

Мандатная проверка выполнена, используя три столбца контекста таблицы user (Host, User и authentication_string). Статус блокировки зарегистрирован в столбце account_locked таблицы user. Сервер принимает соединение только, если Host и User в user соответствуют имени хоста клиента и пользователя, клиент поставляет пароль, определенный в той строке, и account_locked = 'N'. Правила для допустимых значений Host и User даны в разделе 7.2.3. Блокировка учетной записи может быть изменена с помощью ALTER USER.

Ваша личность основана на двух сведениях:

Если значение столбца User не пробел, имя пользователя в поступающем соединении должно соответствовать точно. Если значение столбца User пробел, оно соответствует любому имени пользователя. Если строка таблицы user, которая соответствует поступающему соединению, есть пустое имя пользователя, пользователь является анонимным пользователем без имени, а не пользователем с именем, которое фактически определил клиент. Это означает, что пустое имя пользователя используется для всей дальнейшей проверки доступа (то есть, во время этапа 2).

Столбец authentication_string может быть пробелом. Это не подстановочный знак и не означает, что любой пароль соответствует. Это означает, что пользователь должен соединиться, не определяя пароль. Если сервер подтверждает подлинность клиента, использующего плагин, метод аутентификации, который реализует плагин, возможно, не использует пароль в authentication_string. В этом случае возможно, что внешний пароль также используется, чтобы подтвердить подлинность.

Не пустое значение authentication_string в таблице user представляет зашифрованные пароли. MySQL не хранит пароли в форме открытого текста. Скорее пароль, поставляемый пользователем, который пытается соединиться, зашифрован (с использованием метода хеширующего пароля, осуществленного плагином аутентификации учетной записи). Зашифрованный пароль используется во время процесса соединения, проверяя, правилен ли пароль. Это делается без передачи зашифрованного пароля по соединению. См. раздел 7.3.1.

С точки зрения MySQL зашифрованный пароль это и есть настоящий пароль, таким образом, Вы никогда не должны предоставлять никому доступ к этому. В частности, не предоставляйте неадминистративный пользовательский доступ чтения к таблицам в базе данных mysql.

Следующая таблица показывает как различные комбинации значений User и Host в таблице user относятся к поступающим соединениям.

Значение User Значение Host Допустимые соединения
'fred' 'thomas.loc.gov'fred с thomas.loc.gov
'''thomas.loc.gov' Кто угодно с thomas.loc.gov
'fred''%' fred откуда угодно
'''%' Кто угодно откуда угодно
'fred''%.loc.gov' fred откуда угодно в домене loc.gov
'fred''x.y.%' fred с x.y.net, x.y.com, x.y.edu и т.д.
'fred' '192.168.10.177' fred с IP 192.168.10.177
'fred' '192.168.10.%' fred из сети 192.168.10 класса C
'fred' '192.168.10.0/255.255.255.0' fred из сети 192.168.10 класса C

Для имени хоста клиента и имени пользователя поступающего соединения возможно соответствовать больше, чем одной строке в user. Предыдущий набор примеров демонстрирует это: несколько записей соответствуют соединению от fred с thomas.loc.gov.

Когда многократные соответствия возможны, сервер должен определить, которое из них использовать. Это решает этот вопрос следующим образом:

Строки с наиболее определенным Host будут первыми. Буквальные имена хоста и IP-адреса являются самыми определенными. Специфика буквального IP-адреса не затронута тем, есть ли сетевая маска, таким образом, 192.168.1.13 и 192.168.1.0/255.255.255.0 считаются одинаково определенными. Образец '%' значит любой host и является наименее определенным. Пустая строка '' тоже значит любой host, но сортируется после '%'. Строки с тем же самым Host упорядочены с наиболее определенным User сначала (пустой User значит любой user и является наименее определенным). Для строк с одинаково определенными Host и User порядок не определен.

Чтобы видеть, как это работает, предположите что таблица user похожа на это:

+-----------+---------+-
| Host      | User    | ...
+-----------+---------+-
| %         | root    | ...
| %         | jeffrey | ...
| localhost | root    | ...
| localhost |         | ...
+-----------+---------+-
Когда сервер читает таблицу в память, это сортирует строки, используя описанные правила. Результат после сортировки похож на это:
+-----------+---------+-
| Host      | User    | ...
+-----------+---------+-
| localhost | root    | ...
| localhost |         | ...
| %         | jeffrey | ...
| %         | root    | ...
+-----------+---------+-

Когда клиент пытается соединиться, сервер просматривает сортированные строки и использует первое найденное соответствие. Для соединения с localhost как jeffrey две строки из таблицы соответствуют: одна с Host и User 'localhost' и '', вторая со значениями '%' и 'jeffrey'. Строка 'localhost' первая в сортированном порядке, так что она будет использована.

Вот другой пример. Предположите, что таблица user похожа на это:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-
Сортированная таблица похожа на это:
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-
Соединение jeffrey от thomas.loc.gov является соответствующим первой строке, тогда как соединение jeffrey от любого узла является соответствующим второй.

Распространенное заблуждение думать, что для данного имени пользователя все строки, которые явно называют того пользователя, используются сначала, когда сервер пытается определить, стоит ли с ним работать. Это не истина. Предыдущий пример иллюстрирует, что соединение jeffrey от thomas.loc.gov является сначала соответствующим не строке, содержащей 'jeffrey' как столбец User, а строке без имени пользователя. В результате jeffrey опознан как анонимный пользователь, даже при том, что он определил имя пользователя, соединяясь.

Если Вы в состоянии соединиться с сервером, но Ваши привилегии не состоят в том, что Вы ожидаете, Вы, вероятно, опознаетесь как некоторая другая учетная запись. Узнать, что считает сервер, можно, используя функцию CURRENT_USER(), см. раздел 13.14. Это возвращает значение в формате user_name@ host_name, который указывает значения User и Host от соответствия строки в таблице user. Предположите, что jeffrey соединяется и запускает следующий запрос:

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+
Результат, показанный здесь, указывает что соответствием user у строки таблицы был пробел в столбце User. Другими словами, сервер обрабатывает jeffrey как анонимного пользователя.

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

7.2.6. Управление доступом, этап 2: проверка запроса

После того, как Вы устанавливаете соединение, сервер вводит этап 2 управления доступом. Для каждого запроса сервер определяет, какую работу Вы хотите выполнить, затем проверяет, есть ли у Вас достаточные привилегии, чтобы это сделать. Здесь столбцы привилегии в таблицах привилегий играют роль. Эти привилегии могут прибыть из любой из таблиц user, db, tables_priv, columns_priv или procs_priv. Вы можете счесть полезным обратиться к разделу 7.2.2, который перечисляет столбцы, существующие в каждой из таблиц привилегий.

Таблица user предоставляет привилегии, которые назначены Вам на глобальной основе и которые применяются независимо от того, какова база данных по умолчанию. Например, если таблица user предоставляет Вам привилегию DELETE, Вы можете удалить строки из любой таблицы в любой базе данных на сервере! Мудро предоставить привилегии в user только людям, которые нуждаются в них, такие как администраторы базы данных. Для других пользователей Вы должны оставить все привилегии внутри user в виде 'N' и давать привилегии только на более определенных уровнях. Вы можете предоставить привилегии для особых баз данных, таблиц, столбцов или подпрограмм.

Таблица db предоставляет определенные для базы данных привилегии. Значения в столбцах контекста этой таблицы могут принять следующие формы:

Сервер читает таблицу db в память и сортирует в то же самое время, когда это читает user. Сервер сортирует таблицу db, основанную на столбцах контекста Host, Db и User. Как с user, сортировка помещает наиболее определенные значения сначала и наименее определенные значения в конец, и когда сервер ищет соответствие строк, это использует первое соответствие, которое находит.

Таблицы tables_priv, columns_priv и procs_priv предоставляют привилегии определенные для таблицы, определенные для столбца и определенные для подпрограммы привилегии. Значения в столбцах контекста этих таблиц могут принять следующие формы:

Сервер сортирует tables_priv, columns_priv и procs_priv, исходя из столбцов Host, Db и User. Это подобно сортировке db, но более просто, потому что только Host может содержать подстановочные знаки.

Сервер использует сортированные таблицы, чтобы проверить каждый запрос. Для запросов, которые требуют административных привилегий, например, SHUTDOWN или RELOAD, сервер проверяет только строки таблицы user, потому что это единственная таблица, которая определяет административные привилегии. Сервер предоставляет доступ, если строка разрешает требуемую работу. Например, если Вы хотите выполнить mysqladmin shutdown, но Ваша строка таблицы user не позволяет SHUTDOWN, сервер лишает доступа, даже не проверяя таблицу db. Это не содержит Shutdown_priv, таким образом нет никакой потребности это сделать.

Для связанных с базой данных запросов (INSERT, UPDATE и т.д.), сервер сначала проверяет глобальные привилегии пользователя, просматривая user. Если строка разрешает требуемую работу, доступ предоставляют. Если глобальные привилегии в user недостаточны, сервер определяет определенные для базы данных привилегии пользователя, проверяя db:

Сервер смотрит таблицу db для соответствия Host, Db и User. Host и User являются соответствующими имени хоста соединяющегося пользователя и имени пользователя MySQL. Db является соответствующим базе данных, к которой пользователь хочет получить доступ. Если нет никакой строки для Host и User, доступ запрещен.

После определения определенных для базы данных привилегий, предоставленных db, сервер добавляет их к глобальным привилегиям, предоставленным таблицей user. Если результат разрешает требуемую работу, доступ предоставляют. Иначе сервер последовательно проверяет столбцы привилегий в таблицах tables_priv и columns_priv к привилегиям пользователя и разрешает доступ, основываясь на результате. Для сохраненной подпрограммы сервер использует таблицу procs_priv вместо tables_priv и columns_priv.

Выраженное в логических членах, предыдущее описание того, как привилегии пользователя вычислены, может быть получено так:

global privileges OR (database privileges AND host privileges) OR
       table privileges OR column privileges OR routine privileges
Это, возможно, не очевидно, если глобальные привилегии user, как первоначально находят, недостаточны для требуемой работы, сервер добавляет те привилегии к привилегиям базы данных, таблицы и столбца позже. Причина состоит в том, что запрос мог бы потребовать больше, чем одного типа привилегии. Например, если Вы выполняете INSERT INTO ... SELECT, нужны привилегии INSERT и SELECT. Ваши привилегии могли бы быть таковы, что user предоставляет одну привилегию, а db другую. В этом случае у Вас есть необходимые привилегии, чтобы выполнить запрос, но сервер не может сказать это для любой таблицы отдельно, привилегии, предоставленные строками в обеих таблицах, должны быть объединены.

7.2.7. Когда изменения привилегии вступают в силу

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

Если Вы изменяете таблицы привилегий косвенно, используя GRANT, REVOKE, SET PASSWORD или RENAME USER, сервер замечает эти изменения и загружает таблицы привилегий в память снова немедленно.

Если Вы изменяете таблицы привилегий непосредственно, используя INSERT, UPDATE или DELETE, Ваши изменения не имеют никакого эффекта на привилегию до перезапуска сервера или перезагрузки таблиц. Если Вы изменяете таблицы привилегий непосредственно, но забываете перезагружать их, Ваши изменения не имеют эффекта, пока Вы не перезапускаете сервер.

Чтобы сказать серверу перезагружать таблицы привилегий, выполните flush-privileges. Это делается командой FLUSH PRIVILEGES, mysqladmin flush-privileges или mysqladmin reload.

Табличная перезагрузка привилегий затрагивает привилегии для каждого существующего соединения клиента следующим образом:

Если сервер запущен с опцией --skip-grant-tables, это не читает таблицы привилегий или осуществляет любое управление доступом. Любой может соединиться и сделать что-либо. Чтобы сервер восставновил работу системы доступа, сбросьте привилегии.

7.2.8. Поиск неисправностей и проблем соединений с MySQL

Если Вы сталкиваетесь с проблемами, когда Вы пытаетесь соединиться с сервером MySQL, следующие элементы описывают некоторые планы действий, которые Вы можете использовать, чтобы исправить проблему.

7.3. Управление учетной записью пользователя MySQL

Этот раздел описывает, как настроить учетные записи клиентов Вашего сервера MySQL. Это обсуждает следующие темы:

См. раздел 14.7.1.

7.3.1. Имена пользователя и пароли

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

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

Есть несколько различий между способом, которым имена пользователя и пароли используются MySQL и Вашей операционной системой:

Процесс установки MySQL заполняет таблицы привилегий с начальной записью root, см. раздел 2.9.4, который также обсуждает, как назначить пароли. После этого Вы обычно настраиваете, изменяете и удаляете учетные записи MySQL, используя запросы CREATE USER, DROP USER, GRANT и REVOKE. См. раздел 14.7.1.

Чтобы соединиться с сервером MySQL с клиентом командной строки, определите имя пользователя и опции пароля по мере необходимости для учетной записи, которую Вы хотите использовать:

shell> mysql --user=monty --password db_name
Если Вы предпочитаете короткие опции, команда похожа на это:
shell> mysql -u monty -p db_name
Если Вы опускаете значение пароля после опции --password или -p (как показано), клиент запрашивает его. Альтернативно, пароль может быть определен в командной строке:
shell> mysql --user=monty --password=password db_name
shell> mysql -u monty -ppassword db_name
Если Вы используете опцию -p, не должно быть никакого пробела между -p и следующим значением пароля.

Определение пароля в командной строке нужно считать опасным. См. раздел 7.1.2.1. Вы можете использовать файл опции или файл входа в систему, чтобы избежать задавать пароль в командной строке. См. разделы 5.2.6 и 5.6.7.

См. раздел 5.2.2.

7.3.2. Добавление учетных записей пользователя

Вы можете создать учетные записи MySQL двумя путями:

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

Другая опция для того, чтобы создать учетные записи должна использовать инструмент GUI MySQL Workbench. Кроме того, несколько имеющих отношение к третьей стороне программ предлагают управление учетными записями MySQL. В частности, это phpMyAdmin.

Следующие примеры показывают, как использовать mysql, чтобы настроить новые учетные записи. Эти примеры предполагают, что привилегии были настроены согласно значениям по умолчанию, описанным в разделе 2.9.4. Это означает, что, чтобы произвести изменения, Вы должны соединиться с сервером MySQL как пользователь MySQL root, который имеет доступ CREATE USER.

Используйте mysql , чтобы соединиться с сервером:

shell> mysql --user=root mysql
Если Вы назначили пароль на root, Вы должны также указать опцию --password или -p.

После соединения с сервером как root, Вы можете добавить новые учетные записи. Следующий пример использует CREATE USER и GRANT:

mysql> CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
    ->       WITH GRANT OPTION;
mysql> CREATE USER 'monty'@'%' IDENTIFIED BY 'some_pass';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
    ->       WITH GRANT OPTION;
mysql> CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin_pass';
mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
mysql> CREATE USER 'dummy'@'localhost';
У учетных записей, создаваемых этими запросами, есть следующие свойства:

Чтобы видеть привилегии для учетной записи, надо использовать SHOW GRANTS:

mysql> SHOW GRANTS FOR 'admin'@'localhost';
+-----------------------------------------------------+
| Grants for admin@localhost                          |
+-----------------------------------------------------+
| GRANT RELOAD, PROCESS ON *.* TO 'admin'@'localhost' |
+-----------------------------------------------------+
Чтобы видеть свойства не привилегии для учетной записи, надо использовать SHOW CREATE USER:
mysql> SHOW CREATE USER 'admin'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for admin@localhost: CREATE USER 'admin'@'localhost'
       IDENTIFIED WITH 'mysql_native_password'
       AS '*67ACDEBDAB923990001F0FFB017EB8ED41861105'
       REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
Следующие примеры создают три учетных записи и предоставляют им доступ к определенным базам данных. У каждой из них есть имя пользователя custom и пароль obscure:
mysql> CREATE USER 'custom'@'localhost' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->       ON bankaccount.* TO 'custom'@'localhost';
mysql> CREATE USER 'custom'@'host47.example.com' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->       ON expenses.* TO 'custom'@'host47.example.com';
mysql> CREATE USER 'custom'@'%.example.com' IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->       ON customer.* TO 'custom'@'%.example.com';
Три учетных записи могут использоваться следующим образом:

7.3.3. Удаление учетных записей пользователя

Чтобы удалить учетную запись, используйте DROP USER, который описан в разделе 14.7.1.5. Например:

mysql> DROP USER 'jeffrey'@'localhost';

7.3.4. Используя роли

В MySQL роль это названный набор привилегий. Как учетным записям пользователя, ролям можно предоставить привилегии.

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

Чтобы управлять ролями, используйте запросы CREATE ROLE, DROP ROLE, GRANT и REVOKE ROLE. Следующее обсуждение обеспечивает примеры ролевого использования. Для описаний отдельных запросов ролевой манипуляции см. раздел 14.7.1.

Предположите, что приложение использует базу данных app_db. Могут быть учетные записи пользователя разработчиков, которые создают и поддерживают приложение, и пользователей, которые взаимодействуют с ним. Разработчики нуждаются в полном доступе к базе данных. Некоторые пользователи должны только читать, а некоторые пользователи нуждаются в доступе чтения-записи.

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

Чтобы создать роли, надо использовать CREATE ROLE:

CREATE ROLE 'app_developer', 'app_read', 'app_write';
Чтобы назначить привилегии на эти роли, надо использовать GRANT так же, как назначая привилегии на учетные записи пользователя:
GRANT ALL ON app_db.* TO 'app_developer';
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
Теперь предположите, что первоначально Вы должны создать одну учетную запись разработчика, две учетных записи, которые нуждаются в доступе только для чтения, и одну учетную запись, которая нуждается в доступе чтения-записи. Примените CREATE USER, чтобы создать учетные записи:
CREATE USER 'dev1'@'localhost' IDENTIFIED BY 'dev1pass';
CREATE USER 'read_user1'@'localhost' IDENTIFIED BY 'read_user1pass';
CREATE USER 'read_user2'@'localhost' IDENTIFIED BY 'read_user2pass';
CREATE USER 'rw_user1'@'localhost' IDENTIFIED BY 'rw_user1pass';
Чтобы назначить каждой учетной записи необходимые привилегии, Вы могли бы использовать GRANT, но это требует перечисления привилегий для каждого пользователя. Вместо этого используйте GRANT, который разрешает предоставлять роли, а не привилегии:
GRANT 'app_developer' TO 'dev1'@'localhost';
GRANT 'app_read' TO 'read_user1'@'localhost', 'read_user2'@'localhost';
GRANT 'app_read', 'app_write' TO 'rw_user1'@'localhost';
rw_user1 предоставляют роли чтения и записи, которые объединяются, чтобы обеспечить необходимые привилегии чтения-записи.

GRANT для того, чтобы предоставить роли учетной записи отличается от синтаксиса для того, чтобы предоставить привилегии. Чтобы назначить привилегии, есть ON, тогда как, чтобы назначить роли ON нет. Поскольку синтаксисы отличны, Вы не можете смешать назначение привилегий и ролей в том же самом запросе. Разрешено назначить привилегии и роли учетной записи, но Вы должны использовать отдельные запросы GRANT, каждый со своим синтаксисом.

Чтобы проверить назначения привилегии, надо использовать SHOW GRANTS. Например:

mysql> SHOW GRANTS FOR 'dev1'@'localhost';
+-------------------------------------------------+
| Grants for dev1@localhost                       |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost`        |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+-------------------------------------------------+
Однако, это показывает каждую предоставленную роль без раскрытия ее к привилегиям, которые представляет роль. Чтобы показать ролевые привилегии также, добавьте USING, называя предоставленные роли, для которых нужно вывести на экран привилегии:
mysql> SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
+----------------------------------------------------------+
| Grants for dev1@localhost                                |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost`                 |
| GRANT ALL PRIVILEGES ON `app_db`.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost`          |
+----------------------------------------------------------+
Проверьте тип пользователя так же:
mysql> SHOW GRANTS FOR 'rw_user1'@'localhost'
    ->      USING 'app_read', 'app_write';
+------------------------------------------------------------------------------+
| Grants for rw_user1@localhost                                                |
+------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost`                                 |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO `rw_user1`@`localhost` |
| GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost`               |
+------------------------------------------------------------------------------+

mysql> SHOW GRANTS FOR 'read_user1'@'localhost' USING 'app_read';
+--------------------------------------------------------+
| Grants for read_user1@localhost                        |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `read_user1`@`localhost`         |
| GRANT SELECT ON `app_db`.* TO `read_user1`@`localhost` |
| GRANT `app_read`@`%` TO `read_user1`@`localhost`       |
+--------------------------------------------------------+
Если Вы не выводите на экран информацию для своей собственной учетной записи, USING требует привилегию SUPER.

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

SET DEFAULT ROLE ALL TO 'dev1'@'localhost', 'read_user1'@'localhost',
    'read_user2'@'localhost',
    'rw_user1'@'localhost';
Изменение привилегий, предоставленных роли также, затрагивает любого пользователя с этой ролью. Предположите, что Вы хотите временно сделать всех пользователей приложения пользователями только для чтения. Чтобы сделать это, отмените привилегии модификации от роли app_write:
REVOKE INSERT, UPDATE, DELETE ON app_db.* FROM 'app_write';
Когда это происходит, роль будет без привилегий вообще. Это может быть замечено, используя SHOW GRANTS (это демонстрирует, что этот запрос может использоваться с ролями):
mysql> SHOW GRANTS FOR 'app_write';
+---------------------------------------+
| Grants for app_write@%                |
+---------------------------------------+
| GRANT USAGE ON *.* TO `app_write`@`%` |
+---------------------------------------+
Поскольку отмена привилегии от ролей затрагивает привилегии для любого пользователя, которому назначали измененную роль, rw_user1 теперь не имеет никаких привилегий модификации:
mysql> SHOW GRANTS FOR 'rw_user1'@'localhost'
    ->      USING 'app_read', 'app_write';
+----------------------------------------------------------------+
| Grants for rw_user1@localhost                                  |
+----------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost`                   |
| GRANT SELECT ON `app_db`.* TO `rw_user1`@`localhost`           |
| GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost` |
+----------------------------------------------------------------+
В действительности пользователь rw_user1 с правами чтения-записи стал пользователем только для чтения. Это также происходит для любых других учетных записей, которым предоставляют те же самые роли. Не нужно менять привилегии для каждой такой учетной записи индивидуально.

Чтобы восстановить привилегии модификации к роли, просто повторно предоставьте их:

GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
rw_user1 снова имеет привилегии модификации (также, как и любые другие учетные записи с этой ролью).

Одна вещь, не очевидная из предыдущего обсуждения, состоит в том, что имя роли, как имя пользователя, состоит из части имени пользователя и части имени хоста в формате 'user_name'@'host_name '. Если часть узла отсутствует, она принимает значение по умолчанию %, что означает, что имена ролей 'app_developer', 'app_read' и 'app_write', создаваемые ранее, фактически 'app_developer'@'%', 'app_read'@'%' и 'app_write'@'%'. См. раздел 7.2.4.

7.3.5. Задание пределов ресурсов для учетной записи

Одно средство ограничения использования клиентом ресурсов сервера MySQL состоит в том, чтобы установить глобальную переменную max_user_connections к ненулевому значению. Это ограничивает число одновременных соединений, которые могут быть сделаны любым пользователем, но не устанавливает границ того, что клиент может сделать, когда соединится. Кроме того, установка max_user_connections не включает управление отдельными учетными записями. Оба типа управления представляют интерес для администраторов MySQL.

Чтобы обратиться к таким проблемам, MySQL разрешает пределы для отдельных учетных записей на использование этих ресурсов сервера:

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

account в этом контексте соответствует строке в таблице mysql.user. Таким образом, соединение оценено против User и Host в таблице user, которая относится к соединению. Например, учетная запись 'usera'@'%.example.com' соответствует строке в user, которая имеет User и Host, равные usera и %.example.com, чтобы разрешить usera соединяться от любого узла в домене example.com. В этом случае, сервер применяет пределы ресурса в этой строке все вместе ко всем соединениям usera от любого узла в домене example.com, потому что все такие соединения используют ту же самую учетную запись.

До MySQL 5.0.3 account был оценен против фактического узла, от которого соединяется пользователь. Этот более старый метод учета может быть выбран, запуская сервер с опцией --old-style-user-limits. В этом случае, если usera соединяется одновременно от host1.example.com и host2.example.com, сервер применяет пределы ресурса учетной записи отдельно к каждому соединению. Если usera соединяется снова от host1.example.com, сервер применяет пределы для этого соединения вместе с существующим соединением от этого узла.

Чтобы установить пределы ресурса для учетной записи во время создания учетной записи, используйте CREATE USER . Чтобы изменить пределы для существующей учетной записи, надо использовать ALTER USER. Обеспечьте параметр WITH, который называет каждый ресурс, который будет ограничен. Значение по умолчанию для каждого предела ноль (никакого предела). Например, чтобы создать новую учетную запись, которая может получить доступ к базе данных customer, но только ограниченным способом, сделайте эти запросы:

mysql> CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'
    ->        WITH MAX_QUERIES_PER_HOUR 20
    ->        MAX_UPDATES_PER_HOUR 10 MAX_CONNECTIONS_PER_HOUR 5
    ->        MAX_USER_CONNECTIONS 2;
Типы предела нельзя все назвать в WITH, но названные могут присутствовать в любом порядке. Значение для каждого почасового лимита должно быть целым числмо, представляющим количество в час. Для MAX_USER_CONNECTIONS предел это целое число, представляющее максимальное количество одновременных соединений с учетной записью. Если этот предел установлен к нолю, глобальная переменная max_user_connections определяет число одновременных соединений. Если max_user_connections также ноль, нет никакого предела для учетной записи.

Чтобы изменить пределы для существующей учетной записи, используйте ALTER USER. Следующий запрос изменяет предел запросов для francis на 100:

mysql> ALTER USER 'francis'@'localhost' WITH MAX_QUERIES_PER_HOUR 100;
Запрос изменяет только определенное предельное значение.

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

mysql> ALTER USER 'francis'@'localhost' WITH MAX_CONNECTIONS_PER_HOUR 0;
Как упомянуто ранее, предел одновременного соединения для учетной записи определен MAX_USER_CONNECTIONS и переменной max_user_connections . Предположите, что глобальное значение max_user_connections = 10 и три учетных записи, определили отдельные пределы ресурса следующим образом:
ALTER USER 'user1'@'localhost' WITH MAX_USER_CONNECTIONS 0;
ALTER USER 'user2'@'localhost' WITH MAX_USER_CONNECTIONS 5;
ALTER USER 'user3'@'localhost' WITH MAX_USER_CONNECTIONS 20;
user1 имеет предел соединения 10 (глобальное значение max_user_connections ), потому что у этого есть MAX_USER_CONNECTIONS = 0. user2 и user3 имеют пределы соединения 5 и 20, соответственно, потому что они имеют отличный от нуля MAX_USER_CONNECTIONS.

Сервер хранит пределы ресурса для учетной записи в строке таблицы user, соответствующей учетной записи. Столбцы max_questions, max_updates и max_connections хранят почасовые пределы и столбец max_user_connections хранит лимит MAX_USER_CONNECTIONS. См. раздел 7.2.2.

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

Поскольку сервер работает, он считает число раз, сколько каждая учетная запись использует ресурсы. Если учетная запись достигает своего предела на числе соединений в течение прошлого часа, сервер отклоняет дальнейшие соединения для учетной записи, пока этот час не закончился. Точно так же, если учетная запись достигает своего предела на числе запросов или обновлений, сервер отклоняет дальнейшие запросы или обновления, пока час не закончился. Во всех таких случаях сервер выпускает соответствующие сообщения об ошибках.

Подсчет ресурса происходит за учетную запись, а не за клиента. Например, если у Вашей учетной записи есть предел запроса 50, Вы не можете увеличить свой предел до 100, делая два одновременных соединения клиента с сервером. Запросы на обоих соединениях посчитаны вместе.

Текущее почасовое использование ресурса может быть сброшено глобально для всех учетных записей или индивидуально для конкретной записи:

Сбросы часовых счетчиков не затрагивают MAX_USER_CONNECTIONS.

Все количества начинаются с 0, когда сервер запускается. Счетчики не переносят через перезапуски сервера.

Для MAX_USER_CONNECTIONS случай края может произойти, если учетная запись в настоящее время имеет максимальное количество открытых соединений, разрешенных для нее: разъединение, сопровождаемое быстрым соединением, может привести к ошибке ( ER_TOO_MANY_USER_CONNECTIONS или ER_USER_LIMIT_REACHED ), если сервер не полностью обработал разъединение к тому времени, когда соединение происходит. Когда сервер обработает разъединение, другое соединение будет разрешено.

7.3.6. Назначение паролей учетной записи

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

MySQL хранит пароли в таблице user базы данных mysql. Операции, которые назначают или изменяют пароли, разрешены только пользователям с привилегией CREATE USER или привилегиями для базы данных mysql (INSERT, чтобы создавать новые записи, или UPDATE для модификации существующих). Если переменная read_only включена, использование запросов модификации учетной записи, например, CREATE USER или SET PASSWORD дополнительно требует привилегии SUPER.

Обсуждение здесь суммирует синтаксис только для наиболее распространенных операторов присваивания пароля. Для полных деталей о других возможностях см. разделы 14.7.1.3, 14.7.1.1, 14.7.1.6 и 14.7.1.11.

MySQL хеширует пароли, сохраненные в mysql.user. Для большинства запросов, описанных здесь, MySQL автоматически хеширует определенный пароль. Исключение это SET PASSWORD ... = PASSWORD('auth_string'), для которого Вы используете PASSWORD() явно, чтобы хешировать пароль. Есть также синтаксисы для for CREATE USER, ALTER USER, GRANT и SET PASSWORD, которые разрешают хешированные значения, которые будут определены буквально, для деталей см. описания тех запросов.

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

Чтобы назначить пароль, когда Вы создаете новую учетную запись, следует использовать CREATE USER и включить IDENTIFIED BY:

mysql> CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
Для CREATE USER MySQL MySQL автоматически хеширует пароль прежде, чем сохранить это в mysql.user.

CREATE USER также имеет синтаксис для того, чтобы определить плагин аутентификации учетной записи. См. раздел 14.7.1.3.

Чтобы назначить или изменить пароль для существующей учетной записи, используйте один из следующих методов:

7.3.7. Политика истечения пароля

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

Чтобы истечь пароль вручную, администратор базы данных использует ALTER USER:

ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
Эта работа отмечает пароль как истекший в соответствующей строке mysql.user. Таблица mysql.user показывает для каждой учетной записи, когда ее пароль был последний раз изменен, и сервер автоматически обрабатывает пароль как истекший во время соединения клиента. Это работает без явного ручного истечения пароля.

Переменная default_password_lifetime определяет глобальную автоматическую политику истечения пароля. Это относится к учетным записям, которые используют встроенные методы аутентификации MySQL (учетные записи, которые используют плагин аутентификации mysql_native_password или sha256_password).

По умолчанию default_password_lifetime = 0, отключает автоматическое истечение пароля. Если значение default_password_lifetime положительное целое число N, это указывает на разрешенное время жизни пароля: пароли должны быть изменены каждые N дней.

Примеры:

Независимо от глобальной политики это может быть переопределено для отдельных учетных записей с помощью ALTER USER:

Эти ALTER USER обновляют соответствующую строку mysql.user.

Когда клиент успешно соединяется, сервер определяет, истек ли пароль учетной записи:

Ограниченный клиент работает в режиме песочницы, который ограничивает операции, разрешенные клиентом (см. раздел 7.3.8). Операции, выполненные ограниченным клиентом, приводят к ошибке, пока пользователь не устанавливает новый пароль учетной записи:

mysql> SELECT 1;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement

mysql> ALTER USER USER() IDENTIFIED BY 'new_password';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
Этот ограниченный режим работы разрешает запрос SET, который полезен, если устаревший SET PASSWORD используется вместо ALTER USER и у пароля учетной записи есть формат хеширования, который требует old_passwords, отличающееся от значения по умолчанию.

Для административного пользователя возможно сбросить пароль учетной записи, но любые существующие сеансы для этой учетной записи остаются ограниченными. Клиент, использующий учетную запись, должен разъединиться и повторно соединиться прежде, чем запросы могут быть выполнены успешно.

7.3.8. Истечение пароля и режим песочницы

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

Чтобы истечь пароль учетной записи, используйте ALTER USER. Например:

ALTER USER 'myuser'@'localhost' PASSWORD EXPIRE;

Этот запрос изменяет строку в mysql.user с названной учетной записью, устанавливая password_expired в 'Y'. Это не затрагивает текущих соединений, которые учетная запись имеет. Для каждого последующего соединения, которое использует учетную запись, сервер или разъединяет клиента или обрабатывает клиента в sandbox mode, в котором сервер разрешает клиенту только те операции, которые необходимым, чтобы сбрасывать пароль с истекшим сроком. Меры, предпринятые сервером, зависят от настроек клиента и сервера.

Если сервер разъединяет клиента, он возвращает ошибку ER_MUST_CHANGE_PASSWORD_LOGIN:

shell> mysql -u myuser -p
Password: ******
ERROR 1862 (HY000): Your password has expired. To log in you must
change it using a client that supports expired passwords.
Если сервер помещает клиента в режим песочницы, эти операции разрешены в пределах сеанса клиента:

Для любой работы, не разрешенной в пределах сеанса, сервер возвращает ошибку ER_MUST_CHANGE_PASSWORD:

mysql> USE performance_schema;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement

mysql> SELECT 1;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
Для неинтерактивных запросов mysql (например, в пакетном режиме), сервер обычно разъединяет клиента, если пароль истек. Чтобы разрешить mysql оставаться соединенным так, чтобы пароль мог быть изменен (с использованием описанных выше запросов), добавьте опцию --connect-expired-password к вызову mysql.

Как упомянуто ранее, разъединяет ли сервер клиента с паролем с истекшим сроком или помещает в режим песочницы, зависит от комбинации настроек клиента и сервера. Следующее обсуждение описывает соответствующие настройки и как они взаимодействуют.

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

У разных MySQL Connector есть свои собственные соглашения для того, чтобы указать на готовность обработать режим песочницы. См. соответствующую документацию.

На стороне сервера, если клиент указывает, что может обработать истекшие пароли, сервер помещает это в режим песочницы.

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

Предыдущие настройки клиента и сервера применяются только для учетных записей с паролями с истекшим сроком. Если клиент соединяется с использованием пароля с неистекшим сроком, сервер обрабатывает клиента как обычно.

7.3.9. Аутентификация плагинами

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

Плагин возвращает состояние серверу, указывая, разрешают ли пользователю соединиться.

Аутентификация включает две важные способности:

Несколько плагинов аутентификации доступны в MySQL:

См. раздел C.9 .

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

См. раздел 26.2.4.9 .

Инструкции использования плагина аутентификации

Этот раздел обеспечивает общие инструкции для установки и использования плагинов аутентификации.

Вообще аутентификация использует соответствующие плагины на сторонах сервера и клиента, таким образом, Вы используете данный метод аутентификации так:

Инструкции здесь используют в качестве примера плагин аутентификации, включенный в MySQL (см. раздел 7.5.1.6). Процедура подобна для других плагинов аутентификации, замените соответствующим плагином и именами файла.

У плагина аутентификации в качестве примера есть эти характеристики:

Установите и используйте плагин аутентификации в качестве примера следующим образом:

  1. Удостоверьтесь, что библиотека установлена на хостах сервера и клиента.

  2. Установите серверный испытательный плагин при запуске сервера или во время выполнения:

  3. Проверьте, что плагин установлен. Например, можно использовать SHOW PLUGINS:

    mysql> SHOW PLUGINS\G
    ...
    *************************** 21. row ***************************
       Name: test_plugin_server
     Status: ACTIVE
       Type: AUTHENTICATION
    Library: auth_test_plugin.so
    License: GPL
    
    См. раздел 6.6.3.
  4. Чтобы определить, что пользователь MySQL должен быть заверен, используя определенный плагин сервера, назовите плагин в IDENTIFIED WITH запроса CREATE USER, который создает пользователя:
    CREATE USER 'testuser'@'localhost' IDENTIFIED WITH test_plugin_server;
    
  5. Соединитесь с сервером, используя программу клиента. Испытательный плагин подтверждает подлинность тем же самым путем, как аутентификация MySQL, так что обеспечьте обычные параметры --user и --password, которые Вы обычно используете, чтобы соединиться с сервером. Например:
    shell> mysql --user=your_name --password=your_pass
    
    Для соединений testuser сервер видит, что учетная запись должна быть заверена, используя серверный плагин test_plugin_server и сообщает программе клиента, какой клиентский плагин это должно использовать, в этом случае auth_test_plugin.

    В случае, если учетная запись использует метод аутентификации, который является значением по умолчанию для сервера и для программы клиента, сервер не должен сообщать клиенту, какой плагин использовать. Это истина для учетных записей, которые используют аутентификацию MySQL (mysql_native_password).

    Опция --default-auth=plugin_name может быть определена в командной строке mysql как подсказка, который клиентский плагин программа может ожидать использовать, хотя сервер переопределит это, если учетная запись пользователя потребует отличного плагина.

    Если программа клиента не находит плагин, определите опцию --plugin-dir= dir_name, чтобы указать, где плагин расположен.

Если Вы запускаете сервер с опцией --skip-grant-tables, плагины аутентификации не используются, даже если загружены, потому что сервер не выполняет аутентификации клиента и разрешает любому клиенту соединяться. Поскольку это опасно, Вы могли бы хотеть использовать --skip-grant-tables вместе с --skip-networking , чтобы препятствовать тому, чтобы отдаленные клиенты соединились.

7.3.10. Пользователи Proxy

Аутентификация к серверу MySQL происходит посредством плагинов аутентификации. Плагин, который подтверждает подлинность данного соединения, может просить, чтобы соединяющийся (внешний) пользователь был обработан как различный пользователь в проверке привилегий. Это позволяет внешнему пользователю быть полномочием для второго пользователя, то есть, чтобы иметь привилегии второго пользователя:

Этот раздел описывает, как пользователь по доверенности работает. Для общей информации о плагинах аутентификации см. раздел 7.3.9. Для информации об определенных плагинах см. раздел 7.5.1. Для информации о написании плагинов аутентификации, которые поддерживают пользователей по доверенности см. раздел 26.2.4.9.4.

Для proxy для данного плагина аутентификации должны быть удовлетворены эти условия:

Механизм по доверенности разрешает отображать только имя пользователя клиента на proxied имя пользователя. Нет никакого предоставления для того, чтобы отобразить имена хоста. Когда соединяющийся клиент соответствует учетной записи по доверенности, сервер работает с учетной записи proxied, используя имя пользователя возвращенное плагином аутентификации и имея хоста учетной записи по доверенности.

Рассмотрите следующие определения:

-- create proxy user
CREATE USER 'employee_ext'@'localhost'
       IDENTIFIED WITH my_auth_plugin AS 'my_auth_string';

-- create proxied user
CREATE USER 'employee'@'localhost' IDENTIFIED BY 'employee_pass';

-- grant PROXY privilege for proxy user to proxied user
GRANT PROXY ON 'employee'@'localhost' TO 'employee_ext'@'localhost';
Когда клиент соединяется как employee_ext от местного узла, используется my_auth_plugin, чтобы выполнить аутентификацию. Предположите, что my_auth_plugin возвращает имя пользователя employee серверу, основанное на контенте 'my_auth_string' и возможно консультируясь с некоторой внешней системой аутентификации. Имя employee это не employee_ext, так что возвращение employee служит запросом к серверу, чтобы обработать клиента employee_ext в целях проверки привилегии как employee.

В этом случае employee_ext это пользователь по доверенности и employee proxied пользователь.

Сервер проверяет аутентификацию по доверенности для employee возможно для employee_ext, проверяя имеет ли proxy-пользователь employee_ext привилегию PROXY для employee (proxied). Если эту привилегию не предоставили, ошибка происходит.

Когда proxying происходит, функции USER() и CURRENT_USER() могут использоваться, чтобы видеть различие между соединяющимся пользователем (пользователь по доверенности) и учетной записью, привилегии которой применяются во время текущего сеанса (proxied-пользователь). Для только что описанного примера те функции возвращают эти значения:

mysql> SELECT USER(), CURRENT_USER();
+------------------------+--------------------+
| USER()                 | CURRENT_USER()     |
+------------------------+--------------------+
| employee_ext@localhost | employee@localhost |
+------------------------+--------------------+
В CREATE USER, который создает учетную запись пользователя по доверенности, IDENTIFIED WITH, который называет плагин аутентификации, произвольно сопровождается AS 'auth_string', определяющей строку, которую сервер передает к плагину, когда пользователь соединяется. Если существует, строка предоставляет информацию, которая помогает плагину определить, как отобразить внешнее имя пользователя клиента на proxied имя пользователя. Если плагин использует этот параметр, формат строки аутентификации зависит от того, как плагин намеревается использовать это. Консультируйтесь с документацией для данного плагина для информации о строковых значениях аутентификации, которые это принимает.

Предоставление привилегии по доверенности

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

GRANT PROXY ON 'proxied_user' TO 'proxy_user';
Запрос создает строку в таблице mysql.proxies_priv.

Во время соединения proxy_user должен представить допустимого внешне заверенного пользователя MySQL, и proxied_user должен представить допустимого в местном масштабе заверенного пользователя. Иначе попытка соединения терпит неудачу.

Синтаксис REVOKE такой:

REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';
Расширения MySQL для GRANT и REVOKE работают как обычно:
GRANT PROXY ON 'a' TO 'b', 'c', 'd';
GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION;
GRANT PROXY ON 'a' TO ''@'';
REVOKE PROXY ON 'a' FROM 'b', 'c', 'd';
В предыдущем примере ''@'' это пользователь proxy по умолчанию и означает любой пользователь.

Привилегию PROXY можно предоставить в этих случаях:

Начальная учетная запись root, создаваемая во время установки MySQL, имеет привилегию PROXY ... WITH GRANT OPTION для ''@'', то есть, для всех пользователей и всех узлов. Это разрешает root настраивать пользователей по доверенности, а также делегировать другим учетным записям полномочия настроить пользователей по доверенности. Например, root может сделать это:

CREATE USER 'admin'@'localhost' IDENTIFIED BY 'test';
GRANT PROXY ON ''@'' TO 'admin'@'localhost' WITH GRANT OPTION;
Эти запросы создают пользователя admin, который может управлять всеми отображениями GRANT PROXY. Например, admin может сделать это:
GRANT PROXY ON sally TO joe;

Пользователи полномочий по умолчанию

Чтобы определить, что некоторые или все пользователи должны соединиться с использованием данного плагина аутентификации, создайте пустого пользователя MySQL, свяжите его с тем плагином для аутентификации и позвольте плагину возвращать реальное заверенное имя пользователя (если это не пустой пользователь). Например, предположите, что существует плагин ldap_auth, который осуществляет аутентификацию LDAP и отображение пользователей на учетную запись разработчика или на менеджера. Чтобы настроить proxying пользователей на эти учетные записи, используйте следующие запросы:

-- create default proxy user
CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL';
-- create proxied users
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'developer_pass';
CREATE USER 'manager'@'localhost' IDENTIFIED BY 'manager_pass';

-- grant PROXY privilege for default proxy user to proxied users
GRANT PROXY ON 'manager'@'localhost' TO ''@'';
GRANT PROXY ON 'developer'@'localhost' TO ''@'';
Теперь предположите, что клиент пытается соединиться следующим образом:
mysql --user=myuser --password='myuser_pass' ...
Сервер не будет находить myuser, определенный как пользователь MySQL. Но потому что есть пустая учетная запись пользователя (''@''), которая соответствует имени пользователя клиента и хоста, сервер подтверждает подлинность клиента по этой учетной записи: сервер вызывает ldap_auth и передает ему myuser и myuser_pass как имя пользователя и пароль.

Если плагин ldap_auth находит в каталоге LDAP myuser_pass неправильный пароль для myuser, аутентификация терпит неудачу, и сервер отклоняет соединение.

Если пароль правилен и ldap_auth считает, что myuser разработчик, это возвращает имя пользователя developer серверу MySQL вместо myuser. Возвращение имени пользователя, отличающегося от имени пользователя клиента myuser сигнал серверу, что это должно обработать myuser как proxy. Сервер проверяет, что ''@'' может подтвердить подлинность как developer (потому что это имеет привилегию PROXY) и принимает соединение. Сеанс присваивает myuser привилегии developer. Эти привилегии должны быть настроены заранее с использованием GRANT. Функции USER() и CURRENT_USER() возвращают эти значения:

mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER()           | CURRENT_USER()      |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+
Если плагин вместо этого находит в каталоге LDAP, что myuser менеджер, это возвращает manager как имя пользователя и сеанс присваивает myuser привилегии для manager.
mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER()           | CURRENT_USER()    |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+
Для простоты внешняя аутентификация не может быть многоуровневой.

Полномочия значения по умолчанию и анонимные пользовательские конфликты

Если Вы намереваетесь создать пользователя proxy по умолчанию, проверьте соответствие учетной записи любого пользователя, которая имеют приоритет и таким образом препятствуют тому, чтобы пользователь по умолчанию работал, как предназначено.

В предыдущем обсуждении учетная запись пользователя proxy по умолчанию имеет '' в части узла, которая соответствует любому узлу. Если Вы настраиваете пользователя proxy по умолчанию, позаботьтесь также о проверке, существуют ли учетные записи не по доверенности с той же самой пользовательской частью и '%' в части узла, потому что '%' также соответствует любому узлу, но имеет приоритет перед '' по правилам, которые сервер использует для сортировки строк учетной записи внутренне (см. раздел 7.2.5).

Предположите, что установка MySQL включает эти две учетных записи:

-- create default proxy user
CREATE USER ''@'' IDENTIFIED WITH some_plugin AS 'some_auth_string';
-- create anonymous user
CREATE USER ''@'%' IDENTIFIED BY 'some_password';
Первая учетная запись (''@'') работает как пользователь proxy по умолчанию, используемый, чтобы подтвердить подлинность соединений для пользователей, которые иначе не соответствуют более определенным учетным записям. Вторая учетная запись (''@'%') это анонимная учетная запись пользователя, которая, возможно, была создана, например, чтобы позволить пользователям без их собственной учетной записи соединиться анонимно.

У обеих учетных записей есть та же самая пользовательская часть (''), которая соответствует любому пользователю. И у каждой учетной записи есть часть узла, которая соответствует любому узлу. Однако, есть приоритет в учетной записи, соответствующей для попыток соединения, потому что соответствующие правила сортируют узел '%' перед ''. Для учетных записей, которые не соответствуют более определенной учетной записи, сервер пытается подтвердить их подлинность для ''@'%' (анонимный пользователь), а не ''@'' (пользователь proxy по умолчанию). Результат состоит в том, что учетная запись proxy по умолчанию никогда не используется.

Чтобы избежать этой проблемы, используйте одну из следующих стратегий:

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

Некоторые плагины аутентификации осуществляют отображение пользователя по доверенности для себя. Сервер самого MySQL может отобразить пользователей по доверенности согласно предоставленным привилегиям по доверенности. Если переменная check_proxy_users включена, сервер выполняет отображение пользователя по доверенности для любых плагинов аутентификации, которые просят это:

Пользовательское отображение по доверенности, выполненное сервером, подвергается некоторым ограничениям:

Пользовательские системные переменные по доверенности

Две системные переменные прослеживают процесс входа в систему по доверенности:

7.3.11. Блокировка учетной записи пользователя

MySQL поддерживает блокировку учетных записей пользователя, используя ACCOUNT LOCK и ACCOUNT UNLOCK для CREATE USER и ALTER USER:

Блокировка зарегистрирована в столбце account_locked таблицы mysql.user. Вывод SHOW CREATE USER указывает, заблокирована ли учетная запись.

Если клиент пытается соединиться с заблокированной учетной записью, попытка терпит неудачу. Сервер постепенно увеличивает переменную Locked_connects , которая указывает на число попыток соединиться с заблокированной учетной записью, возвращает ошибку ER_ACCOUNT_HAS_BEEN_LOCKED и пишет сообщение в журнал ошибок:

Access denied for user 'user_name'@'host_name'.
Account is locked.
Блокировка учетной записи не затрагивает возможность соединиться с использованием пользователя по доверенности, который принимает идентичность заблокированной учетной записи. Это также не затрагивает способность выполнить сохраненные программы или представления, у которых есть DEFINER, указывающий на заблокированную учетную запись. Таким образом, способность использовать учетную запись proxied или сохраненными программами (или представлениями) не затронута, блокируя учетную запись.

Блокирующая учетную запись способность зависит от присутствия столбца account_locked в mysql.user. Для обновлений до MySQL 5.7.6 и позже от более старых версий должен быть выполнен mysql_upgrade , чтобы гарантировать, что этот столбец существует. Для необновленных установок, которые не имеют столбца account_locked, сервер обрабатывает все учетные записи как разблокированные, а использование ACCOUNT LOCK или ACCOUNT UNLOCK производит ошибку.

7.3.12. Ревизия деятельности учетной записи MySQL

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

Учетные записи MySQL соответствуют строкам в mysql.user. Когда клиент соединяется успешно, сервер подтверждает подлинность клиента к особой строке в этой таблице. User и Host столбцы в этой строке уникально идентифицируют учетную запись и соответствуют формату 'user_name'@'host_name' , в котором имена учетной записи написаны в запросах SQL.

Учетная запись, используемая, чтобы подтвердить подлинность клиента, определяет, какие привилегии клиент имеет. Обычно функция CURRENT_USER() может быть вызвана, чтобы определить, какая это учетная запись для пользователя клиента. Ее значение создано из столбцов User и Host строки таблицы user для учетной записи.

Однако, есть обстоятельства, при которых CURRENT_USER() соответствует не пользователю клиента, а отличной учетной записи. Это происходит в контекстах, когда проверка привилегии не базируется на учетной записи клиента:

В тех контекстах проверка привилегии сделана против DEFINER, а CURRENT_USER() ссылается на ту учетную запись, а не на клиента, который вызвал сохраненную подпрограмму или представление или кто заставил триггер активироваться. Чтобы определить пользователя вызова, Вы можете вызвать USER(), которая возвращает значение, указывающее на фактическое имя пользователя, обеспеченное клиентом и узлом, от которого соединялся клиент. Однако, это значение не обязательно соответствует непосредственно учетной записи в таблице user, так как USER() никогда не содержит подстановочные знаки, тогда как значение учетной записи (как возвращено CURRENT_USER()) может содержать подстановочные знаки имени хоста и имя пользователя.

Например, пустое имя пользователя соответствует любому пользователю, таким образом, учетная запись ''@'localhost' позволяет клиентам соединиться как анонимный пользователь от местного узла с любым именем пользователя. В этом случае если клиент соединяется как user1 от местного узла, USER() и CURRENT_USER() возвратят различные значения:

mysql> SELECT USER(), CURRENT_USER();
+-----------------+----------------+
| USER()          | CURRENT_USER() |
+-----------------+----------------+
| user1@localhost | @localhost     |
+-----------------+----------------+
Часть имени хоста учетной записи может содержать подстановочные знаки. Если имя хоста содержит '%', '_' или применяет нотацию сетевой маски, учетная запись может использоваться для клиентов, соединяющихся от многих узлов и CURRENT_USER() не будет указывать, от какого именно. Например, учетная запись 'user2'@'%.example.com' может использоваться user2, чтобы соединяться от любого узла в домене example.com. Если user2 соединяется от remote.example.com, USER() и CURRENT_USER() возвратят различные значения:
mysql> SELECT USER(), CURRENT_USER();
+--------------------------+---------------------+
| USER()                   | CURRENT_USER()      |
+--------------------------+---------------------+
| user2@remote.example.com | user2@%.example.com |
+--------------------------+---------------------+
Если приложение должно вызвать USER() для ревизии пользователя (например, если это делает ревизию изнутри триггера), оно должно также быть в состоянии связать USER() с учетной записью в таблице user, поэтому необходимо избежать учетных записей, которые содержат подстановочные знаки в столбцах User или Host. Определенно не разрешено User быть пустым (что создает анонимную учетную запись пользователя) и не разрешаются символы образца или нотация сетевой маски в Host. У всех учетных записей должно быть непустое значение User и точное Host.

Относительно предыдущих примеров, учетные записи ''@'localhost' и 'user2'@'%.example.com' должны быть изменены, чтобы не использовать подстановочные знаки:

RENAME USER ''@'localhost' TO 'user1'@'localhost';
RENAME USER 'user2'@'%.example.com' TO 'user2'@'remote.example.com';
Если user2 должен быть в состоянии соединиться от нескольких узлов в example.com, должна быть отдельная учетка на каждый узел.

Чтобы извлечь имя пользователя или имя хоста из CURRENT_USER() или USER(), используйте SUBSTRING_INDEX() :

mysql> SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',1);
+---------------------------------------+
| SUBSTRING_INDEX(CURRENT_USER(),'@',1) |
+---------------------------------------+
| user1                                 |
+---------------------------------------+

mysql> SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',-1);
+----------------------------------------+
| SUBSTRING_INDEX(CURRENT_USER(),'@',-1) |
+----------------------------------------+
| localhost                              |
+----------------------------------------+

7.4. Используя безопасные соединения

С незашифрованным соединением между клиентом MySQL и сервером кто-то с доступом к сети мог бы наблюдать весь Ваш трафик и осмотреть данные, посылаемые или полученные между клиентом и сервером.

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

MySQL поддерживает безопасные (зашифрованные) соединения между клиентами и сервером, используя TLS (Transport Layer Security). TLS иногда упоминается как SSL (Secure Sockets Layer), но MySQL фактически не использует протокол SSL для безопасных соединений, потому что это обеспечивает слабое шифрование (см. раздел 7.4.3 ).

TLS использует алгоритмы шифрования, чтобы гарантировать, что данным, полученным по общедоступной сети, можно доверять. У этого есть механизмы, чтобы обнаружить изменение данных, потерю или переигровку. TLS также включает алгоритмы, которые обеспечивают проверку идентичности, используя стандарт X509.

X509 позволяет идентифицировать кого-то в Интернете. В основных условиях должен быть некоторый объект, названный Certificate Authority (CA), который назначает электронные сертификаты любому, кто нуждается в них. Сертификаты полагаются на асимметричные алгоритмы шифрования, у которых есть два ключа шифрования (открытый ключ и секретный ключ). Владелец сертификаты может представить сертификат другой стороне как доказательство идентичности. Сертификат состоит из открытого ключа своего владельца. Зашифрованное использование любых данных этого открытого ключа может быть дешифровано, только используя соответствующий секретный ключ, который хранится владельцем сертификата.

MySQL может быть собран для использования поддержки безопасного соединения OpenSSL или yaSSL. Для сравнения этих двух пакетов см. раздел 7.4.1. Для информации о протоколах шифрования и шифрах каждого пакета см. раздел 7.4.3.

MySQL выполняет шифрование на основе соединения, и использование шифрования для данного пользователя может быть дополнительным или принудительным. Это позволяет Вам выбрать зашифрованное или незашифрованное соединение, согласно требованиям отдельных приложений. Для информации о том, как потребовать, чтобы пользователи использовали зашифрованные соединения см. обсуждение параметра REQUIRE в CREATE USER в разделе 14.7.1.3 . См. также переменную require_secure_transport в разделе 6.1.5.

Безопасные соединения доступны через MySQL C API с использованием mysql_ssl_set() и mysql_options(). См. разделы 25.8.7.72 и 25.8.7.50.

Репликация использует C API, таким образом, безопасные соединения могут использоваться между основными и ведомыми серверами. См. раздел 19.3.9 .

Также возможно соединиться надежно изнутри соединения SSH с узлом сервера MySQL. Для примера см. раздел 7.4.7 .

7.4.1. OpenSSL и yaSSL

MySQL может быть собран, используя OpenSSL или yaSSL, оба из которых включают безопасное соединение, основанное на OpenSSL API:

OpenSSL и yaSSL предлагают ту же самую основную функциональность, но у дистрибутивов MySQL, собранных, используя OpenSSL, есть дополнительные функции:

Определенная OpenSSL-связанная система и переменные состояния присутствуют, только если MySQL был собран, используя OpenSSL:

Чтобы определить, был ли Ваш сервер собран, используя OpenSSL, проверьте существование любой из этих переменных. Например, этот запрос возвращает строку, если OpenSSL использовался и пустой результат, если yaSSL использовался:

SHOW STATUS LIKE 'Rsa_public_key';

7.4.2. Создание MySQL с поддержкой безопасных соединений

Чтобы использовать соединения SSL между сервером MySQL и программами клиента, Ваша система должна поддерживать OpenSSL или yaSSL:

Если Вы собираете MySQL от исходного дистрибутива, CMake конфигурирует пакет, чтобы использовать yaSSL по умолчанию. Чтобы собрать с использованием OpenSSL вместо этого, используйте эту процедуру:

  1. Гарантируйте, что OpenSSL 1.0.1 или выше установлен на Вашей системе. Чтобы получить OpenSSL, посетите http://www.openssl.org.

    Если установленная версия OpenSSL ниже 1.0.1, CMake производит ошибку во время конфигурации MySQL.

  2. Чтобы использовать OpenSSL, добавьте опцию -DWITH_SSL=system для CMake. Например:
    shell> cmake . -DWITH_SSL=system
    
    Эта команда конфигурирует пакет, чтобы пользоваться установленной библиотекой OpenSSL. Альтернативно, чтобы явно определить путь к установке OpenSSL, используйте следующий синтаксис. Это может быть полезно, если у Вас есть много версий установленного OpenSSL, чтобы препятствовать тому, чтобы CMake выбрал неправильную:
    shell> cmake . -DWITH_SSL=path_name
    
    См. раздел 2.8.4.
  3. Соберите и установите пакет.

Чтобы проверить, поддерживает ли mysqld безопасные соединения, исследуйте значение переменной have_ssl :

mysql> SHOW VARIABLES LIKE 'have_ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_ssl      | YES   |
+---------------+-------+
Если это YES, сервер поддерживает безопасные соединения. Если значение DISABLED, сервер способен к поддержке безопасных соединений, но не был запущен с соответствующей опцией --ssl-xxx, см. раздел 7.4.4.

Чтобы определить, был ли сервер собран, используя OpenSSL или yaSSL, проверьте существование любой системы или переменных состояния, которые присутствуют только для OpenSSL. См. раздел 7.4.1.

7.4.3. Безопасные протоколы соединения и шифры

Чтобы определить, какой протокол шифрования и шифр используются для зашифрованного соединения, используйте следующие запросы, чтобы проверить значения переменных Ssl_version и Ssl_cipher:

mysql> SHOW SESSION STATUS LIKE 'Ssl_version';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Ssl_version   | TLSv1 |
+---------------+-------+

mysql> SHOW SESSION STATUS LIKE 'Ssl_cipher';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES128-GCM-SHA256 |
+---------------+---------------------------+
Если соединение не зашифровано, у обеих переменных пустое значение.

MySQL поддерживает зашифрованные соединения, используя протоколы TLS:

Значение переменной tls_version определяет, которые протоколы разрешено использовать из тех, которые доступны. Значение tls_version это разделенный запятыми список значений, содержащий один или больше этих протоколов (не чувствительны к регистру): TLSv1, TLSv1.1, TLSv1.2. По умолчанию, эта переменная перечисляет все протоколы, поддержанные библиотекой SSL, использовавшейся, чтобы собрать MySQL (TLSv1,TLSv1.1,TLSv1.2 для OpenSSL, TLSv1,TLSv1.1 для yaSSL). Чтобы определить значение tls_version во время выполнения, используйте этот запрос:

mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| tls_version   | TLSv1,TLSv1.1,TLSv1.2 |
+---------------+-----------------------+
Чтобы изменить значение tls_version, установите это при запуске сервера. Например, чтобы запретить соединения, которые используют протокол TLSv1, используют эти строки в файле my.cnf:
[mysqld]
tls_version=TLSv1.1,TLSv1.2
Чтобы быть даже больше защищенным и разрешать только соединения TLSv1.2, установите tls_version так (предполагается, что Ваш сервер собран, используя OpenSSL, потому что yaSSL не поддерживает TLSv1.2):
[mysqld]
tls_version=TLSv1.2
Для программ клиента опция --tls-version позволяет определить протоколы TLS, разрешенные в ответ на запрос клиента. Формат значения тот же самый, что касается tls_version .

По умолчанию, MySQL пытается использовать самую высокую версию протокола TLS, доступную в зависимости от того, которой библиотекой SSL пользовались, чтобы собрать сервер и клиент, какой ключевой размер используется и ограничены ли сервер или клиент от использования некоторых протоколов, например, посредством tls_version/ --tls-version:

Если у сервера и клиента нет никакого общего протокола, сервер заканчивает запрос соединения. Например, если сервер сконфигурирован с tls_version=TLSv1.1,TLSv1.2 , попытки соединения потерпят неудачу для клиентов, вызванных с --tls-version=TLSv1 , и для клиентов, которые не поддерживают опцию --tls-version (и неявно поддерживают только TLSv1).

Чтобы определить, который шифр данный сервер поддерживает, используйте следующий запрос, чтобы проверить значение переменной Ssl_cipher_list :

SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
Набор доступных шифров зависит от Вашей версии MySQL, был ли MySQL собран, используя OpenSSL или yaSSL и (для OpenSSL) от версии библиотеки.

Порядок шифров, которые передает MySQL в библиотеку SSL, является существенным. Более безопасные шифры упомянуты сначала в списке, и первый шифр, поддержанный обеспеченным сертификатом, выбран.

MySQL передает этот список шифров OpenSSL:

ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-DSS-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256
DHE-DSS-AES128-SHA256
DHE-DSS-AES256-GCM-SHA384
DHE-RSA-AES256-SHA256
DHE-DSS-AES256-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
DHE-DSS-AES128-SHA
DHE-RSA-AES128-SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
DHE-RSA-AES256-SHA
AES128-GCM-SHA256
DH-DSS-AES128-GCM-SHA256
ECDH-ECDSA-AES128-GCM-SHA256
AES256-GCM-SHA384
DH-DSS-AES256-GCM-SHA384
ECDH-ECDSA-AES256-GCM-SHA384
AES128-SHA256
DH-DSS-AES128-SHA256
ECDH-ECDSA-AES128-SHA256
AES256-SHA256
DH-DSS-AES256-SHA256
ECDH-ECDSA-AES256-SHA384
AES128-SHA
DH-DSS-AES128-SHA
ECDH-ECDSA-AES128-SHA
AES256-SHA
DH-DSS-AES256-SHA
ECDH-ECDSA-AES256-SHA
DHE-RSA-AES256-GCM-SHA384
DH-RSA-AES128-GCM-SHA256
ECDH-RSA-AES128-GCM-SHA256
DH-RSA-AES256-GCM-SHA384
ECDH-RSA-AES256-GCM-SHA384
DH-RSA-AES128-SHA256
ECDH-RSA-AES128-SHA256
DH-RSA-AES256-SHA256
ECDH-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-ECDSA-AES256-SHA
DHE-DSS-AES128-SHA
DHE-RSA-AES128-SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
DHE-RSA-AES256-SHA
AES128-SHA
DH-DSS-AES128-SHA
ECDH-ECDSA-AES128-SHA
AES256-SHA
DH-DSS-AES256-SHA
ECDH-ECDSA-AES256-SHA
DH-RSA-AES128-SHA
ECDH-RSA-AES128-SHA
DH-RSA-AES256-SHA
ECDH-RSA-AES256-SHA
DES-CBC3-SHA
MySQL передает этот список шифров yaSSL:
DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA
AES128-RMD
DES-CBC3-RMD
DHE-RSA-AES256-RMD
DHE-RSA-AES128-RMD
DHE-RSA-DES-CBC3-RMD
AES256-SHA
RC4-SHA
RC4-MD5
DES-CBC3-SHA
DES-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC-SHA
AES128-SHA:AES256-RMD
Эти ограничения шифра активны:

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

7.4.4. Конфигурирование MySQL, чтобы использовать безопасные соединения

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

Если Вы должны создать необходимые сертификат и ключевые файлы, см. раздел 7.4.6.

Серверная конфигурация для безопасных соединений

Чтобы запустить сервер MySQL так, чтобы это разрешило клиентам соединяться надежно, используйте опции, которые идентифицируют сертификат и ключевые файлы сервера, устанавливая безопасное соединение:

Например, запустите сервер с этих строк в my.cnf, изменяя имена файлов по мере необходимости:

[mysqld]
ssl-ca=ca.pem
ssl-cert=server-cert.pem
ssl-key=server-key.pem
Каждая опция называет файл в формате PEM. Если у Вас есть исходный дистрибутив MySQL, Вы можете проверить свою установку, используя демонстрационный сертификат и ключевые файлы в каталоге mysql-test/std_data.

Опция стороны сервера --ssl включена по умолчанию.

Серверы MySQL, собранные, используя OpenSSL, могут произвести недостающие сертификат и ключевые файлы автоматически при запуске. См. раздел 7.4.6.1.

Сервер выполняет автооткрытие файла сертификата и ключа. Если включена --ssl (возможно наряду с --ssl-cipher) и другие опции --ssl-xxx не даны, чтобы сконфигурировать безопасные соединения явно, сервер пытается включить поддержку безопасных соединений автоматически при запуске:

Если сервер автоматически включает поддержку безопасных соединений, это пишет сообщение в журнал ошибок. Если сервер обнаруживает, что сертификат CA самоподписан, он пишет предупреждение в журнал ошибок. Сертификат будет самоподписан, если создается автоматически сервером или вручную, используя mysql_ssl_rsa_setup .

Для любого сертификата и ключевых файлов, которые сервер обнаруживает и использует автоматически, он использует имена файла, чтобы установить соответствующие системные переменные (ssl_ca, ssl_cert и ssl_key).

Для дальнейшего управления, должны ли клиенты соединиться надежно, используйте переменную require_secure_transport, см. раздел 6.1.5.

Клиентская конфигурация для безопасных соединений

Для программ клиента опции для безопасных соединений подобны используемым на стороне сервера, но --ssl-cert и --ssl-key идентифицируют общественный и частный ключ клиента:

Чтобы соединиться надежно с сервером MySQL, который поддерживает безопасные соединения, опции, которые должен определить клиент, зависят от требований шифрования учетной записи MySQL, используемой клиентом. См. обсуждение REQUIRE в разделе 14.7.1.3.

Предположите, что Вы хотите соединиться с использованием учетной записи, которая не имеет никаких специальных требований шифрования или создавалась, используя CREATE USER, который включает REQUIRE SSL. Как рекомендуемый набор опций безопасного соединения, запустите сервер с, по крайней мере, --ssl-cert и --ssl-key, и вызовите клиент с --ssl-ca. Клиент может соединиться надежно так:

shell> mysql --ssl-ca=ca.pem
Чтобы потребовать, чтобы сертификат клиента также был определен, создайте учетную запись, используя опцию REQUIRE X509. Тогда клиент должен также определить надлежащий ключ клиента и файлы сертификата, или сервер отклонит соединение:
shell> mysql --ssl-ca=ca.pem \
                --ssl-cert=client-cert.pem --ssl-key=client-key.pem
Чтобы предотвратить использование шифрования и переопределить другие опции --ssl-xxx, вызовите программу клиента с --ssl-mode=DISABLED .
shell> mysql --ssl-mode=DISABLED
Программы клиента пытаются установить безопасное соединение по умолчанию всякий раз, когда сервер поддерживает безопасные соединения:

См. раздел 7.4.3.

Клиент может определить, использует ли текущее соединение с сервером шифрование, проверяя значение Ssl_cipher. Если значение пусто, соединение не зашифровано. Иначе соединение зашифровано, и значение указывает на шифр шифрования. Например:

mysql> SHOW STATUS LIKE 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA |
+---------------+--------------------+
Для mysql альтернатива должна использовать STATUS или \s и проверять строку SSL:
mysql> \s
...
SSL: Cipher in use is DHE-RSA-AES256-SHA
...
Или:
mysql> \s
...
SSL: Not in use
...

Конфигурация C API для безопасных соединений

C API позволяет приложениям использовать безопасные соединения:

Репликация использует C API, таким образом, безопасные соединения могут использоваться между основными и ведомыми серверами. См. раздел 19.3.9 .

7.4.5. Опции команды для безопасных соединений

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

Таблица 7.8. Резюме опций безопасного соединения

ФорматОписание
--skip-sslНе используйте безопасное соединение
--ssl Включить безопасное соединение
--ssl-ca Путь к файлу, который содержит список SSL CA
--ssl-capathПуть каталога, который содержит, доверенные сертификаты SSL CA в формате PEM
--ssl-cert Путь к файлу, который содержит сертификат X509 в формате PEM
--ssl-cipherСписок разрешенных шифров, чтобы использовать для шифрования соединения
--ssl-crl Путь к файлу, который содержит списки аннулирования сертификатов
--ssl-crlpathПуть к каталогу, который содержит файлы списка аннулирования сертификатов
--ssl-key Путь к файлу, который содержит ключ X509 в формате PEM
--ssl-mode Статус безопасности соединения с сервером
--tls-versionПротоколы, разрешенные для безопасных соединений

7.4.6. Создание сертификатов и ключей SSL и RSA

Следующее обсуждение описывает, как создать файлы, требуемые для SSL и поддержки RSA в MySQL. Создание файла может быть выполнено, используя услуги, предоставленные MySQL непосредственно или вызывая openssl.

Сертификат SSL и ключевые файлы позволяют MySQL поддержать безопасные соединения, используя SSL. См. раздел 7.4.4.

Файлы ключа RSA позволяют MySQL поддержать безопасный обмен паролями по незашифрованным соединениям для учетных записей, заверенных плагином sha256_password, см. раздел 7.5.1.2.

7.4.6.1. Создание использование сертификатов и ключей SSL и RSA

MySQL обеспечивает два способа создать сертификат и ключевые файлы SSL и файлы ключевой пары RSA, требуемые, чтобы поддерживать безопасные соединения, используя SSL и безопасный обмен паролями, использующий RSA по незашифрованным соединениям, если те файлы отсутствуют:

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

Автоматическое создание файлов SSL и RSA

У серверов MySQL есть способность автоматического производства файлов SSL и RSA при запуске, для дистрибутивов MySQL, собранных, используя OpenSSL. Переменные auto_generate_certs и sha256_password_auto_generate_rsa_keys управляют автоматическим созданием этих файлов. Обе переменные включены по умолчанию. Их можно включить при запуске, но нельзя установить во время выполнения.

При запуске сервер автоматически производит сертификат SSL и ключевые файлы для клиента и сервера в каталоге данных, если включена auto_generate_certs , никакие опции SSL, кроме --ssl не заданы и файлы SSL сервера отсутствуют в каталоге данных. Эти файлы включают безопасные соединения клиента, используя SSL, см. раздел 7.4.4.

  1. Сервер проверяет каталог данных на файлы SSL со следующими именами:

    ca.pem
    server-cert.pem
    server-key.pem
    
  2. Если какой-либо из тех файлов присутствует, сервер не создает файлов SSL. Иначе это создает их плюс некоторые дополнительные файлы:
    ca.pem          Self-signed CA certificate
    ca-key.pem      CA private key
    server-cert.pem Server certificate
    server-key.pem  Server private key
    client-cert.pem Client certificate
    client-key.pem  Client private key
    
  3. Если сервер создает файлы SSL, он использует названия ca.pem, server-cert.pem и server-key.pem, чтобы установить соответствующие системные переменные (ssl_ca, ssl_cert и ssl_key).

При запуске сервер автоматически производит частные/общественные файлы ключевой пары RSA в каталоге данных, если включена переменная sha256_password_auto_generate_rsa_keys, никакие опции RSA не определены, и файлы RSA отсутствуют в каталоге данных. Эти файлы включают безопасный обмен паролями, использующий RSA по незашифрованным соединениям для учетных записей, заверенных плагином sha256_password, см. раздел 7.5.1.2.

  1. Сервер проверяет каталог данных на файлы RSA со следующими именами:

    private_key.pem Private member of private/public key pair
    public_key.pem  Public member of private/public key pair
    
  2. Если какой-либо из этих файлов присутствует, сервер не создает файлов RSA. Иначе это создает их.
  3. Если сервер создает файлы RSA, он использует их имена, чтобы установить соответствующие системные переменные ( sha256_password_private_key_path, sha256_password_public_key_path).

Ручное создание файлов SSL и RSA, используя mysql_ssl_rsa_setup

MySQL включает mysql_ssl_rsa_setup, которая может быть вызвана вручную, чтобы произвести файлы SSL и RSA. Эта утилита включена во все дистрибутивы MySQL, но это действительно требует, чтобы доступной команды openssl. Для инструкций использования см. раздел 5.4.3.

Характеристики файлов SSL и RSA

Файлы SSL и RSA, создаваемые автоматически сервером или вызывая mysql_ssl_rsa_setup имеют эти характеристики:

Чтобы видеть содержание сертификата SSL (например, чтобы проверить диапазон дат, по которым это допустимо), вызовите openssl:

shell> openssl x509 -text -in ca.pem
shell> openssl x509 -text -in server-cert.pem
shell> openssl x509 -text -in client-cert.pem
Также возможно проверить информацию об истечении сертификата SSL, используя этот запрос SQL:
mysql> SHOW STATUS LIKE 'Ssl_server_not%';
+-----------------------+--------------------------+
| Variable_name         | Value                    |
+-----------------------+--------------------------+
| Ssl_server_not_after  | Apr 28 14:16:39 2025 GMT |
| Ssl_server_not_before | May  1 14:16:39 2015 GMT |
+-----------------------+--------------------------+

7.4.6.2. Создание сертификатов и ключей SSL, используя openssl

Этот раздел описывает, как использовать openssl , чтобы настроить сертификат SSL и ключевые файлы для использования серверами MySQL и клиентами. Первый пример показывает упрощенную процедуру, такую как, Вы могли бы использовать из командной строки. Второй показывает сценарий, который содержит больше деталей. Первые два примера предназначены для использования в Unix и оба используют openssl как часть OpenSSL. Третий пример описывает, как настроить файлы SSL в Windows.

Есть более легкие альтернативы производства файлов, требуемых для SSL, чем процедура, описанная здесь: позвольте серверу сгенерировать их или использовать mysql_ssl_rsa_setup, см. раздел 7.4.6.1.

Безотносительно метода, который Вы используете, чтобы произвести сертификат и ключевые файлы, значение Common Name, используемое для сервера и свидетельств/ключей клиента, должно отличаться от значения Common Name, используемого для сертификата CA. Иначе сертификат и ключевые файлы не будут работать на сервере, собранном, используя OpenSSL. Типичная ошибка в этом случае:

ERROR 2026 (HY000): SSL connection error:
error:00000001:lib(0):func(0):reason(1)
Пример 1: Создание файлов SSL из командной строки в Unix

Следующий пример показывает ряд команд, чтобы создать сертификат и ключевые файлы клиента и сервера. Вы должны будете ответить на несколько подсказок openssl. Чтобы произвести испытательные файлы, Вы можете нажать Enter на все подсказки. Чтобы произвести файлы для производственного использования, Вы должны обеспечить непустые ответы.

# Create clean environment
shell> rm -rf newcerts
shell> mkdir newcerts && cd newcerts

# Create CA certificate
shell> openssl genrsa 2048 > ca-key.pem
shell> openssl req -new -x509 -nodes -days 3600 \
                  -key ca-key.pem -out ca.pem

# Create server certificate, remove passphrase, and sign it
# server-cert.pem = public key, server-key.pem = private key
shell> openssl req -newkey rsa:2048 -days 3600 \
                  -nodes -keyout server-key.pem -out server-req.pem
shell> openssl rsa -in server-key.pem -out server-key.pem
shell> openssl x509 -req -in server-req.pem -days 3600 \
                  -CA ca.pem -CAkey ca-key.pem -set_serial 01 \
                  -out server-cert.pem

# Create client certificate, remove passphrase, and sign it
# client-cert.pem = public key, client-key.pem = private key
shell> openssl req -newkey rsa:2048 -days 3600 \
                  -nodes -keyout client-key.pem -out client-req.pem
shell> openssl rsa -in client-key.pem -out client-key.pem
shell> openssl x509 -req -in client-req.pem -days 3600 \
                  -CA ca.pem -CAkey ca-key.pem -set_serial 01 \
                  -out client-cert.pem
После производства сертификатов проверьте их:
shell> openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Чтобы видеть содержание сертификата (например, проверить диапазон дат, по которым сертификат допустим), вызовите openssl:
shell> openssl x509 -text -in ca.pem
shell> openssl x509 -text -in server-cert.pem
shell> openssl x509 -text -in client-cert.pem
Теперь у Вас есть ряд файлов, которые могут использоваться следующим образом:

См. раздел 7.4.4.

Пример 2: Создание файлов SSL, используя скрипт в Unix

Вот скрипт в качестве примера, который показывает, как настроить сертификат SSL и ключевые файлы для MySQL. После выполнения скрипта используйте файлы для соединений SSL как описано в разделе 7.4.4.

DIR=`pwd`/openssl
PRIV=$DIR/private

mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf

# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)
touch $DIR/index.txt
echo "01" > $DIR/serial

#
# Generation of Certificate Authority(CA)
#
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/ca.pem \
        -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, раздел) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:

#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
$DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, раздел) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key
#
openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

# Sign server cert
#
openssl ca -cert $DIR/ca.pem -policy policy_anything \
        -out $DIR/server-cert.pem -config $DIR/openssl.cnf \
        -infiles $DIR/server-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName :PRINTABLE:'FI'
# organizationName:PRINTABLE:'MySQL AB'
# commonName:PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
$DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, раздел) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

#
# Sign client cert
#
openssl ca -cert $DIR/ca.pem -policy policy_anything \
        -out $DIR/client-cert.pem -config $DIR/openssl.cnf \
        -infiles $DIR/client-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName :PRINTABLE:'FI'
# organizationName:PRINTABLE:'MySQL AB'
# commonName:PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create a my.cnf file that you can use to test the certificates
#
cat <<EOF > $DIR/my.cnf
[client]
ssl-ca=$DIR/ca.pem
ssl-cert=$DIR/client-cert.pem
ssl-key=$DIR/client-key.pem
[mysqld]
ssl-ca=$DIR/ca.pem
ssl-cert=$DIR/server-cert.pem
ssl-key=$DIR/server-key.pem
EOF
Пример 3: Создание файлов SSL в Windows

Загрузите OpenSSL для Windows, если это не установлено в Вашей системе. Краткий обзор доступных пакетов может быть найден на:


http://www.slproweb.com/products/Win32OpenSSL.html
Выберите Win32 OpenSSL Light или Win64 OpenSSL Light, в зависимости от Вашей архитектуры (32-битовый или 64-битовый). Местоположение установки по умолчанию будет C:\OpenSSL-Win32 или C:\OpenSSL-Win64. Следующие инструкции принимают местоположение по умолчанию C:\OpenSSL-Win32.

Если сообщение происходит во время указания установки '...critical component is missing: Microsoft Visual C++ 2008 Redistributables', отмените установку и загрузите один из следующих пакетов также, снова в зависимости от Вашей архитектуры (32-битовый или 64-битовый):

После установки дополнительного пакета, перезапустите процедуру установки OpenSSL.

Во время установки оставьте значение по умолчанию C:\OpenSSL-Win32 как путь установки, а также опцию по умолчанию 'Copy OpenSSL DLL files to the Windows system directory'.

Когда установка закончилась, надо добавить C:\OpenSSL-Win32\bin в Windows System Path:

  1. На рабочем столе кликните правой кнопкой мыши по My Computer и выберите Properties.

  2. Выберите вкладку Advanced из меню System Properties и там нажмите кнопку Environment Variables.
  3. В System Variables выберите Path, кликните по Edit. Появится диалог Edit System Variable.
  4. Добавьте в конец ';C:\OpenSSL-Win32\bin' (обратите внимание на точку с запятой!).
  5. Трижды нажмите OK.
  6. Проверьте, что OpenSSL был правильно объединен в переменную Path, открывая новую консоль (Start>Run>cmd.exe ) и проверяя, что OpenSSL доступен:
    Microsoft Windows [Version ...]
    Copyright (c) 2006 Microsoft Corporation. All rights reserved.
    
    C:\Windows\system32>cd \
    
    C:\>openssl
    OpenSSL> exit <<< If you see the OpenSSL prompt,
    installation was successful.
    
    C:\>
    

В зависимости от Вашей версии Windows предыдущие устанавливающие путь инструкции могли бы отличаться немного.

После того, как OpenSSL был установлен, используйте инструкции, подобные тем, которые даны в примере 1 (показан ранее в этом разделе), со следующими изменениями:

После производства сертификата и ключевых файлов, чтобы использовать их для соединений SSL см. раздел 7.4.4.

7.4.6.3. Создание ключей RSA, используя openssl

Этот раздел описывает, как использовать openssl , чтобы настроить файлы ключа RSA, которые позволяют MySQL поддержать безопасный обмен паролями по незашифрованным соединениям для учетных записей, заверенных плагином sha256_password.

Есть более легкие альтернативы производству файлов, требуемых для RSA, чем процедура, описанная здесь: позвольте серверу сгенерировать их или использовать mysql_ssl_rsa_setup, см. раздел 7.4.6.1.

Чтобы создать файлы пары ключа RSA, выполните эти команды в то время, как зарегистрированы в системе как учетная запись, которая выполняет сервер MySQL, таким образом, файлы будут принадлежать той учетной записи:

openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
Эти команды создают 2048-битовые ключи. Чтобы создать более сильные ключи, используйте большее значение.

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

chmod 400 private_key.pem
chmod 444 public_key.pem

7.4.7. Соединение с MySQL из Windows по SSH

Этот раздел описывает, как получить безопасное соединение с удаленным сервером MySQL с SSH. Информация была предоставлена David Carlson <dcarlson@mplcomm.com >.

  1. Установите клиент SSH на своей машине Windows. Для сравнения клиентов SSH см. http://en.wikipedia.org/wiki/Comparison_of_SSH_clients.

  2. Запустите свой Windows-клиент SSH. Установите Host_Name = yourmysqlserver_URL_or_IP. Установите userid=your_userid, чтобы входить в систему к Вашему серверу. Это значение userid не должно бы быть тем же самым, как имя пользователя Вашей учетной записи MySQL.
  3. Настройте перенаправление портов. Либо удаленное перенаправление (local_port: 3306, remote_host: yourmysqlservername_or_ip, remote_port: 3306), либо локальное перенаправление (port: 3306, host: localhost, remote port: 3306).
  4. Сохраните все, иначе Вы должны будете сделать заново это в следующий раз.
  5. Войдите в систему сервера с сеансом SSH, который Вы только что создали.
  6. На Вашей машине Windows, запустите некоторое приложение ODBC (такое как Access).
  7. Создайте новый файл в Windows и свяжите с MySQL, используя драйвер ODBC тем же самым путем, как Вы обычно делаете, указав localhost для сервера MySQL, а не yourmysqlservername .

В этом пункте у Вас должно быть соединение ODBC с MySQL, зашифрованное использованием SSH.

7.5. Плагины безопасности

MySQL включает несколько плагинов, которые осуществляют механизмы безопасности:

7.5.1. Плагины аутентификации

Следующие разделы описывают плагины аутентификации, доступные в MySQL.

Плагин по умолчанию mysql_native_password, если системная переменная default_authentication_plugin не установлена иначе.

7.5.1.1. Родной плагин аутентификации

MySQL включает плагин mysql_native_password, который осуществляет родную аутентификацию, то есть, аутентификация для паролей, сохраненных в столбце authentication_string таблицы mysql.user.

Следующая таблица показывает плагина на сторонах сервера и клиента.

Таблица 7.9. Плагин аутентификации пароля MySQL

Имя плагина сервера mysql_native_password
Имя плагина клиентаmysql_native_password
БиблиотекаНет (встроенный плагин)

Плагин существует в обеих формах клиента и сервера:

Если строка учетной записи не определяет имени плагина, сервер игнорирует учетную запись.

См. раздел 7.3.9.

7.5.1.2. Плагин аутентификации SHA-256

MySQL обеспечивает плагин аутентификации, который осуществляет SHA-256, хеширующий пароли учетной записи пользователя.

Соединяться с сервером, используя учетную запись, которая подтверждает подлинность с плагином sha256_password можно, используя соединение SSL или незашифрованное соединение, которое шифрует пароль, используя RSA, как описано позже в этом разделе. Так или иначе, использование плагина sha256_password требует, чтобы MySQL был собран с SSL. См. раздел 7.4.

Следующая таблица показывает имена плагина на сторонах сервера и клиента.

Таблица 7.10. Плагин аутентификации MySQL SHA-256

Имя плагина сервераsha256_password
Имя плагина клиентаsha256_password
БиблиотекаНет (встроенный плагин)

Сторона сервера плагина sha256_password встроена в сервер, не должна быть загружена явно и не может быть отключена, выгружая его. Точно так же клиенты не должны определить местоположение клиентского плагина.

Чтобы настраивать учетную запись, которая использует плагин sha256_password для хеширования пароля по SHA-256, используйте следующий запрос:

CREATE USER 'sha256user'@'localhost'
       IDENTIFIED WITH sha256_password BY 'Sh@256Pa33';
Альтернативно, запустите сервер с плагином аутентификации по умолчанию, установленным в sha256_password. Например, поместите эти строки в файл параметров сервера:
[mysqld]
default_authentication_plugin=sha256_password
Это вызывает плагин sha256_password, который будет использоваться по умолчанию для новых учетных записей. В результате возможно создать учетную запись и установить ее пароль, не называя плагин явно, используя CREATE USER:
CREATE USER 'sha256user'@'localhost' IDENTIFIED BY 'Sh@256Pa33';
В этом случае сервер назначает плагин sha256_password учетной записи и шифрует пароль, используя SHA-256.

Учетные записи в mysql.user, которые используют пароли SHA-256, могут быть идентифицированы как строки с 'sha256_password' в столбце plugin и хешем пароля SHA-256 в столбце authentication_string.

Другое последствие использования sha256_password как плагин аутентификации по умолчанию: чтобы создать учетную запись, которая использует отличный плагин, Вы должны определить плагин, используя IDENTIFIED WITH в CREATE USER. Например, чтобы использовать плагин mysql_native_password используйте этот запрос:

CREATE USER 'nativeuser'@'localhost'
       IDENTIFIED WITH mysql_native_password BY 'N@tivePa33';
MySQL может быть собран, используя OpenSSL или yaSSL (см. раздел 7.4.1). Плагин sha256_password работает с дистрибутивами, собранными, используя любой пакет, но если MySQL собран, используя OpenSSL, шифрование RSA доступно, и sha256_password осуществляет следующие дополнительные способности. Чтобы включить эти способности, Вы должны также следовать за процедурой конфигурации RSA, данной позже в этом разделе.

Для клиентов, которые используют плагин sha256_password, пароли никогда не выставляются как открытый текст, соединяясь с сервером. То, как передача пароля происходит, зависит от того, используется ли соединение SSL и доступно ли шифрование RSA:

Как упомянуто ранее, шифрование пароля RSA доступно, только если MySQL был собран, используя OpenSSL. Значение для дистрибутивов MySQL, собранных, используя yaSSL: пароли SHA-256 могут использоваться только, когда клиенты используют SSL, чтобы получить доступ к серверу. См. раздел 7.4.4.

Предполагая, что MySQL был собран, используя OpenSSL, следующая процедура описывает, как включить шифрование RSA паролей во время процесса соединения клиента:

  1. Создайте файлы пары открытого ключа RSA, используя инструкции в разделе 7.4.6.

  2. Если файлы частного и открытого ключа расположены в каталоге данных и названы private_key.pem и public_key.pem (значения по умолчанию системных переменных sha256_password_private_key_path и sha256_password_public_key_path), сервер будет использовать их автоматически при запуске.

    Иначе в файле параметров сервера установите системные переменные в ключевые имена файла. Если файлы расположены в каталоге серверных данных, Вы не должны определить их полные пути:

    [mysqld]
    sha256_password_private_key_path=myprivkey.pem
    sha256_password_public_key_path=mypubkey.pem
    
    Если ключевые файлы не расположены в каталоге данных, используйте полные пути
    [mysqld]
    sha256_password_private_key_path=/usr/local/mysql/myprivkey.pem
    sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem
    
  3. Перезапустите сервер, затем соединитесь с ним и проверьте переменную Rsa_public_key. Значение будет отличаться от показанного здесь, но должно быть непустым:
    mysql> SHOW STATUS LIKE 'Rsa_public_key'\G
    *************************** 1. row ***************************
    Variable_name: Rsa_public_key
    Value: -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd+KvSZgY7cNBZMNpwX6
    MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa
    aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
    g8aV7EtKwyhHb0c30QIDAQAB
    -----END PUBLIC KEY-----
    
    Если значение пусто, сервер нашел некоторую проблему с ключевыми файлами. Проверьте журнал ошибок на диагностическую информацию.

После того, как сервер был сконфигурирован с файлами ключа RSA, у клиентов есть опция использования их, чтобы соединиться с сервером, используя учетные записи, которые подтверждают подлинность с плагином sha256_password. Как упомянуто ранее, такие учетные записи могут использовать любое соединение SSL (когда RSA не используется) или незашифрованное соединение, которое шифрует пароль, используя RSA. Предположите для следующего обсуждения, что SSL не используется. Соединение с сервером не требует специальной подготовки на стороне клиента. Например:

shell> mysql --ssl-mode=DISABLED -u sha256user -p
Enter password: Sh@256Pa33
Поскольку соединение пытается использовать sha256user, сервер определяет, что sha256_password соответствующий плагин аутентификации и вызывает это. Плагин находит, что соединение не использует SSL и таким образом требует, чтобы пароль был передан, используя шифрование RSA. В этом случае плагин посылает открытый ключ RSA клиенту, который использует его, чтобы зашифровать пароль, и возвращает результат серверу. Использование плагина RSA включает сторону сервера, чтобы дешифровать пароль, и принимает или отклоняет соединение, основываясь на том, правилен ли пароль.

Сервер посылает открытый ключ клиенту, но если копия открытого ключа RSA доступна на хосте клиента, клиент может использовать это, чтобы сохранить передачу туда и обратно в протоколе клиент-сервер:

shell> mysql --ssl-mode=DISABLED -u sha256user -p --server-public-key-path=file_name
Значение открытого ключа в файле, указанном опцией --server-public-key-path должно быть тем же самым, как значение ключа в серверном файле, названном в переменной sha256_password_public_key_path. Если ключевой файл содержит допустимое значение открытого ключа, но значение является неправильным, происходит ошибка доступа. Если ключевой файл не содержит допустимый открытый ключ, программа клиента не может использовать его. В этом случае плагин sha256_password посылает открытый ключ клиенту как будто нет опции --server-public-key-path.

Пользователи клиента могут получить открытый ключ RSA двумя способами:

7.5.1.3. Плагин аутентификации без логина

Плагин mysql_no_login предотвращает все соединения клиента с любой учетной записью, которая использует его. Случаи использования для такого плагина включают учетные записи, которые должны быть в состоянии выполнить сохраненные программы и представления с поднятыми привилегиями, не выставляя те привилегии обычным пользователям, и учетные записи по доверенности, которые никогда не должны разрешать прямой вход в систему.

Следующая таблица показывает имена файла библиотеки и плагина. Суффикс имени файла может отличаться в Вашей системе. Местоположение файла это каталог, названный в переменной plugin_dir. См. раздел 7.3.9.

Таблица 7.11. Плагин MySQL No Login

Имя плагина сервера mysql_no_login
Имя плагина клиентаНет
Библиотекаmysql_no_login.so

Учетная запись, которая подтверждает подлинность с использованим mysql_no_login, может использоваться в качестве DEFINER для сохраненной программы и объектов представления. Если такое определение объекта также включает SQL SECURITY DEFINER, это выполняется с привилегиями соответствующей учетной записи. DBA может использовать это поведение, чтобы обеспечить доступ к конфиденциальным или уязвимым данным, которые выставлены только через хорошо управляемые интерфейсы.

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

CREATE DATABASE nologindb;
CREATE USER 'nologin'@'localhost' IDENTIFIED WITH mysql_no_login;
GRANT ALL ON nologindb.* TO 'nologin'@'localhost';
GRANT SELECT ON mysql.user TO 'nologin'@'localhost';
CREATE DEFINER = 'nologin'@'localhost' SQL SECURITY DEFINER
       VIEW nologindb.myview AS SELECT User, Host FROM mysql.user;
Чтобы обеспечить защищенный доступ к представлению об обычных пользователях, сделайте это:
GRANT SELECT ON nologindb.myview TO 'ordinaryuser'@'localhost';
Теперь обычный пользователь может использовать представление, чтобы получить доступ к ограниченной информации, которую оно представляет:
SELECT * FROM nologindb.myview;
Попытки пользователя получить доступ к столбцам кроме выставленных представлением приводят к ошибке.

Поскольку учетная запись nologin не может использоваться непосредственно, операции, требуемые, чтобы настраивать объекты, которые она использует, должны быть выполнены root или подобной учетной записью с привилегиями, требуемыми, чтобы создать объекты и установить DEFINER.

Учетная запись, которая подтверждает подлинность с использованием mysql_no_login, может использоваться в качестве основного пользователя для учетных записей по доверенности:

CREATE USER 'proxy_base'@'localhost' IDENTIFIED WITH mysql_no_login;
... grant to 'proxy_base'@'localhost' any privileges it requires ...
GRANT PROXY ON 'proxy_base'@'localhost' TO 'real_user'@'localhost';
Это позволяет клиентам получить доступ к MySQL через учетную запись по доверенности, но не обойти механизм доверенности, соединяясь непосредственно как пользователь по доверенности.

См. разделы 7.3.9 и 7.3.10.

7.5.1.4. Клиентский плагин аутентификации открытого текста

Клиентский плагин аутентификации посылает пароль в сервер, не хешируя или шифруя. Этот плагин встроен в библиотеку клиента MySQL.

Таблица 7.12. Плагин аутентификации открытого текста MySQL

Имя плагина сервераОтсутствует
Имя плагина клиента mysql_clear_password
БиблиотекаНет (встроенный плагин)

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

Одностороннее хеширование не может быть сделано для схем аутентификации, которые требуют, чтобы сервер получил пароль как сторона клиента. В таких случаях клиентский плагин mysql_clear_password может использоваться, чтобы послать пароль в сервер открытым текстом. Нет никакого соответствующего серверного плагина. Скорее клиентский плагин может использоваться любым серверным плагином, который нуждается в пароле открытого текста. Плагин аутентификации PAM именно такой, см. The PAM Authentication Plugin.

См. раздел 7.3.9.

Посылка паролей в открытом тексте может быть проблемой безопасности в некоторых конфигурациях. Чтобы избежать проблем, если есть возможность, клиенты должны соединиться с MySQL Server используя метод, который защищает пароль. Возможности включают SSL (см. раздел 7.4), IPsec или частную сеть.

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

7.5.1.5. Плагин аутентификации сокета

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

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

Таблица 7.13. Плагин авторизации MySQL Socket

Имя плагина сервера auth_socket
Имя плагина клиентаНет
Библиотекаauth_socket.so

Плагин аутентификации auth_socket подтверждает подлинность клиентов, которые соединяются от местного узла через файл сокета Unix. Плагин использует опцию сокета SO_PEERCRED, чтобы получить информацию о пользователе, выполняющем программу клиента. Таким образом, плагин может быть создан только на системах, которые поддерживают опцию SO_PEERCRED, например, Linux.

Плагин проверяет, соответствует ли имя пользователя сокета имени пользователя MySQL, определенному программой клиента серверу. Если имена не соответствуют, плагин также проверяет, соответствует ли имя пользователя имени, определенному в столбце authentication_string таблицы mysql.user. Если соответствие найдено, плагин разрешает соединение.

Предположите, что учетная запись MySQL создается для пользователя valerie, который должен быть заверен плагином auth_socket для соединений от местного узла к файлу сокета:

CREATE USER 'valerie'@'localhost' IDENTIFIED WITH auth_socket;
Если пользователь на местном узле с именем для входа в систему stefanie вызывает mysql с опцией --user=valerie, чтобы соединяться через файл сокета, сервер с помощью auth_socket подтверждает подлинность клиента. Плагин решает, что значение опции --user (valerie) отличается от имени пользователя клиента (stephanie) и отказывается от соединения. Если пользователь valerie пробует ту же самую вещь, плагин находит, что имя пользователя и имя пользователя MySQL оба valerie и разрешает соединение. Однако, плагин отказывается от соединения даже для valerie, если соединение сделано, используя различный протокол, такой как TCP/IP.

См. раздел 7.3.9.

7.5.1.6. Испытательный плагин аутентификации

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

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

Таблица 7.14. Испытательный плагин аутентификации MySQL

Имя плагина сервера test_plugin_server
Имя плагина клиента auth_test_plugin
Библиотекаauth_test_plugin.so

Поскольку испытательный плагин подтверждает подлинность так же, как аутентификация MySQL, обеспечьте обычные опции --user и --password, которые Вы обычно используете для учетных записей, которые используют родную аутентификацию, когда Вы соединяетесь с сервером. Например:

shell> mysql --user=your_name --password=your_pass
См. раздел 7.3.9.

7.5.2. Плагин проверки допустимости пароля

Плагин validate_password служит, чтобы проверить пароли и улучшить безопасность. Плагин выставляет ряд системных переменных, которые позволяют Вам определить политику пароля.

Этот плагин осуществляет две способности:

Например, пароль открытого текста в следующем запросе проверен. Под политикой пароля значения по умолчанию, которая требует, чтобы пароли были по крайней мере 8 символов в длину, пароль слаб, и запрос производит ошибку:

mysql> ALTER USER USER() IDENTIFIED BY 'abc';
ERROR 1819 (HY000): Your password does not satisfy the current
policy requirements
Пароли, определенные как хешированные значения, не проверены, потому что оригинальное значение пароля недоступно:
mysql> ALTER USER 'jeffrey'@'localhost'
    ->       IDENTIFIED WITH mysql_native_password
    ->       AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E';
Query OK, 0 rows affected (0.01 sec)
Системные переменные, имеющие названия формы validate_password_xxx представляют параметры политики управления паролем. Чтобы сконфигурировать проверку пароля, измените эти переменные, см. раздел 7.5.2.2 .

Если validate_password не установлен, переменные validate_password_xxx недоступны, пароли в запросах не проверены, и VALIDATE_PASSWORD_STRENGTH() всегда возвращает 0. Например, без установленного плагина, учетным записям могут быть назначены пароли короче 8 символов.

Плагин validate_password осуществляет три уровня проверки пароля: LOW, MEDIUM и STRONG. Значение по умолчанию MEDIUM, чтобы изменить это, измените значение validate_password_policy. Политика осуществляет все более и более строгие тесты пароля. Следующие описания относятся к значениям параметра по умолчанию, которые могут быть изменены, меняя соответствующие системные переменные.

Кроме того, validate_password поддерживает способность отклонения паролей, которые соответствуют части имени пользователя эффективной учетной записи пользователя текущего сеанса. Чтобы включить управление этой способностью, плагин выставляет переменную validate_password_check_user_name. По умолчанию эта переменная включена.

7.5.2.1. Установка плагина проверки допустимости пароля

Этот раздел описывает, как установить validate_password.

Чтобы быть применимым сервером, файл библиотеки должен быть расположен в каталоге плагинов MySQL (каталог, названный в переменной plugin_dir). В случае необходимости установите значение plugin_dir при запуске сервера, чтобы сказать серверу местоположение каталога.

Базовое имя файла библиотеки validate_password.

Чтобы загрузить плагин при запуске сервера, используйте опцию --plugin-load , чтобы назвать файл библиотеки, который содержит плагин. С этим загружающим плагин методом опция должна быть дана каждый раз, когда сервер запускается. Например, вставьте эти строки в Ваш файл my.cnf:

[mysqld]
plugin-load=validate_password.so
Альтернативно, чтобы зарегистрировать плагин во время выполнения, используйте это запрос (скорректируйте расширение по мере необходимости):
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
INSTALL PLUGIN загружает плагин, а также регистрирует это в таблице mysql.plugins, чтобы заставить плагин загружаться для каждого последующего нормального запуска сервера.

Чтобы проверить установку, исследуйте таблицу INFORMATION_SCHEMA.PLUGINS или используйте команду SHOW PLUGINS (см. раздел 6.6.3). Например:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
    ->        WHERE PLUGIN_NAME LIKE 'validate%';
+-------------------+---------------+
| PLUGIN_NAME       | PLUGIN_STATUS |
+-------------------+---------------+
| validate_password | ACTIVE        |
+-------------------+---------------+
Если плагин был ранее зарегистрирован INSTALL PLUGIN или загружен --plugin-load, Вы можете использовать опцию --validate-password при запуске сервера, чтобы управлять активацией. Например, чтобы загрузить плагин при запуске и препятствовать тому, чтобы это было удалено во времени выполнения, используйте эти опции:
[mysqld]
plugin-load=validate_password.so
validate-password=FORCE_PLUS_PERMANENT
Если надо препятствовать тому, чтобы сервер работал без плагина проверки допустимости пароля, следует использовать --validate-password со значением FORCE или FORCE_PLUS_PERMANENT.

7.5.2.2. Опции и переменные плагина проверки допустимости пароля

Управлять активацией validate_password можно через опцию:

Если validate_password включен, он выставляет несколько системных переменных, представляющих параметры, которые управляют проверкой пароля:

mysql> SHOW VARIABLES LIKE 'validate_password%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | ON     |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
Чтобы изменить, как пароли проверены, Вы можете установить эти системные переменные при запуске сервера или во время выполнения. Следующий список описывает значение каждой переменной.

Если validate_password включен, он выставляет переменные состояния, которые предоставляют операционную информацию:

mysql> SHOW STATUS LIKE 'validate_password%';
+-----------------------------------------------+---------------------+
| Variable_name                                 | Value               |
+-----------------------------------------------+---------------------+
| validate_password_dictionary_file_last_parsed | 2015-06-29 11:08:51 |
| validate_password_dictionary_file_words_count | 1902                |
+-----------------------------------------------+---------------------+
Следующий список описывает значение каждой переменной состояния.

7.5.3. Брелок MySQL

MySQL Server поддерживает службу брелока, которая позволяет внутренним серверным компонентам и плагинам надежно хранить чувствительную информацию для более позднего извлечения. Выполнение основано на плагине:

InnoDB использует плагин брелока, чтобы сохранить ключ для шифрования табличного пространства.

См. раздел 7.5.3.1.

См. раздел 7.5.3.3.

7.5.3.1. Установка плагина брелока

Этот раздел описывает, как установить плагин брелока. Для общей информации об установке плагинов см. раздел 6.6.2.

Чтобы быть применимым сервером, файл библиотеки должен быть расположен в каталоге плагина MySQL (каталог, названный в переменной plugin_dir). В случае необходимости установите значение plugin_dir при запуске сервера, чтобы сказать серверу местоположение каталога.

Только один плагин брелока должен быть включен за один раз. Включение многих плагинов брелока не поддержано, и результаты, возможно, не будут правильными.

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

Базовое имя файла библиотеки keyring_file.

Чтобы загрузить плагин, используйте опцию --early-plugin-load, чтобы назвать файл библиотеки. Например, на платформах, где суффикс файла библиотеки .so, используйте эти строки в серверном файле my.cnf:

[mysqld]
early-plugin-load=keyring_file.so
Прежде чем запустить сервер, проверьте примечания на свой выбранный плагин брелока, чтобы видеть, требует ли он дополнительной конфигурации, см. раздел 7.5.3.2.

После выполнения любой определенной для плагина конфигурации, запустите сервер. Чтобы проверить установку, исследуйте таблицу INFORMATION_SCHEMA.PLUGINS или используйте SHOW PLUGINS (см. раздел 6.6.3):

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS
    ->        WHERE PLUGIN_NAME LIKE 'keyring%';
+--------------+---------------+
| PLUGIN_NAME  | PLUGIN_STATUS |
+--------------+---------------+
| keyring_file | ACTIVE        |
+--------------+---------------+
Если никакой плагин брелока не доступен, когда серверный компонент пытается получить доступ к службе брелока, служба не может использоваться тем компонентом. В результате компонент может быть не в состоянии инициализироваться или может инициализироваться с ограниченной функциональностью. Например, если InnoDB находит, что есть зашифрованные табличные пространства, когда это инициализируется, это пытается получить доступ к брелоку. Если брелок недоступен, InnoDB может получить доступ только к незашифрованным табличным пространствам. Чтобы гарантировать, что InnoDB может получить доступ к зашифрованным табличным пространствам также, надо использовать --early-plugin-load, чтобы загрузить плагин брелока.

Плагины могут быть загружены другими методами, такими как опция --plugin-load или --plugin-load-add или запрос INSTALL PLUGIN. Однако, плагины брелока, загруженные с использованием тех методов, могут быть доступны слишком поздно в последовательности запуска сервера для определенных серверных компонентов, таких как InnoDB:

7.5.3.2. Конфигурирование keyring_file

Плагин keyring_file это плагин брелока, который хранит данные брелока в файле, местном для узла сервера.

Чтобы использовать keyring_file, используйте общие инструкции по установке в раздел 7.5.3.1, вместе с определенной для плагина информацией о конфигурации.

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

[mysqld]
early-plugin-load=keyring_file.so
keyring_file_data=/usr/local/mysql/mysql-keyring/keyring
Операции брелока являются транзакционными: плагин использует резервный файл во время записи, чтобы гарантировать, что он может откатиться назад к оригинальному файлу, если работа потерпит неудачу. У резервного файла есть то же самое имя, как у значения keyring_file_data с расширением .backup.

См. раздел 6.1.5.

7.5.3.3. Функции ключевого менеджмента брелока

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

MySQL Server также включает интерфейс SQL для ключевого менеджмента брелока, осуществленного как ряд определяемых пользователем функций (UDF), которые получают доступ к функциям, обеспеченным внутренней службой брелока. UDF брелока содержатся в файле библиотеки, который также содержит плагин keyring_udf, который должен быть включен до вызова UDF. Кроме того, плагин брелока keyring_file должен быть включен.

7.5.3.3.1. Установка или удаление функций брелока

UDF включают операции ключевого менеджмента брелока, но плагин keyring_udf должен также быть установлен, потому что UDF не будет работать правильно без него. Попытки использовать UDF без keyring_udf приводят к ошибке.

Базовое имя файла библиотеки keyring_udf.

Чтобы установить keyring_udf и UDF, используйте INSTALL PLUGIN и CREATE FUNCTION:

INSTALL PLUGIN keyring_udf SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_generate RETURNS INTEGER SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_fetch RETURNS STRING SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_type_fetch RETURNS STRING SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_store RETURNS INTEGER SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_remove RETURNS INTEGER SONAME 'keyring_udf.so';
Если плагин и UDF используются на основном сервере репликации, их ставят также на всех ведомых серверах, чтобы избежать проблем.

После того, как установлен, как только что описано, плагин keyring_udf и UDF остаются установленными пока не удалены. Чтобы удалить их, используйте UNINSTALL PLUGIN и DROP FUNCTION:

UNINSTALL PLUGIN keyring_udf;
DROP FUNCTION keyring_key_generate;
DROP FUNCTION keyring_key_fetch;
DROP FUNCTION keyring_key_length_fetch;
DROP FUNCTION keyring_key_type_fetch;
DROP FUNCTION keyring_key_store;
DROP FUNCTION keyring_key_remove;
7.5.3.3.2. Используя функции брелока

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

UDF подвергаются этим ограничениям:

Чтобы создать новый случайный ключ и сохранить это в брелоке, вызовите keyring_key_generate(), передавая этому ID для ключа, наряду с ключевым типом (методом шифрования) и его длиной в байтах. Следующее требование создает 2048-битовый ключ DSA-encrypted, названный MyKey:

mysql> SELECT keyring_key_generate('MyKey', 'DSA', 256);
+-------------------------------------------+
| keyring_key_generate('MyKey', 'DSA', 256) |
+-------------------------------------------+
| 1                                         |
+-------------------------------------------+
Возвращаемое значение 1 указывает на успех. Если ключ не может быть создан, возвращаемое значение NULL и ошибка происходит. Чтобы быть в состоянии проверить тип возвращения независимо от того, происходит ли ошибка, надо использовать SELECT ... INTO @var_name и проверить переменное значение:
mysql> SELECT keyring_key_generate('', '', -1) INTO @x;
ERROR 3188 (HY000): Function 'keyring_key_generate' failed because
underlying keyring service returned an error. Please check if a
keyring plugin is installed and that provided arguments are valid
for the keyring you are using.

mysql> SELECT @x;
+------+
| @x   |
+------+
| NULL |
+------+
mysql> SELECT keyring_key_generate('x', 'AES', 16) INTO @x;
mysql> SELECT @x;
+------+
| @x   |
+------+
| 1    |
+------+
Этот метод также относится к другим UDF брелока, которые возвращают NULL и ошибку для отказа.

ID, переданный keyring_key_generate(), обеспечивает средство, которым можно обратиться к ключу в последующих требованиях UDF. Например, используйте ID, чтобы получить ключевой тип как строку или длину в байтах как целое число:

mysql> SELECT keyring_key_type_fetch('MyKey');
+---------------------------------+
| keyring_key_type_fetch('MyKey') |
+---------------------------------+
| DSA                             |
+---------------------------------+

mysql> SELECT keyring_key_length_fetch('MyKey');
+-----------------------------------+
| keyring_key_length_fetch('MyKey') |
+-----------------------------------+
|   256                             |
+-----------------------------------+
Чтобы получить значение ключа, передайте ключевое ID к keyring_key_fetch(). Следующее использует в качестве примера HEX(), чтобы вывести на экран значение ключа, потому что это может содержать непригодные для печатания символы. Пример также использует короткий ключ для краткости, но надо знать, что ключи большей длины обеспечивают лучшую безопасность:
mysql> SELECT keyring_key_generate('MyShortKey', 'DSA', 8);
+----------------------------------------------+
| keyring_key_generate('MyShortKey', 'DSA', 8) |
+----------------------------------------------+
|  1                                           |
+----------------------------------------------+

mysql> SELECT HEX(keyring_key_fetch('MyShortKey'));
+--------------------------------------+
| HEX(keyring_key_fetch('MyShortKey')) |
+--------------------------------------+
| 1DB3B0FC3328A24C                     |
+--------------------------------------+
Брелок UDF обрабатывают ключевые ID, типы и значения как двоичные строки, таким образом, сравнения являются чувствительными к регистру. Например, ID MyKey и mykey это разные ключи.

Чтобы удалить ключ, передайте ключевое ID к keyring_key_remove():

mysql> SELECT keyring_key_remove('MyKey');
+-----------------------------+
| keyring_key_remove('MyKey') |
+-----------------------------+
| 1                           |
+-----------------------------+
Чтобы запутать и сохранить ключ, который Вы обеспечиваете, передайте ключевое ID, тип и значение keyring_key_store():
mysql> SELECT keyring_key_store('AES_key', 'AES', 'Secret string');
+------------------------------------------------------+
| keyring_key_store('AES_key', 'AES', 'Secret string') |
+------------------------------------------------------+
| 1                                                    |
+------------------------------------------------------+
Как обозначено ранее, у пользователя должна быть глобальная привилегия EXECUTE, чтобы вызвать UDF, и пользователь, который сохраняет ключ в брелоке первоначально, должен быть тем же самым пользователем, который выполняет последующие операции на ключе позже, как определено значением CURRENT_USER() для каждого вызова UDF. Чтобы разрешить ключевые операции пользователям, у которых нет глобальной привилегии EXECUTE или кто, возможно, не владелец ключа, используйте этот метод:

  1. Определите сохраненные программы, которые заключают в капсулу необходимые ключевые операции и имеют DEFINER равный ключевому владельцу.

  2. Предоставьте привилегию EXECUTE для определенных сохраненных программ отдельным пользователям, которые должны быть в состоянии вызвать их.
  3. Если операции, осуществленные сохраненной программой, не включают создание ключей, создайте любые необходимые ключи заранее, используя учетную запись, названную как DEFINER в определении программы.

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

Следующий пример показывает, как настроить совместно используемый ключ SharedKey, который принадлежит DBA, и сохраненную функцию get_shared_key(), которая обеспечивает доступ к текущему значению ключа. Значение может быть получено любым пользователем с привилегией EXECUTE для той функции, которая создается в схеме key_schema.

От административной учетной записи MySQL ('root'@'localhost' в этом примере), создайте административную схему и сохраненную функцию, чтобы получить доступ к ключу:

mysql> CREATE SCHEMA key_schema;
mysql> CREATE DEFINER = 'root'@'localhost'
    ->        FUNCTION key_schema.get_shared_key()
    ->        RETURNS BLOB READS SQL DATA
    -> RETURN keyring_key_fetch('SharedKey');
Из административной учетной записи, гарантируйте, что совместно используемый ключ существует:
mysql> SELECT keyring_key_generate('SharedKey', 'DSA', 8);
+---------------------------------------------+
| keyring_key_generate('SharedKey', 'DSA', 8) |
+---------------------------------------------+
| 1                                           |
+---------------------------------------------+
Из административной учетной записи, создайте обычную учетную запись пользователя, которой нужно предоставить ключевой доступ:
mysql> CREATE USER 'key_user'@'localhost'
    ->        IDENTIFIED BY 'key_user_pwd';
Из учетки key_user проверьте, что без надлежащей привилегии EXECUTE, новая учетная запись не может получить доступ к совместно используемому ключу:
mysql> SELECT HEX(key_schema.get_shared_key());
ERROR 1370 (42000): execute command denied to user 'key_user'@'localhost'
for routine 'key_schema.get_shared_key'
Из административной учетной записи дайте привилегию EXECUTE учетке key_user для сохраненной функции:
mysql> GRANT EXECUTE ON FUNCTION key_schema.get_shared_key
    ->       TO 'key_user'@'localhost';
Из учетки key_user проверьте, что ключ теперь доступен:
mysql> SELECT HEX(key_schema.get_shared_key());
+----------------------------------+
| HEX(key_schema.get_shared_key()) |
+----------------------------------+
| 9BAFB9E75CEEB013                 |
+----------------------------------+
7.5.3.3.3. Обзор функций брелока

Этот раздел описывает для каждого брелока определяемую пользователем функция (UDF), ее цель и возвращаемое значение. Для информации об условиях, при которых могут быть вызваны эти UDF, см. раздел 7.5.3.3.2.

Эти UDF доступны: