RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
YandexMoney: 
41001198119846 
E-gold:
5128052

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

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

  • Общие факторы. Они включают хорошие пароли, не предоставление ненужных привилегий пользователям, гарантирование безопасности приложения, предотвращение инъекций SQL и повреждения данных и другое. См. раздел 7.1.

  • Безопасность установки непосредственно. Файлы с данными, файлы системного журнала и все файлы приложения Вашей установки должны быть защищены, чтобы гарантировать, что они не читаемы или перезаписываемы неправомочными сторонами. Для получения дополнительной информации см. раздел 2.9.
  • Управление доступом и безопасность в пределах системы базы данных непосредственно, включая пользователей и базы данных, предоставление доступа к базам данных и сохраненные программы в пределах базы данных. Для получения дополнительной информации см. разделы 7.2 и 7.3.
  • Особенности связанных с безопасностью плагинов. См. раздел 7.5.
  • Сетевая безопасность MySQL и Вашей системы. Безопасность связана с привилегиями отдельных пользователей, но Вы можете также хотеть ограничить MySQL так, чтобы это было доступно только в местном масштабе на узле сервера MySQL или ограниченному набору других узлов.
  • Гарантируйте, что у Вас есть соответствующие резервные копии Ваших файлов базы данных, конфигурации и файлов системного журнала. Также убедитесь, что у Вас есть решение для восстановления, что Вы в состоянии успешно возвратить информацию от своих резервных копий. См. главу 8.

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

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

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

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

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

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

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

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

  • Никогда не давайте никому (кроме учетной записи MySQL root) доступ к таблице user в базе mysql! Это важно.

  • Изучите, как система привилегии доступа MySQL работает (см. раздел 7.2). Используйте GRANT и REVOKE, чтобы управлять доступом к MySQL. Не предоставляйте больше привилегий, чем необходимо. Никогда не предоставляйте привилегии всем узлам.

    • Попробуйте mysql -u root. Если Вы в состоянии соединиться успешно с сервером без пароля, любой может соединиться с Вашим сервером MySQL как MySQL root с полными привилегиями! Рассмотрите инструкции по установке MySQL, обращая особое внимание на информацию об установке пароля root, см. раздел 2.9.4.

    • Используйте SHOW GRANTS, чтобы проверить, у каких учетных записей куда есть доступ. Тогда используйте REVOKE, чтобы удалить те привилегии, которые не необходимы.

  • Не храните пароли открытого текста в своей базе данных. Злоумышленник может взять полный список паролей и использовать их. Вместо этого используйте SHA2(), SHA1(), MD5() или некоторую другую одностороннюю хеширующую функцию и храните значение хеша.

    Чтобы предотвратить восстановление пароля, используя таблицы радуги, не используйте эти функции на простом пароле, вместо этого, выберите некоторую строку, которая будет использоваться в качестве salt и используйте hash(hash(password)+salt).

  • Не выбирайте пароли из словарей. Специальные программы существуют, чтобы сломать пароли. Даже такие пароли, как xfish98, очень плохи. Намного лучше duag98, который содержит то же самое слово fish, но на одну клавишу левее на стандартной клавиатуре QWERTY. Другой метод должен использовать пароль, который взят от первых символов каждого слова в предложении (например, Four score and seven years ago приводит к паролю Fsasya). Пароль легко запомнить и ввести, но трудно предположить для кого-то, кто не знает предложение. В этом случае Вы можете дополнительно заменить цифрами слова числа, чтобы получить фразу 4 score and 7 years ago и пароль 4sa7ya, который еще более трудно предположить.
  • Поставьте и настройте брандмауэр. Это защищает Вас по крайней мере от 50% всех типов деяний в любом программном обеспечении. Поместите MySQL позади брандмауэра или в демилитаризированной зоне (DMZ).

    • Попытайтесь просмотреть свои порты из Интернета, используя такой инструмент, как nmap. MySQL использует порт 3306 по умолчанию. Этот порт не должен быть доступным от узлов, которым не доверяют. Как простой способ проверить, открыт ли Ваш порт MySQL, попробуйте следующую команду от некоторой отдаленной машины, где server_host это имя хоста или IP-адрес узла, на котором работает Ваш сервер MySQL:

      shell> telnet server_host 3306
      
      Если telnet зависает, или соединению отказывают, порт заблокирован. Если Вы получаете соединение и некоторые ошибочные символы, порт открыт и должен быть закрыт на Вашем брандмауэре или маршрутизаторе, если у Вас действительно нет серьезного основания сохранить это открытым.

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

  • Не передавайте открытые (незашифрованные) данные по Интернету. Эта информация доступна для всех, у кого есть время и способность перехватить и использовать ее в их собственных целях. Вместо этого используйте зашифрованный протокол, такой как SSL или SSH. MySQL поддерживает внутренние соединения SSL. Другой метод должен использовать перенаправление портов SSH, чтобы создать зашифрованный (и сжатый) туннель для коммуникации.
  • Учитесь использовать tcpdump и strings. В большинстве случаев Вы можете проверить, зашифрованы ли потоки данных MySQL, выпуская команду:
    shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
    
    Это работает под Linux и должно работать с маленькими модификациями под другими системами.

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

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

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

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

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

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

  • mysql_config_editor позволяет Вам сохранить параметры аутентификации в зашифрованном названном файле входа в систему .mylogin.cnf. Файл может быть считан позже программами клиента MySQL, чтобы получить параметры аутентификации для того, чтобы соединиться с MySQL Server. См. раздел 5.6.7 .

  • Используйте в командной строке опцию -pyour_pass или --password=your_pass. Например:
    shell> mysql -u francis -pfrank db_name
    
    Это удобно, но опасно. На некоторых системах Ваш пароль становится видимым системным программам состояния, таким как ps, которые могут быть вызваны другими пользователями. Клиенты MySQL, как правило, переписывают параметр пароля командной строки нолями во время их последовательности инициализации. Однако, есть все еще краткий интервал, во время которого значение видимо. Кроме того, на некоторых системах эта стратегия перезаписи неэффективна, и пароль остается видимым (System V Unix и, возможно, другие подвергаются этой проблеме).

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

  • Используйте опцию -p или --password в командной строке без значения пароля. В этом случае программа клиента требует пароля в интерактивном режиме:
    shell> mysql -u francis -p db_name
    Enter password: ********
    
    Символы * указывают, где Вы вводите свой пароль. Пароль не выведен на экран.

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

  • Сохраните свой пароль в файле опции. Например, в Unix, Вы можете написать свой пароль в разделе [client] файла .my.cnf:
    [client]
    password=your_pass
    
    Чтобы бережно хранить пароль, файл не должен быть доступным для любого. Чтобы гарантировать это, установите режим доступа к файлу 400 или 600. Например:
    shell> chmod 600 .my.cnf
    
    Чтобы назвать в командной строке определенный файл опции, содержащий пароль, используйте --defaults-file=file_name, где file_name полное имя файла. Например:
    shell> mysql --defaults-file=/home/francis/mysql-opts
    
    раздел 5.2.6 обсуждает файлы опции более подробно.
  • Сохраните свой пароль в переменной окружения MYSQL_PWD, см. раздел 5.9.

    Этот метод определения Вашего пароля MySQL нужно считать This method of specifying your MySQL password must be очень опасным, и он не должен использоваться. Некоторые версии ps включают опцию, чтобы вывести на экран окружающую среду выполнения процессов. На некоторых системах, если Вы устанавливаете MYSQL_PWD, Ваш пароль выставлен любому другому пользователю, который выполняет ps. Даже на системах без такой версии ps, неблагоразумно предположить, что нет никаких других методов, которыми пользователи могут исследовать окружающую среду процесса.

В 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 сервер регистрирует запрос, возвращенный плагином перезаписи запроса. Это может отличаться от полученного запроса.

  • С --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 безопасной, Вы должны рассмотреть следующие предложения:

  • Потребуйте, чтобы у всех учетных записей MySQL был пароль. Программа клиента не обязательно знает личность человека, выполняющего ее. Для приложений клиент-сервер распространено, что пользователь может определить любое имя пользователя в программе клиента. Например, любой может использовать mysql , чтобы соединиться как любой другой человек, просто вызывая это как mysql -u other_user db_name, если other_user пароля не имеет. Если у всех учетных записей есть пароль, соединение, использующее учетную запись другого пользователя, становится намного более трудным.

    См. раздел 7.3.6.

  • Удостоверьтесь, что единственная учетная запись пользователя Unix с чтением или записью в каталогах базы данных это учетная запись, которая используется для того, чтобы выполнить mysqld.
  • Никогда не выполняйте сервер MySQL как Unix-пользователь root. Это чрезвычайно опасно, потому что любой пользователь с привилегией FILE в состоянии заставить сервер создавать файлы как root (например, ~root/.bashrc). Чтобы предотвратить это, mysqld отказывается работать как root, если это не определено явно, используя опцию --user=root .

    mysqld может (и должен) быть выполнен как обычный непривилегированный пользователь вместо этого. Вы можете создать отдельную учетную запись Unix mysql, чтобы сделать все еще более безопасным. Используйте эту учетную запись только для управления MySQL. Чтобы запустить mysqld как иного пользователя Unix, добавьте опцию user, которая определяет имя пользователя в группу [mysqld] файла my.cnf, где Вы определяете параметры сервера. Например:

    [mysqld]
    user=mysql
    
    Это заставляет сервер запускаться как назначенный пользователь вручную или при использовании mysqld_safe или mysql.server. См. раздел 7.1.5.

    Выполнение mysqld как пользователь Unix не root не означает, что Вы должны изменить имя root в таблице user. Имена пользователей для учетных записей MySQL не имеют никакого отношения к именам пользователей для учетных записей Unix .

  • Не предоставляйте привилегию FILE неадминистративным пользователям. Любой пользователь, у которого есть эта привилегия, может написать файл где угодно в файловой системе с привилегиями mysqld . Это включает каталог данных сервера, содержащий файлы, которые осуществляют таблицы привилегии. Чтобы сделать привилегию FILE безопасней, файлы, произведенные SELECT ... INTO OUTFILE не перезаписывают существующие файлы и перезаписываемы всеми.

    FILE может также использоваться, чтобы считать любой файл, который доступен для пользователя Unix, от которого сервер выполняется. С этой привилегией Вы можете считать любой файл в таблицу базы данных. Этим можно было злоупотребить, например, при использовании LOAD DATA для чтения в таблицу /etc/passwd, которая тогда может быть выведена на экран с SELECT.

    Ограничить местоположение, в котором файлы могут быть считаны и написаны можно, установив secure_file_priv к определенному каталогу. См. раздел 6.1.5.

  • Не предоставляйте привилегии PROCESS или SUPER неадминистративным пользователям. Вывод mysqladmin processlist и SHOW PROCESSLIST показывает текст любых запросов, в настоящее время выполняемых, таким образом, любой пользователь, которому разрешают видеть список процесса сервера, мог быть в состоянии видеть запросы, сделанные другими пользователями, например, UPDATE user SET password=PASSWORD('not_secure').

    mysqld резервирует дополнительное соединение для пользователей, которые имеют привилегию SUPER, так, чтобы MySQL-пользователь root мог войти в систему и проверить деятельность сервера, даже если уже используются все нормальные соединения.

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

  • Не разрешайте использование символьных ссылок на таблицы. Эта способность может быть отключена опцией --skip-symbolic-links . Это особенно важно, если Вы выполняете mysqld как root, потому что любой, кто имеет доступ на запись к каталогу данных сервера может удалить любой файл в системе! См. раздел 9.12.2.2.
  • Сохраненные программы и представления должны быть написаны, используя направляющие линии безопасности, обсужденные в разделе 21.6.
  • Если Вы не доверяете своему DNS, Вы должны использовать IP-адреса, а не имена хоста в таблицах доступа. В любом случае Вы должны быть очень осторожными относительно создания записей таблицы доступа, используя значение имени хоста, которое содержит подстановочные знаки.
  • Если Вы хотите ограничить число соединений, разрешенных единственной учетной записи, Вы можете сделать так, устанавливая max_user_connections в mysqld . GRANT также поддерживает опции управления ресурсом для того, чтобы ограничить степень использования сервера, разрешенного учетной записи. См. раздел 14.7.1.6.
  • Если каталог плагинов перезаписываем сервером, для пользователя может быть возможно написать выполнимый код в файл в каталоге, используя SELECT ... INTO DUMPFILE. Это может быть предотвращено, делая plugin_dir только для чтения сервером или устанавливая --secure-file-priv к каталогу, где запись из SELECT может быть сделана безопасно.

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:

  • Передача файла от хоста клиента до узла сервера начата сервером MySQL. В теории исправленный сервер мог быть создан, который скажет программе клиента передавать файл по выбору сервера, а не файл, названный клиентом в LOAD DATA. Такой сервер мог бы получить доступ к любому файлу на хосте клиента, к которому пользователь клиента имеет доступ на чтение.

  • В Веб-окружающей среде, где клиенты соединяются от веб-сервера, пользователь мог бы использовать LOAD DATA LOCAL, чтобы читать любые файлы, к которым процесс веб-сервера имеет доступ (предполагая, что пользователь может выполнить любую команду SQL-сервера). В этой окружающей среде клиент относительно сервера MySQL фактически веб-сервер, а не отдаленная программа, выполняемая пользователем, который соединяется с веб-сервером.

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

  • По умолчанию все клиенты MySQL и библиотеки в двоичных дистрибутивах собраны с опцией -DENABLED_LOCAL_INFILE=1.

  • Если Вы создаете MySQL из исходных текстов, но не вызываете CMake с -DENABLED_LOCAL_INFILE=1, LOAD DATA LOCAL не может использоваться никаким клиентом, если это не написано явно, чтобы вызвать mysql_options(...MYSQL_OPT_LOCAL_INFILE, 0). См. раздел 25.8.7.50.
  • Вы можете отключить все запросы LOAD DATA LOCAL на сервере, запуская mysqld с опцией --local-infile=0 .
  • Для mysql включить LOAD DATA LOCAL можно указанием --local-infile[=1] или выключить через --local-infile=0 . Для mysqlimport местная загрузка файла с данными выключена по умолчанию, включите это через --local или -L. В любом случае успешное использование местной работы загрузки требует, чтобы сервер разрешил это.
  • Если Вы используете LOAD DATA LOCAL в скриптах Perl или других программах, которые читают группу [client] файлов опций, Вы можете добавить опцию local-infile=1. Однако, чтобы препятствовать этому вызывать проблемы для программ, которые не понимают local-infile, определите это, используя префикс loose-:
    [client]
    loose-local-infile=1
    
  • Если LOAD DATA LOCAL выключен в сервере или в клиенте, клиент, который пытается сделать такой запрос, получает следующее сообщение об ошибке:
    ERROR 1148: The used command is not allowed with this MySQL version
    

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 (например, те, которые основаны на методе в предыдущем параграфе, который заставляет сервер тратить впустую ресурсы). Иначе Ваш сервер становится безразличным к законным пользователям.

  • Позвольте строгому режиму SQL сказать серверу быть более рестриктивным, в плане значений данных, которые это принимает. См. раздел 6.1.8.

  • Попытайтесь ввести единственные и двойные кавычки (' и ") во всех Ваших Веб-формах. Если Вы получаете какой-либо вид ошибки MySQL, исследуйте проблему сразу же.
  • Попытайтесь изменить динамические URL, добавляя %22 ("), %23 (#) и %27 (').
  • Попытайтесь изменить типы данных в динамических URL от числового до символьных типов, используя символы, показанные в предыдущих примерах. Ваше приложение должно быть безопасным против этих и подобных нападений.
  • Попытайтесь ввести символы, пробелы и специальные символы, а не числа в числовых областях. Ваше приложение должно удалить их прежде, чем передать к MySQL или иначе произвести ошибку. Прохождение любых значений к MySQL очень опасно!
  • Проверьте размер данных прежде, чем передать это MySQL.
  • Не давайте Вашим приложениям привилегии доступа, в которых они не нуждаются.

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

  • MySQL C API: Примените mysql_real_escape_string_quote().

  • MySQL++: Примените модификаторы escape и quote для потоков запроса.
  • PHP: Используйте расширение mysqli или pdo_mysql, но не старое ext/mysql. Новое API имеет улучшенный протокол аутентификации MySQL и пароли, так же как подготовленные запросы с заполнителями. См. также Choosing an API.

    Если более старое расширение ext/mysql должна использоваться mysql_real_escape_string_quote() для того, чтобы экранировать символы, но но mysql_escape_string() или addslashes() потому, что только mysql_real_escape_string_quote() осведомлена о наборе символов, другие функции могут пропускать данные, используя (недопустимые) многобайтовые наборы символов.

  • Perl DBI: Используйте заполнители или метод quote().
  • Ruby DBI: Используйте заполнители или метод quote().
  • Java JDBC: Используйте заполнители и объект PreparedStatement.

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

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 обеспечивает привилегии, которые применяются в различных контекстах и на разных уровнях работы:

  • Административные привилегии позволяют пользователям управлять работой сервера 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 могут быть более определенные требования привилегии, чем обозначено здесь. Если так, описание для рассматриваемого запроса обеспечивает детали.

  • ALL или ALL PRIVILEGES означает все привилегии, доступные в данном уровне привилегии (кроме GRANT OPTION). Например, предоставление ALL в глобальном или табличном уровне предоставляет все глобальные привилегии или все привилегии на уровне таблицы.

  • ALTER включает использование ALTER TABLE, чтобы изменить структуру таблиц. ALTER TABLE также требует CREATE и INSERT. Переименование таблицы требует ALTER и DROP на старой таблице, CREATE и INSERT на новой.
  • ALTER ROUTINE необходима, чтобы изменить или удалить сохраненные подпрограммы (процедуры и функции).
  • CREATE включает создание новых баз данных и таблиц.
  • CREATE ROLE включает использование CREATE ROLE. CREATE USER также включает использование CREATE ROLE.
  • CREATE ROUTINE необходима, чтобы создать сохраненные подпрограммы (процедуры и функции).
  • CREATE TABLESPACE необходима, чтобы создать, изменить или удалить группы файла системного журнала и табличные пространства.
  • CREATE TEMPORARY TABLES включает создание временных таблиц, используя CREATE TEMPORARY TABLE.

    После того, как сеанс составил временную таблицу, никакая дальнейшая привилегия не проверяется для таблицы. Сеанс создания может выполнить любую работу на таблице, например, as DROP TABLE, INSERT, UPDATE или SELECT.

    Одно значение этого поведения: сеанс может управлять своими временными таблицами, даже если у текущего пользователя нет никакой привилегии создать их. Предположите, что текущий пользователь не имеет CREATE TEMPORARY TABLES, но в состоянии выполнить хранимую процедуру контекста DEFINER, которая выполняется с привилегиями пользователя, который действительно имеет привилегию CREATE TEMPORARY TABLES, и это составляет временную таблицу. В то время, как процедура выполняется, сеанс использует привилегии пользователя определения. После окончания процедуры эффективные привилегии возвращаются к таковым для текущего пользователя, который может все еще видеть временную таблицу и выполнить любую работу на ней.

    Чтобы сохранить привилегии для временных и невременных таблиц отдельными, общее обходное решение для этой ситуации должно создать базу данных, посвященную использованию временных таблиц. Тогда для той базы данных пользователю можно предоставить CREATE TEMPORARY TABLES наряду с любыми другими привилегиями, требуемыми для временных табличных операций, сделанных тем пользователем.

  • CREATE USER разрешает использовать ALTER USER , CREATE ROLE, CREATE USER, DROP ROLE, DROP USER, RENAME USER и REVOKE ALL PRIVILEGES.
  • CREATE VIEW включает использование CREATE VIEW .
  • DELETE позволяет строкам быть удаленными из таблиц в базе данных.
  • DROP включает удаление существующих баз данных, таблиц и представлений. DROP требуется, чтобы использовать запрос ALTER TABLE ... DROP PARTITION на разделенной таблице. DROP также требуется для TRUNCATE TABLE. Если Вы предоставляете DROP для базы данных mysql, пользователь может удалить базу данных, в которой сохранены привилегии доступа MySQL.
  • DROP ROLE включает использование DROP ROLE. CREATE USER также включает использование DROP ROLE .
  • EVENT разрешает создавать, изменять, удалять или видеть события для Event Scheduler.
  • EXECUTE разрешает выполнять сохраненные подпрограммы (процедуры и функции).
  • FILE дает Вам разрешение читать и писать файлы на узле сервера, используя LOAD DATA INFILE и SELECT ... INTO OUTFILE и функцию LOAD_FILE(). Пользователь, который имеет привилегию FILE, может считать любой файл на узле сервера, который читаем сервером MySQL. Это подразумевает, что пользователь может считать любой файл в любом каталоге базы данных, потому что сервер может получить доступ к любому из тех файлов. FILE также позволяет пользователю создать новые файлы в любом каталоге, где сервер MySQL имеет доступ на запись. Это включает каталог данных сервера, содержащий файлы, которые осуществляют таблицы привилегии. Как мера по безопасности, сервер не будет перезаписывать существующие файлы.

    Ограничить местоположение, в котором файлы могут быть считаны и написаны можно, установив secure_file_priv к определенному каталогу. См. раздел 6.1.5.

  • GRANT OPTION позволяет Вам дать другим пользователям или удалить от других пользователей те привилегии, которыми Вы сами обладаете.
  • INDEX разрешает создать или удалить индексы. INDEX относится к существующим таблицам. Если Вы имеете CREATE для таблицы, Вы можете включать индексные определения в CREATE TABLE.
  • INSERT позволяет строкам быть вставленными в таблицы в базе данных. INSERT также требуется для ANALYZE TABLE , OPTIMIZE TABLE и REPAIR TABLE.
  • LOCK TABLES разрешает заблокировать таблицы, для которых Вы имеете привилегию SELECT с помощью LOCK TABLES. Это включает использование блокировки, которая препятствует тому, чтобы другие сеансы читали заблокированную таблицу.
  • PROCESS принадлежит отображению информации о выполнении потоков в пределах сервера (то есть, информации о запросах, выполняемых сеансами). Привилегия включает использование SHOW PROCESSLIST или mysqladmin processlist , чтобы видеть потоки, которые принадлежат другим учетным записям, Вы можете всегда видеть свои собственные потоки. PROCESS также включает использование SHOW ENGINE.
  • PROXY позволяет пользователю явиться олицетворением или стать известным как другой пользователь. См. раздел 7.3.10.
  • Создание ограничения внешнего ключа требует привилегии REFERENCES для родительской таблицы.
  • RELOAD включает использование FLUSH. Это также включает mysqladmin , которая эквивалентна операциям FLUSH: flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh и reload.

    reload говорит серверу перезагружать таблицы привилегий в память. flush-privileges синоним для reload. refresh закрывает и вновь открывает файлы системного журнала и сбрасывает все таблицы. Другие команды flush-xxx выполняют функции, подобные refresh, но являются более определенными и могут быть предпочтительными в некоторых случаях. Например, если Вы хотите сбросить только файлы системного журнала, flush-logs лучший выбор, чем refresh.

  • REPLICATION CLIENT включает использование SHOW MASTER STATUS, SHOW SLAVE STATUS и SHOW BINARY LOGS.
  • REPLICATION SLAVE нужно предоставить учетным записям, которые используются ведомыми серверами, чтобы соединиться с текущим сервером как их ведущее устройство. Без этой привилегии ведомое устройство не может просить обновления, которые были сделаны к базам данных главного сервера.
  • SELECT позволяет Вам выбрать строки из таблиц в базе данных. Запросы SELECT требуют привилегию SELECT только если они фактически получают строки от таблицы. Некоторые SELECT не получают доступ к таблицам и могут быть выполнены без разрешения для любой базы данных. Например, Вы можете использовать SELECT как простой калькулятор, чтобы оценить выражения, которые не делают ссылки на таблицы:
    SELECT 1+1;
    SELECT PI()*2;
    
    Привилегия SELECT также необходима для других запросов, которые читают значения столбцов. Например, SELECT необходима для столбцов, на которые ссылаются на правой стороне col_name=expr в UPDATE или для столбцов, названных в WHERE в DELETE или UPDATE.
  • SHOW DATABASES позволяет учетной записи видеть имена базы данных с помощью запроса SHOW DATABASE. Учетные записи, у которых нет этой привилегии, видят только базы данных, для которых они имеют некоторые привилегии, и не могут использовать запрос вообще, если сервер был запущен с опцией --skip-show-database. Отметьте, что любая глобальная привилегия это привилегия для базы данных.
  • SHOW VIEW включает использование SHOW CREATE VIEW.
  • SHUTDOWN включает использование SHUTDOWN и mysqladmin shutdown .
  • SUPER позволяет учетной записи использовать CHANGE MASTER TO, KILL или mysqladmin kill , чтобы уничтожить потоки, принадлежащие другим учетным записям (Вы можете всегда уничтожать свои собственные потоки), PURGE BINARY LOGS, mysqladmin debug , включая или отключая журналирование, выполняя обновления, даже если включена системная переменная read_only, запускать и останавливать репликацию на ведомых серверах, указывать любую учетную запись в параметре DEFINER сохраненных программ и представлений, и позволяет Вам соединиться (однажды), даже если превышен предел соединений, которым управляет max_connections .

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

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

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

    Когда триггер активирован (пользователем, у которого есть привилегии выполнить INSERT, UPDATE или DELETE для таблицы, связанной с ним), выполнение требует, чтобы пользователь, который определил триггер имел привилегию TRIGGER.

  • UPDATE позволяет строкам быть обновленными в таблицах в базе данных.
  • USAGE указывает "никаких привилегий". Это используется на глобальном уровне с GRANT, чтобы изменить признаки учетной записи, такие как пределы ресурса или характеристики SSL, не затрагивая существующие привилегии учетной записи.

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

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

  • GRANT OPTION позволяет пользователям дать свои привилегии другим пользователям. Два пользователя, у которых есть различные привилегии с GRANT OPTION в состоянии объединить привилегии.
  • ALTER может использоваться, чтобы ниспровергнуть систему привилегии, переименовывая таблицы.
  • SHUTDOWN можно злоупотребить, чтобы отказать в службе другим пользователям полностью, заканчивая сервер.
  • PROCESS может использоваться, чтобы рассмотреть простой текст в настоящее время выполняемых запросов, включая запросы, которые устанавливают или изменяют пароли.
  • SUPER может использоваться, чтобы закончить другие сеансы или изменить то, как сервер работает.
  • Привилегии, предоставленные для базы данных mysql, могут использоваться, чтобы изменить пароли и другую информацию о привилегии доступа. Пароли сохранены зашифрованными, таким образом, злонамеренный пользователь не может просто читать их, чтобы узнать пароль простого текста. Однако, пользователь с правами на запись в столбец authentication_string таблицы user может изменить пароль учетной записи, и затем соединиться с сервером MySQL, используя эту учетную запись.

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

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

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

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

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

  • user: Учетные записи пользователя, глобальные привилегии и другие столбцы.

  • db: Привилегии на уровне базы данных.
  • tables_priv: Привилегии на уровне таблицы.
  • columns_priv: Привилегии на уровне столбца.
  • procs_priv: Привилегии процедур и функций.
  • proxies_priv: Пользовательские доверенные привилегии.

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

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

  • Столбцы контекста определяют контекст каждой строки в таблицах, то есть, контекст, в котором применяется строка. Например, в таблице user строка со значениями Host и User соответственно 'thomas.loc.gov' и 'bob' относится к подтверждению соединений, сделанных к серверу от узла thomas.loc.gov клиентом, который определяет имя пользователя bob. Точно так же в таблице db строка с значениями Host, User и Db соответственно 'thomas.loc.gov', 'bob' и 'reports' применяется когда bob соединяется от узла thomas.loc.gov для доступа к базе данных reports. Таблицы tables_priv и columns_priv содержат столбцы контекста, указывающие на таблицы или комбинации таблицы/столбца, к которым применяется каждая строка. Столбцы контекста procs_priv указывают на сохраненную подпрограмму, к которой применяется каждая строка.

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

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

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

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

  • Табличные столбцы контекста db определяют, какие пользователи могут получить доступ к каким базам данных от которого узла. Столбцы привилегии определяют разрешенные операции. Привилегия, предоставленная на уровне базы данных, относится к базе данных и всем объектам в базе данных, таким как таблицы и сохраненные программы.

  • Таблицы tables_priv и columns_priv подобны db, но являются более точными: они применяются на уровнях таблицы и столбца, а не на уровне базы данных. Привилегия, предоставленная на табличном уровне, относится к таблице и всем ее столбцам. Привилегия, предоставленная на уровне столбца, применяется только к определенному столбцу.
  • Таблица procs_priv относится к сохраненным подпрограммам (процедуры и функции). Привилегия, предоставленная на уровне подпрограммы, применяется только к единственной процедуре или функции.
  • Таблица proxies_priv показывает, какие пользователи могут действовать как полномочия для других пользователей и может ли пользователь предоставить привилегию PROXY другим пользователям.

Сервер использует таблицы 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 делает запись информации об учетных записях по доверенности. У нее есть эти столбцы:

  • Host, User: Учетная запись по доверенности, то есть, учетная запись, которая имеет привилегию PROXY для учетной записи.

  • Proxied_host, Proxied_user: Учетная запись proxied.
  • Grantor, Timestamp: Не задействованы.
  • With_grant: Может ли учетная запись по доверенности предоставить привилегию PROXY другим учетным записям.

Для учетной записи, чтобы быть в состоянии предоставить привилегию 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, имена учетной записи следуют этим правилам:

  • Синтаксис имени учетной записи 'user_name'@'host_name'.

  • Имя учетной записи, состоящее только из имени пользователя, эквивалентно 'user_name'@'%'. Например, 'me' эквивалентно 'me'@'%'.
  • Имя пользователя и имя хоста не должны быть заключены в кавычки, если они законны как идентификаторы без кавычек. Кавычки необходимы, чтобы определить строку user_name, содержащую специальные символы (такие как пробел или -) или строку host_name со специальными или подстановочными символами (например, . или %), скажем, 'test-user'@'%.com'.
  • Имена пользователя и имена хоста берутся в кавычки как идентификаторы или как строки, используя `, ' или (").
  • Части имени пользователя и хоста, если заключены в кавычки, должны быть заключены в кавычки отдельно. Таким образом, напишите 'me'@'localhost', но не 'me@localhost', последнее аналогично 'me@localhost'@'%'.
  • Ссылка на CURRENT_USER или CURRENT_USER() эквивалентна определению имени пользователя текущего клиента и имени хоста буквально.

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

  • Таблица user содержит одну строку для каждой учетной записи. Столбцы User и Host хранят имя пользователя и имя хоста. Эта таблица также показывает, какие глобальные привилегии учетная запись имеет.

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

См. раздел 7.2.2.

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

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

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

  • Значение узла может быть именем хоста или IP-адресом (IPv4 или IPv6). Имя 'localhost' указывает на местный узел. IP-адрес '127.0.0.1' указывает на интерфейс IPv4 loopback. IP-адрес '::1' указывает на интерфейс IPv6 loopback.

  • Символы % и _ разрешены в значениях IP-адреса или имени хоста. У них есть то же самое значение, что касается соответствующих образцу операций, выполненных с LIKE. Например, значение узла '%' соответствует любому имени хоста, тогда как значение '%.mysql.com' соответствует любому имени хоста в домене mysql.com. '192.168.1.%' соответствует любому хосту в сети 192.168.1 класса C.

    Поскольку подстановочные значения разрешены в значениях узла (например, '192.168.1.%' соответствует каждому узлу подсети), кто-то мог попытаться эксплуатировать эту способность, называя узел 192.168.1.somewhere.com. Чтобы помешать таким попыткам, MySQL не выполняет соответствие на именах хоста, которые начинаются с цифр и точки. Например, если узел называют 1.2.example.com, его имя никогда не соответствует части узла имени учетной записи. Подстановочное значение IP может соответствовать только IP-адресу, не имени хоста.

  • Для значения узла, определенного как адрес IPv4, сетевая маска может быть дана, чтобы указать сколько битов адреса использовать для сетевого адреса. Нотация сетевой маски не может использоваться для адресов IPv6.

    Синтаксис host_ip/netmask . Например:

    CREATE USER 'david'@'192.58.197.0/255.255.255.0';
    
    Это позволяет david соединяться от любого хоста клиента, имеющего IP-адрес client_ip для которого следующее условие истина:
    client_ip & netmask = host_ip
    
    Таким образом, для CREATE USER:
    client_ip & 255.255.255.0 = 192.58.197.0
    
    IP-адреса, которые удовлетворяют этому диапазону условия, от 192.58.197.0 до 192.58.197.255.

    Сетевая маска, как правило, начинается с набора битов 1, сопровождаемого набором битов 0. Примеры:

    • 192.0.0.0/255.0.0.0: Любой узел в сети 192 класса A.

    • 192.168.0.0/255.255.0.0: Любой узел в сети 192.168 класса B.
    • 192.168.1.0/255.255.255.0: Любой узел в сети 192.168.1 класса C.
    • 192.168.1.1: Только узел с этим определенным IP-адресом.

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

  • Предположите, что у узла местной сети есть полностью определенное имя host1.example.com. Если DNS возвращает поиски имени для этого узла как host1.example.com, используйте это имя в значениях узла учетной записи. Если DNS возвращает только host1, используйте host1.

  • Если DNS возвращает IP-адрес для данного узла как 192.168.1.2, это будет соответствовать значению узла учетной записи 192.168.1.2, но не 192.168.01.2. Точно так же это будет соответствовать образцу узла учетной записи как 192.168.1.%, но не 192.168.01.%.

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

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

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

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

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

  • Что касается имени учетной записи, опуская часть узла роли называют результаты в части узла %. Но в отличие от % в имени учетной записи, часть узла % в имени роли не имеет никаких подстановочных свойств. Например, для имени 'me'@'%' используемого в качестве ролевого имени, часть узла (%) просто символ, у этого нет никакого соответствия любому хосту. Нотация сетевой маски не имеет никакого значения.
  • Имени учетной записи разрешают быть CURRENT_USER() в нескольких контекстах. Ролевому имени нет.

Возможно для строки в 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.

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

  • Хост клиента, от которого Вы соединяетесь.

  • Ваше имя пользователя MySQL.

Если значение столбца 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.

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

  • Всякий раз, когда сервер читает таблицу user в память, это сортирует строки.

  • Когда клиент пытается соединиться, сервер просматривает строки в сортированном порядке.
  • Сервер использует первую строку, которая соответствует имени хоста клиента и имени пользователя.

Строки с наиболее определенным 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 предоставляет определенные для базы данных привилегии. Значения в столбцах контекста этой таблицы могут принять следующие формы:

  • Пустое User соответствует анонимному пользователю. Непустое значение соответствует буквально: на имена пользователя нет никаких подстановочных знаков.

  • Подстановочные символы % и _ могут использоваться в столбцах Host и Db. У них есть то же самое значение, что касается соответствующих образцу операций, выполненных с оператором LIKE. Если Вы хотите использовать любой символ буквально, предоставляя привилегии, Вы должны экранировать его обратным слэшем. Например, чтобы включать символ подчеркивания (_) как часть имени базы данных, определите это как \_ в GRANT.
  • '%' или пустое значение Host означает любой host.
  • '%' или пустое значение Db означает любую базу данных.

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

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

  • Подстановочные символы % и _ могут использоваться в Host. У них есть то же самое значение, что касается соответствующих образцу операций, выполненных с LIKE.

  • '%' или пустой Host значит любой хост.
  • Столбцы Db, Table_name, Column_name и Routine_name не могут содержать подстановочные знаки или быть пробелом.

Сервер сортирует 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.

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

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

  • Изменения привилегии базы данных вступают в силу в следующий раз, когда клиент выполняет USE db_name.

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

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

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

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

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

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

    shell> mysql
    ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
    shell> mysql
    ERROR 2002: Can't connect to local MySQL server through socket
    '/tmp/mysql.sock' (111)
    
  • Могло бы случиться так, что сервер работает, но Вы пытаетесь соединиться с использованием порта TCP/IP, именованного канала или файла сокета Unix, отличающемся от того, на котором слушает сервер. Чтобы исправить это, когда Вы вызываете программу клиента, определите опцию --port, чтобы указать на надлежащий номер порта или --socket, чтобы указать на надлежащий канал или файл сокета Unix. Чтобы узнать, где находится файл сокета, Вы можете использовать эту команду:
    shell> netstat -ln | grep mysql
    
  • Удостоверьтесь, что сервер не был сконфигурирован, чтобы проигнорировать сетевые соединения или (если Вы пытаетесь соединиться отдаленно), что он не был сконфигурирован, чтобы слушать только в местном масштабе на его сетевых интерфейсах. Если сервер был запущен с --skip-networking , это не будет принимать соединения TCP/IP вообще. Если сервер был запущен с --bind-address=127.0.0.1, это слушает соединения TCP/IP только в местном масштабе и не будет принимать удаленные соединения.
  • Проверьте, чтобы удостовериться, что нет никакого блокирующего брандмауэра. Ваш брандмауэр может быть сконфигурирован на основе приложения или номера порта, используемого MySQL для коммуникации (3306 по умолчанию). Под Linux или Unix проверьте свои IP tables, чтобы гарантировать, что порт не был заблокирован. Под Windows такие приложения, как ZoneAlarm или Windows Firewall, возможно, должны быть сконфигурированы, чтобы не заблокировать порт MySQL.
  • Таблицы привилегий должны быть должным образом настроены так, чтобы сервер мог использовать их для управления доступом. Для некоторых типов дистрибутивов (таких как двоичные в Windows или RPM в Linux), процесс установки инициализирует каталог данных MySQL, включая базу данных mysql, содержащую таблицы привилегий. Для дистрибутивов, которые не делают этого, Вы должны инициализировать каталог данных вручную. Для деталей см. раздел 2.9.

    Чтобы определить, должны ли Вы инициализировать таблицы привилегий, ищите подкаталог mysql в соответствии с каталогом данных. Каталог данных обычно называют data или var и расположен в соответствии с Вашим каталогом установки MySQL. Удостоверьтесь, что есть файл user.MYD в каталоге mysql. В противном случае инициализируйте каталог данных. После выполнения этого и запуска сервера, проверьте начальные привилегии, выполняя эту команду:

    shell> mysql -u root
    
    Сервер должен позволить Вам соединяться без ошибки.
  • После новой установки Вы должны соединиться с сервером и настроить своих пользователей и их разрешения на доступ:
    shell> mysql -u root mysql
    
    Сервер должен позволить Вам соединяться без пароля, если Вы инициализировали MySQL, используя mysqld --initialize-secure, чтобы не создать пароль для начальной учетной записи root (см. раздел 2.9.1.1 ). Это угроза безопасности, таким образом установить пароль для root надо в то время, как Вы настраиваете свои другие учетные записи MySQL. Для инструкций по установке начального пароля см. раздел 2.9.4.
  • Если Вы обновили существующую установку MySQL к более новой версии, Вы выполняли mysql_upgrade ? В противном случае сделайте так. Структура таблиц привилегий иногда изменяется, когда новые способности добавлены, таким образом, после обновления Вы должны всегда удостоверяться, что у Ваших таблиц есть текущая структура. Для инструкций см. раздел 5.4.5.
  • Если программа клиента получает следующее сообщение об ошибке, когда пытается соединиться, это означает, что сервер ожидает пароли в более новом формате, чем применяет клиент:
    shell> mysql
    Client does not support authentication protocol requested
    by server; consider upgrading MySQL client
    
  • Помните, что программы клиента используют параметры соединения, определенные в файлах опции или переменных окружения. Если программа клиента посылает неправильные параметры соединения по умолчанию, когда Вы не определили их в командной строке, проверьте любые применимые файлы опции и Вашу среду. Например, если Вы получаете Access denied, когда Вы выполняете клиент без любых опций, удостоверьтесь, что Вы не определили старый пароль в любом из Ваших файлов опции!

    Вы можете подавить использование файлов опции программой клиента, вызывая это с опцией --no-defaults. Например:

    shell> mysqladmin --no-defaults -u root version
    
    Файлы опции, которые используют клиенты, перечислены в разделе 5.2.6. Переменные окружения перечислены в разделе 5.9.
  • Если Вы получаете следующую ошибку, это означает, что Вы используете неправильный пароль для root:
    shell> mysqladmin -u root -pxxxx ver
    Access denied for user 'root'@'localhost' (using password: YES)
    
    Если предыдущая ошибка происходит, даже когда Вы не определили пароль, это означает, что указан неправильный пароль в некотором файле опции. Попробуйте опцию --no-defaults как описано в предыдущем элементе.

    См. раздел 7.3.6.

    Если Вы потеряли или забыли пароль root, см. раздел B.5.3.2.

  • Если Вы изменяете пароль при использовании SET PASSWORD, INSERT или UPDATE, Вы должны зашифровать пароль, используя функцию PASSWORD(). Если Вы не используете PASSWORD() для этих запросов не будет работать пароль. Например, следующий запрос назначает пароль, но не в состоянии зашифровать его, таким образом, пользователь не в состоянии соединиться позже:
    SET PASSWORD FOR 'abe'@'host_name' = 'eagle';
    
    Вместо этого установите пароль так:
    SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');
    
    Функция PASSWORD() является ненужной, когда Вы определяете пароль, используя CREATE USER или GRANT или через mysqladmin password . Каждый из этих способов автоматически использует PASSWORD(), чтобы зашифровать пароль. См. разделы 7.3.6 и 14.7.1.3.
  • localhost синоним для Вашего местного имени хоста, а также узел значения по умолчанию, с которым клиенты пытаются соединиться, если Вы не определяете имя узла явно.

    Вы можете использовать опцию --host=127.0.0.1, чтобы назвать узел сервера явно. Это сделает соединение TCP/IP с местным mysqld. Вы можете также использовать TCP/IP, определяя --host, которая использует фактическое имя хоста местного узла. В этом случае имя хоста должно быть определено в строке таблицы user на узле сервера, даже при том, что Вы выполняете программу клиента на том же самом узле, где сервер.

  • Ошибка Access denied говорит, что Вы пытаетесь войти в систему как хост клиента, от которого Вы пытаетесь соединиться, и использовали ли Вы пароль. Обычно Вы должны иметь строку в user, которая точно соответствует имени хоста и пользователя, которые были даны в сообщении об ошибке. Например, если Вы получаете сообщение об ошибке, которое содержит using password: NO, это означает, что Вы попытались войти в систему без пароля.
  • Если Вы получаете ошибку Access denied, пытаясь соединиться с базой данных с mysql -u user_name, у Вас может быть проблема с таблицей user. Проверьте это, выполняя mysql -u root mysql:
    SELECT * FROM user;
    
    Результат должен включать строку с Host и User, соответствующими имени хоста Вашего клиента и Вашему имени пользователя MySQL.
  • Если следующая ошибка происходит, когда Вы пытаетесь соединиться от узла кроме того, на котором работает сервер MySQL, это означает, что нет никакой строки в user с Host, которое соответствует хосту клиента:
    Host ... is not allowed to connect to this MySQL server
    
    Вы можете установить это, настраивая комбинацию имени хоста клиента и имени пользователя, которое Вы используете, пытаясь соединиться.

    Если Вы не знаете IP-адрес или имя хоста машины, с которой Вы соединяетесь, Вы должны поместить строку с '%' в столбец Host таблицы user. После попытки соединиться от машины клиента, используйте SELECT USER(), чтобы видеть, как Вы действительно соединялись. Тогда измените '%' в строке таблицы user к фактическому имени хоста, которое обнаруживается в журнале. Иначе Ваша система будет с дырой, потому что она разрешает соединения от любого узла к данному имени пользователя.

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

  • Если Вы определяете имя хоста, пытаясь соединиться, но получаете сообщение об ошибке, где имя хоста не показано или является IP-адресом, это означает, что сервер MySQL получил ошибку, пытаясь решить IP-адрес хоста клиента к имени:
    shell> mysqladmin -u root -pxxxx -h some_hostname ver
    Access denied for user 'root'@'' (using password: YES)
    
    Если Вы пытаетесь соединиться как root и получаете следующую ошибку, это означает, что Вы не имеете строки в user с User = 'root', и mysqld не может решить имя хоста для Вашего клиента:
    Access denied for user ''@'unknown'
    
    Эти ошибки указывают на проблему DNS. Чтобы установить это, выполните mysqladmin flush-hosts , чтобы сбросить внутренний кэш узла DNS. См. раздел 9.12.4.2.

    Некоторые постоянные решения:

    • Определите что не так с Вашим сервером DNS.

    • Определите IP-адреса, а не имена хоста в таблицах привилегий MySQL.
    • Поместите запись для машинного имени клиента в /etc/hosts в Unix или \windows\hosts в Windows.
    • Запустите mysqld с опцией --skip-name-resolve.
    • Запустите mysqld с опцией --skip-host-cache.
    • В Unix, если Вы выполняете сервер и клиента на той же самой машине, соединяются с localhost. Для соединений с localhost программы MySQL пытаются соединиться с локальным сервером при использовании файла сокета Unix, если нет параметров соединения, определенных, чтобы гарантировать, что клиент делает соединение TCP/IP. Для получения дополнительной информации см. раздел 5.2.2.
    • В Windows, если Вы выполняете сервер и клиента на той же самой машине и сервер поддерживает именованные каналы, соединяются с именем хоста . (точка). Это использует канал, а не TCP/IP.

  • Если mysql -u root работает, но mysql -h your_hostname -u root выдает Access denied (your_hostname это фактическое имя хоста местного узла), у Вас не может быть правильного названия Вашего узла в user. Типичная проблема здесь состоит в том что Host в user определяет дисквалифицированное имя хоста, но подпрограммы разрешения имени Вашей системы возвращают полностью компетентное доменное имя (или наоборот). Например, если Вы имеете строку с хостом 'pluto' в user, но DNS говорит MySQL, что Ваше имя хоста 'pluto.example.com', строка не сработает. Попытайтесь добавить строку к user, которая содержит IP-адрес Вашего узла как Host. Альтернативно, Вы могли добавить строку к user с Host, которое содержит подстановочный знак, например, 'pluto.%'. Однако, использование Host с % опасно!

  • Если mysql -u user_name работает, а mysql -u user_name some_db нет, Вы не предоставили доступ данному пользователю для базы данных some_db.
  • Если mysql -u user_name работает, когда выполнено на узле сервера, но mysql -h host_name -u user_name не работает, когда выполнено на отдаленном хосте клиента, Вы не включили доступу к серверу для данного имени пользователя с отдаленного узла.
  • Если Вы не можете выяснить, почему Вы получаете Access denied, удалите из user все строки, которые имеют Host, содержащие подстановочные знаки (строки, которые содержат '%' или '_'). Очень распространенная ошибка состоит в том, чтобы вставить новую строку с Host='%' и User='some_user', думая, что это позволяет Вам определить localhost, чтобы соединяться от той же самой машины. Причина, почему это не работает, состоит в том, что привилегии по умолчанию включают строку с Host='localhost' и User=''. Поскольку у этой строки есть Host = 'localhost', что является более определенным, чем '%', это используется в предпочтении к новой строке, соединяясь от localhost! Правильная процедура должна вставить вторую строку с Host='localhost' и User='some_user' или удалить строку с Host='localhost' и User=''. После удаления строки надо выполнить FLUSH PRIVILEGES для перезагрузки таблиц, см. раздел 7.2.5.
  • Если Вы в состоянии соединиться с сервером MySQL, но получаете Access denied при выполнении SELECT ... INTO OUTFILE или LOAD DATA INFILE, Ваша строка в user не имеет привилегии FILE.
  • Если Вы изменяете таблицы привилегий непосредственно (например, при использовании INSERT, UPDATE или DELETE) и Ваши изменения проигнорированы, Вы должны выполнить FLUSH PRIVILEGES или mysqladmin flush-privileges , чтобы заставить сервер перезагружать таблицы привилегии. Иначе Ваши изменения не имеют никакого эффекта до следующего раза, когда сервер перезапущен. Помните, что после того, как Вы изменяете пароль root с UPDATE, Вы не должны будете определить новый пароль, пока не сбросите привилегии, потому что сервер не будет знать, что Вы изменили пароль!
  • Если Ваши привилегии изменились в середине сеанса, может случиться так, что администратор MySQL изменил их. Перезагрузка таблиц привилегий затрагивает новые соединения клиента, но она также затрагивает существующие соединения как обозначено в разделе 7.2.7.
  • Если у Вас есть проблемы доступа с Perl, PHP, Python или ODBC, попробуйте соединиться с сервером с mysql -u user_name db_name или mysql -u user_name -pyour_pass db_name. Если Вы в состоянии соединиться с использованием mysql , проблема связана с Вашей программой, не с привилегиями доступа. Нет никакого пробела между -p и паролем, Вы можете также использовать --password=your_pass, чтобы определить пароль. Если Вы используете опцию -p или --password без значения пароля, MySQL запрашивает у Вас пароль.
  • Для того, чтобы проверить, запустите mysqld с опцией --skip-grant-tables. Тогда Вы можете изменить таблицы привилегий MySQL и использовать SHOW GRANTS для проверки, имеют ли Ваши модификации желаемый эффект. Когда Вы удовлетворены своими изменениями, выполните mysqladmin flush-privileges, чтобы сказать mysqld перезагружать привилегии. Это позволяет Вам начать использовать новое табличное содержание привилегий, не останавливая и перезапуская сервер.
  • Если все остальное терпит неудачу, запустите mysqld с опцией отладки (например, --debug=d,general,query). Это печатает узел и информацию о пользователе о предпринятых соединениях и информацию о каждой команде. См. раздел 26.5.3.
  • Если Вы имеете какие-либо другие проблемы с таблицами привилегий MySQL и чувствуете, что должны отправить проблему в список рассылки, всегда надо обеспечить дамп таблиц привилегий MySQL. Вы можете вывести таблицы с помощью mysqldump mysql . Чтобы зарегистрировать отчет об ошибках, см. инструкции в разделе 1.7. В некоторых случаях Вы, возможно, должны перезапустить mysqld с опцией --skip-grant-tables, чтобы выполнить mysqldump.

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

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

  • Значение имен учетной записи и паролей в MySQL и как это сравнивается с именами и паролями, используемыми Вашей операционной системой.

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

См. раздел 14.7.1.

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

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

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

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

  • Имена пользователя, использующиеся MySQL в целях аутентификации, не имеют никакого отношения к именам пользователя (имена для входа в систему) Windows или Unix. В Unix большинство клиентов MySQL по умолчанию пытается войти в систему, используя текущее имя пользователя Unix в качестве имени пользователя MySQL, но это только для удобства. Значение по умолчанию может быть переопределено легко, потому что программы клиента разрешают любому имени пользователя быть определенным с опцией -u или --user. Это означает, что любой может попытаться соединиться с сервером, используя любое имя пользователя, таким образом, Вы не можете сделать базу данных безопасной ни в каком случае, если у всех учетных записей MySQL нет паролей. Любой, кто определяет имя пользователя для учетной записи, у которой нет никакого пароля, в состоянии соединиться успешно с сервером.

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

    Предел длины имени пользователя MySQL жестко задан в серверах MySQL и клиентах, попытка обойти это, изменяя определения таблиц в базе данных mysql не сработает.

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

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

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

  • Пароли, сохраненные в таблице user, зашифрованы, используя определенные для плагина алгоритмы.
  • Если имя пользователя и пароль содержат только символы ASCII, возможно соединиться с сервером независимо от настроек набора символов. Чтобы соединиться, когда имя пользователя или пароль содержат символы не ASCII, клиент должен вызвать функцию C API mysql_options() с опцией MYSQL_SET_CHARSET_NAME и указать соответствующий набор символов как параметр. Это заставляет аутентификацию использовать указанный набор символов. Иначе аутентификация потерпит неудачу, если набор символов по умолчанию сервера не будет тем же самым.

    Стандартные программы клиента MySQL поддерживают опцию --default-character-set, которая вызывает mysql_options(), как только что описано. Кроме того, автоматическое обнаружение набора символов поддержано, как описано в разделе 11.1.4. Для программ, которые используют соединитель, который не основан на C API, соединитель может обеспечить эквивалент mysql_options(). Проверьте документацию соединителя.

    Предыдущие примечания не применяются к ucs2, utf16 и utf32, которые не разрешены как наборы символов клиента.

Процесс установки 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 двумя путями:

  • При использовании запросов, предназначенных для того, чтобы создать учетные записи и их привилегии, CREATE USER и GRANT. Эти запросы заставляют сервер делать соответствующие модификации к основным таблицам привилегий.

  • Управляя таблицами привилегий непосредственно такими запросами, как INSERT, UPDATE или DELETE.

Привилегированный метод должен использовать запросы управления, потому что они более кратки и менее подвержены ошибкам, чем управление таблицами привилегий непосредственно. Все такие запросы описаны в разделе 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';
У учетных записей, создаваемых этими запросами, есть следующие свойства:

  • У двух учетных записей есть имя пользователя monty и пароль some_pass. Это суперпользователи с полными привилегиями сделать что-либо. 'monty'@'localhost' может использоваться только соединяясь от местного узла. 'monty'@'%' использует символ подстановки '%' для части узла, таким образом, это может использоваться, чтобы соединиться от любого узла.

    'monty'@'localhost' необходим, если есть анонимная учетная запись пользователя для localhost. Без 'monty'@'localhost' та анонимная учетная запись пользователя имеет приоритет, когда monty соединяется от местного узла и monty обработан как анонимный пользователь. Причина этого состоит в том, что у анонимной учетной записи пользователя есть более определенное значение Host, чем у 'monty'@'%' и таким образом она окажется раньше в порядке сортировки таблицы user, см. раздел 7.2.5 .

  • 'admin'@'localhost' имеет пароль admin_pass. Эта учетная запись может использоваться только admin, чтобы соединяться от местного узла. Этому предоставляют привилегии RELOAD и PROCESS. Эти привилегии разрешают admin выполнить mysqladmin reload , mysqladmin refresh и mysqladmin flush-xxx, так же как mysqladmin processlist. Никакие привилегии не предоставляют для того, чтобы получить доступ к любым базам данных.
  • У 'dummy'@'localhost' нет никакого пароля (что опасно). Эта учетная запись может использоваться только, чтобы соединиться от местного узла. Никакие привилегии не предоставляются. Предполагается, что Вы предоставите определенные привилегии учетной записи через GRANT.

Чтобы видеть привилегии для учетной записи, надо использовать 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';
Три учетных записи могут использоваться следующим образом:

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

  • Вторая учетная запись может получить доступ к базе данных expenses, но только от узла host47.example.com.
  • Третья учетная запись может получить доступ к базе данных customer от любого узла в домене 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, делая два одновременных соединения клиента с сервером. Запросы на обоих соединениях посчитаны вместе.

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

  • Чтобы сбросить текущее количество к нолю для всех учетных записей, скомандуйте FLUSH USER_RESOURCES. Количество также может быть сброшено, перезагружая таблицы привилегий (например, FLUSH PRIVILEGES или mysqladmin reload ).

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

Сбросы часовых счетчиков не затрагивают 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.

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

  • Используйте ALTER USER с IDENTIFIED BY:

    mysql> ALTER USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
    
    Если Вы не соединены как анонимный пользователь, Вы можете изменить свой собственный пароль, не называя Вашу собственную учетную запись буквально:
    mysql> ALTER USER USER() IDENTIFIED BY 'mypass';
    
    Для ALTER USER MySQL автоматически хеширует пароль прежде, чем сохранить это в mysql.user.
  • Используйте SET PASSWORD с PASSWORD():
    mysql> SET PASSWORD FOR 'jeffrey'@'localhost' = PASSWORD('mypass');
    
    Если Вы не соединены как анонимный пользователь, Вы можете изменить свой собственный пароль, опуская FOR:
    mysql> SET PASSWORD = PASSWORD('mypass');
    
    Функция PASSWORD() хеширует пароль, используя хеширующий метод, определенный значением переменной old_passwords . Если SET PASSWORD отклоняет хешированное значение пароля, возвращенное PASSWORD() как не находящееся в правильном формате, может быть необходимо изменить old_passwords, чтобы изменить хеширующий метод. См. раздел 14.7.1.11.

    Использование SET PASSWORD ... = PASSWORD('auth_string') для модификации пароля устарело с MySQL 5.7.6. Используйте ALTER USER.

  • Используйте SET PASSWORD без PASSWORD():

    SET PASSWORD интерпретирует строку как строку открытого текста и хеширует это соответственно для плагина аутентификации учетной записи прежде, чем сохранить в mysql.user.

    mysql> SET PASSWORD FOR 'jeffrey'@'localhost' = 'mypass';
    
  • Используйте GRANT USAGE на глобальном уровне (ON *.*), чтобы изменить пароль учетной записи, не затрагивая привилегии текущего пользователя:
    mysql> GRANT USAGE ON *.* TO 'jeffrey'@'localhost'
        ->       IDENTIFIED BY 'mypass';
    
    Для GRANT MySQL автоматически хеширует пароль прежде, чем сохранить это в mysql.user.

    Использование GRANT для модификации паролей устарело в MySQL 5.7.6. Используйте ALTER USER.

  • Чтобы изменить пароль учетной записи из командной строки, используйте mysqladmin :

    shell> mysqladmin -u user_name -h host_name \
                         password "new_password"
    
    Учетка, для которой эта команда установит пароль, это строка таблицы mysql.user, которая соответствует user_name в столбце User и хосту клиента, с которого Вы соединяетесь в Host.

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

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 дней.

Примеры:

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

    [mysqld]
    default_password_lifetime=180
    
  • Чтобы установить глобальную политику, таким образом, что пароли никогда не истекают, надо установить default_password_lifetime = 0:
    [mysqld]
    default_password_lifetime=0
    
  • default_password_lifetime может также быть изменен во время выполнения (это требует привилегии SUPER):
    SET GLOBAL default_password_lifetime = 180;
    SET GLOBAL default_password_lifetime = 0;
    

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

  • Потребуйте, чтобы пароль был изменен каждые 90 дней:

    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
    
  • Отключите истечение пароля:
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    
  • Подчинитесь глобальной политике истечения:
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
    

Эти 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.
Если сервер помещает клиента в режим песочницы, эти операции разрешены в пределах сеанса клиента:

  • Клиент может сбросить пароль учетной записи с ALTER USER или SET PASSWORD. Это изменяет строку в mysql.user, устанавливая password_expired в 'N'. После того, как пароль был сброшен, сервер восстанавливает нормальный доступ для сеанса, так же как для последующих соединений, которые используют учетную запись.

  • Клиент может использовать SET, что полезно, если используется устаревший SET PASSWORD вместо ALTER USER и old_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_OPT_CAN_HANDLE_EXPIRED_PASSWORDS в mysql_options() до соединения с сервером:

    arg = 1;
    result = mysql_options(mysql,
                           MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &arg);
    
    mysql включает MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, если вызван в интерактивном режиме или имеет опцию --connect-expired-password.
  • Передать флаг CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS в mysql_real_connect() во время соединения:
    mysql = mysql_real_connect(mysql, host, user, password, "test",
                               port, unix_socket,
                               CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
    

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

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

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

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

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

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

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

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

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

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

  • Внешняя аутентификация: это позволяет клиентам соединиться с сервером MySQL с параметрами, которые являются подходящими для методов аутентификации кроме родной аутентификации, основанной на паролях, сохраненных в mysql.user. Например, плагины могут быть созданы, чтобы использовать внешние методы аутентификации, такие как PAM, Windows login ID, LDAP или Kerberos.

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

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

  • Плагин, который выполняет родную аутентификацию, которая соответствует паролю в столбце authentication_string. Плагин mysql_native_password осуществляет аутентификацию, основанную на этом родном методе хеширующего пароля. См. раздел 7.5.1.1. Родное использование аутентификации mysql_native_password не значение по умолчанию для новых учетных записей, если переменная default_authentication_plugin установлена иначе.

  • Плагин, который выполняет аутентификацию, используя хеширующий пароль SHA-256. Этот плагин соответствует паролю в столбце authentication_string. Это более сильное шифрование, чем доступное с родной аутентификацией. См. раздел 7.5.1.2.
  • Плагин предотвращает все соединения клиента с любой учетной записью, которая использует его. Случаи использования для такого плагина включают учетные записи, которые должны быть в состоянии выполнить сохраненные программы и представления с поднятыми привилегиями, не выставляя те привилегии обычным пользователям, и учетные записи по доверенности, которые никогда не должны разрешать прямой вход в систему. См. раздел 7.5.1.3.
  • Клиентский плагин, который посылает пароль в сервер, не хешируя. Этот плагин может использоваться серверными плагинами, которые требуют доступа к паролю точно в соответствии с пользователем клиента. См. раздел 7.5.1.4.
  • Плагин, который подтверждает подлинность клиентов, которые соединяются от местного узла через файл сокета Unix, см. раздел 7.5.1.5.
  • Испытательный плагин, который подтверждает подлинность с применением оригинальной аутентификации MySQL. Этот плагин предназначен для целей тестирования и развития и как пример того, как написать плагин аутентификации. См. раздел 7.5.1.6.

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

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

См. раздел 26.2.4.9 .

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

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

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

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

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

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

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

  • Серверное имя плагина test_plugin_server.

  • Клиентское имя плагина auth_test_plugin.
  • Оба плагина расположены в совместно используемом файле библиотеки auth_test_plugin.so в каталоге плагинов (указан в переменной plugin_dir). Суффикс имени файла может отличаться в Вашей системе.

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

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

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

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

      [mysqld]
      plugin-load=test_plugin_server=auth_test_plugin.so
      
    • Чтобы установить плагин во время выполнения, используйте INSTALL PLUGIN:
      INSTALL PLUGIN test_plugin_server SONAME 'auth_test_plugin.so';
      
      Это устанавливает плагин надолго и должно быть выполнено только однажды.

  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 происходит посредством плагинов аутентификации. Плагин, который подтверждает подлинность данного соединения, может просить, чтобы соединяющийся (внешний) пользователь был обработан как различный пользователь в проверке привилегий. Это позволяет внешнему пользователю быть полномочием для второго пользователя, то есть, чтобы иметь привилегии второго пользователя:

  • Внешний пользователь proxy user (пользователь, который может явиться олицетворением или стать известным как другой пользователь).

  • Второй пользователь proxied user (пользователь, идентичность которого может быть взята пользователем по доверенности).

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

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

  • Учетная запись пользователя по доверенности должна быть настроена, чтобы быть заверенной плагином. Используйте CREATE USER, чтобы связать учетную запись с плагином, или ALTER USER, чтобы изменить этот плагин.

  • Для клиента, соединяющегося с учетной записью по доверенности, которая будет обработана как пользователь по доверенности, плагин должен возвратить имя пользователя, отличающееся от имени пользователя клиента, чтобы указать на имя пользователя для учетной записи proxied.
  • Учетная запись пользователя по доверенности должна иметь привилегию PROXY для учетной записи proxied. Используйте GRANT.

Механизм по доверенности разрешает отображать только имя пользователя клиента на 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 можно предоставить в этих случаях:

  • Пользователем, который имеет GRANT PROXY ... WITH GRANT OPTION для proxied_user.

  • proxied_user для себя: значение USER() должно точно соответствовать CURRENT_USER() и proxied_user, для имени пользователя и для имени хоста учетной записи.

Начальная учетная запись 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 по умолчанию никогда не используется.

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

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

  • Используйте более определенного proxy пользователя по умолчанию, который соответствует перед анонимным пользователем. Например, чтобы разрешить только соединения localhost proxy, используйте ''@'localhost':
    CREATE USER ''@'localhost'
           IDENTIFIED WITH some_plugin AS 'some_auth_string';
    
    Кроме того, измените любой запрос GRANT PROXY на имя ''@'localhost' вместо ''@'' как пользователь по доверенности.

    Знайте, что эта стратегия предотвращает соединения анонимного пользователя от localhost.

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

    Создайте пользователей по доверенности:

    -- create proxy user for local connections
    CREATE USER ''@'localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string';
    -- create proxy user for remote connections
    CREATE USER ''@'%' IDENTIFIED WITH some_plugin AS 'some_auth_string';
    
    Создайте proxied пользователей:
    -- create proxied user for local connections
    CREATE USER 'developer'@'localhost' IDENTIFIED BY 'some_password';
    -- create proxied user for remote connections
    CREATE USER 'developer'@'%' IDENTIFIED BY 'some_password';
    
    Предоставьте привилегию по доверенности каждому пользователю по доверенности для соответствующего proxied пользователя:
    GRANT PROXY ON 'developer'@'localhost' TO ''@'localhost';
    GRANT PROXY ON 'developer'@'%' TO ''@'%';
    
    Наконец предоставьте соответствующие привилегии местным и удаленным proxied пользователям (не показано).

    Предположите, что комбинация some_plugin/'some_auth_string' отобразит имя пользователя клиента на developer. Местные соединения соответствуют proxy-пользователю ''@'localhost', который отображается на 'developer'@'localhost' proxied-пользователя. Удаленные соединения соответствуют proxy-пользователю ''@'%', который отображается на 'developer'@'%'.

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

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

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

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

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

  • Сервер не будет proxy к или от анонимного пользователя, даже если предоставлена связанная привилегия PROXY.

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

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

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

  • proxy_user : Это значение NULL, если proxying не используется. Иначе это указывает на учетную запись пользователя по доверенности. Например, если клиент подтверждает подлинность через учетную запись ''@'', эта переменная установлена следующим образом:

    mysql> SELECT @@proxy_user;
    +--------------+
    | @@proxy_user |
    +--------------+
    | ''@''        |
    +--------------+
    
  • external_user: Иногда плагин аутентификации может использовать внешнего пользователя, чтобы подтвердить подлинность. Например, используя аутентификацию Windows плагин, который подтверждает подлинность с применением windows API, не нуждается в идентификаторе для входа в систему, который ему передают. Однако, это все еще использует пользовательский ID Windows, чтобы подтвердить подлинность. Плагин может возвратить этот внешний пользовательский ID (или первые 512 байтов UTF-8 этого) серверу, используя переменную только для чтения external_user. Если плагин не устанавливает эту переменную, ее значение NULL.

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

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

  • Когда используются с 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() соответствует не пользователю клиента, а отличной учетной записи. Это происходит в контекстах, когда проверка привилегии не базируется на учетной записи клиента:

  • Сохраненные подпрограммы (процедуры и функции), определенные с SQL SECURITY DEFINER.

  • Представления, определенные с SQL SECURITY DEFINER.
  • Триггеры и события.

В тех контекстах проверка привилегии сделана против 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:

  • MySQL Enterprise Edition собран, используя OpenSSL. Невозможно использовать yaSSL с MySQL Enterprise Edition.

  • MySQL Community Edition собран, используя yaSSL.
  • MySQL Community Edition может быть собран, используя OpenSSL или yaSSL (см. раздел 7.4.2).

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

  • OpenSSL поддерживает более широкий диапазон шифров из которых можно выбрать для опции --ssl-cipher . OpenSSL поддерживает опции --ssl-capath , --ssl-crl и --ssl-crlpath , см. раздел 7.4.5.

  • Учетные записи, которые подтверждают подлинность с использованием плагина sha256_password, может использовать файлы ключа RSA для безопасной передачи пароля по незашифрованным соединениям. См. раздел 7.5.1.2.
  • Сервер может автоматически произвести сертификаты и ключи SSL и RSA при запуске. См. раздел 7.4.6.1.
  • OpenSSL поддерживает больше режимов шифрования для AES_ENCRYPT() и AES_DECRYPT(), см. раздел 13.13.

Определенная 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:

  • Когда собран, используя OpenSSL 1.0.1 или выше, MySQL поддерживает TLSv1, TLSv1.1 и TLSv1.2.

  • Если собран, используя связанную версию yaSSL, MySQL поддерживает TLSv1 и TLSv1.1.

Значение переменной 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:

  • Если сервер и клиент собраны, используя OpenSSL, TLSv1.2 используется, если возможно.

  • Если сервер и клиент собраны, используя yaSSL, используется TLSv1.1, если возможно.
  • TLSv1.2 не работает со всеми шифрами, у которых есть ключевой размер 512 битов или меньше. Чтобы использовать этот протокол с таким ключом, надо использовать --ssl-cipher, чтобы определить шифр явно:
    AES128-SHA
    AES128-SHA256
    AES256-SHA
    AES256-SHA256
    CAMELLIA128-SHA
    CAMELLIA256-SHA
    DES-CBC3-SHA
    DHE-RSA-AES256-SHA
    RC4-MD5
    RC4-SHA
    SEED-SHA
    
  • Для лучшей безопасности, используйте сертификат с размером ключа RSA 2048 битов или больше.

Если у сервера и клиента нет никакого общего протокола, сервер заканчивает запрос соединения. Например, если сервер сконфигурирован с 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
Эти ограничения шифра активны:

  • Следующие шифры всегда ограничены:

    !DHE-DSS-DES-CBC3-SHA
    !DHE-RSA-DES-CBC3-SHA
    !ECDH-RSA-DES-CBC3-SHA
    !ECDH-ECDSA-DES-CBC3-SHA
    !ECDHE-RSA-DES-CBC3-SHA
    !ECDHE-ECDSA-DES-CBC3-SHA
    
  • Следующие категории шифров всегда ограничены:
    !aNULL
    !eNULL
    !EXPORT
    !LOW
    !MD5
    !DES
    !RC2
    !RC4
    !PSK
    !SSLv3
    

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

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

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

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

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

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

  • --ssl-ca идентифицирует Центр сертификации (CA).

  • --ssl-cert идентифицирует сертификат открытого ключа сервера. Это можно послать клиенту и заверено сертификатом CA.
  • --ssl-key идентифицирует частный ключ сервера.

Например, запустите сервер с этих строк в 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.pem, server-cert.pem и server-key.pem в каталоге данных это включает поддержку безопасных соединений клиентами. Файлы не должны быть самодельными.

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

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

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

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

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

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

  • --ssl-ca идентифицирует Центр сертификации (CA). Эта опция, если используется, должна определить тот же самый сертификат, который используется сервером.

  • --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
Программы клиента пытаются установить безопасное соединение по умолчанию всякий раз, когда сервер поддерживает безопасные соединения:

  • В отсутствие --ssl-mode или --ssl, клиент отступает к незашифрованному соединению, если безопасное соединение не может быть установлено.

  • Чтобы потребовать безопасного соединения и потерпеть неудачу, если его нельзя установить, вызовите клиента с --ssl-mode=REQUIRED .
  • Чтобы использовать незашифрованное соединение, вызовите клиента с --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 mysql_ssl_set(), чтобы установить соответствующие опции сертификата перед запросом mysql_real_connect() . См. раздел 25.8.7.72. Чтобы потребовать использования безопасного соединения, вызовите mysql_options() с опцией MYSQL_OPT_SSL_MODE. Чтобы установить разрешенные протоколы шифрования, вызовите mysql_options() с опцией MYSQL_OPT_TLS_VERSION.

  • Чтобы определить, используется ли шифрование, после того, как соединение установлено, надо использовать mysql_get_ssl_cipher() . Не-NULL указывает на зашифрованное соединение и называет шифр, используемый для шифрования. NULL указывает, что шифрование не используется. См. раздел 25.8.7.34.

Репликация использует 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Протоколы, разрешенные для безопасных соединений
  • --ssl

    Опция клиента --ssl удалена в MySQL 8.0. Для программ клиента надо использовать --ssl-mode.

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

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

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

    • Если сервер обнаруживает допустимые сертификат и ключевые файлы ca.pem, server-cert.pem и server-key.pem в каталоге данных, это включает поддержку безопасных соединений с клиентами. Файлы не должны быть самодельными.

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

    Как рекомендуемый набор опций, чтобы включить безопасные соединения, используйте, по крайней мере, --ssl-cert и --ssl-key на стороне сервера и --ssl-ca на стороне клиента. См. раздел 7.4.4.

    --ssl подразумевается другими опциями --ssl-xxx, как обозначено в описаниях для тех опций.

    Опция --ssl в инвертированной форме переопределяет другие опции --ssl-xxx и указывает, что шифрование не должно использоваться. Чтобы сделать это, определите опцию как --ssl=0 или синоним (--skip-ssl , --disable-ssl ).

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

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

  • --ssl-ca= file_name

    Путь к файлу в формате PEM, который содержит список центров сертификации SSL, которым доверяют. На стороне сервера эта опция подразумевает --ssl.

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

  • --ssl-capath= dir_name

    Путь к каталогу, который содержит доверенные сертификаты центра сертификации SSL в формате PEM. На стороне сервера эта опция подразумевает --ssl.

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

    Дистрибутивы MySQL, собранные, используя OpenSSL, поддерживают --ssl-capath (см. раздел 7.4.1). Дистрибутивы, собранные, используя yaSSL этого не делают, поскольку yaSSL не смотрит ни в каком каталоге и не следует за цепочечным деревом сертификатов. yaSSL требует, чтобы все компоненты дерева сертификатов CA содержались в пределах одного дерева сертификатов CA и что каждый сертификат в файле имел уникальный SubjectName. Чтобы работать вокруг этого yaSSL ограничения, свяжите отдельные файлы сертификатов, включающие дерево сертификатов, в новый файл и определите этот файл как значение --ssl-ca .

  • --ssl-cert= file_name

    Название файла сертификата SSL в формате PEM, чтобы использовать для того, чтобы основать безопасное соединение. На стороне сервера эта опция подразумевает --ssl .

  • --ssl-cipher= cipher_list

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

    Для самой большой мобильности cipher_list должен быть списком из одного или более имен шифра, отделенных двоеточиями. Этот формат понят под OpenSSL и под yaSSL. Примеры:

    --ssl-cipher=AES128-SHA
    --ssl-cipher=DHE-RSA-AES256-SHA:AES128-SHA
    
    OpenSSL поддерживает более гибкий синтаксис для того, чтобы определить шифры, как описано в документации OpenSSL в http://www.openssl.org/docs/apps/ciphers.html. yaSSL не делает так, попытки использовать тот расширенный синтаксис терпят неудачу для MySQL, собранного, используя yaSSL.

    См. раздел 7.4.3.

  • --ssl-crl= file_name

    Путь к файлу, содержащему список аннулирования сертификатов в формате PEM. На стороне сервера эта опция подразумевает --ssl.

    Если ни одна из опцией --ssl-crl или --ssl-crlpath не дана, никакие проверки CRL не выполнены, даже если путь CA содержит списки аннулирования сертификатов.

    Дистрибутивы MySQL, собранные, используя OpenSSL, поддерживают опцию --ssl-crl (см. раздел 7.4.1). Дистрибутивы, собранные, используя yaSSL, это не делают, потому что списки аннулирования не работают с yaSSL.

  • --ssl-crlpath= dir_name

    Путь к каталогу, который содержит файлы, содержащие списки аннулирования сертификатов в формате PEM. На стороне сервера эта опция подразумевает --ssl.

    Если ни одна из опций --ssl-crl или --ssl-crlpath на задана, никакие проверки CRL не выполнены, даже если путь CA содержит списки аннулирования сертификатов.

  • --ssl-key= file_name

    Название файла ключа SSL в формате PEM, чтобы использовать для того, чтобы основать безопасное соединение. На стороне сервера эта опция подразумевает --ssl.

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

    Для лучшей безопасности, используйте сертификат с размером ключа RSA 2048 битов или больше.

  • --ssl-mode=mode

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

    • PREFERRED: Установить безопасное (зашифрованное) соединение, если сервер поддерживает безопасные соединения. Отступить к незашифрованному соединению иначе. Это значение по умолчанию, если не указана опция --ssl-mode.

    • DISABLED: Установить незашифрованное соединение.
    • REQUIRED: Установить безопасное соединение, если сервер поддерживает безопасные соединения. Попытка соединения терпит неудачу, если безопасное соединение не может быть установлено.
    • VERIFY_CA: Аналог REQUIRED, но дополнительно проверяет серверный сертификат TLS для сконфигурированных сертификатов Certificate Authority (CA). Попытка соединения терпит неудачу, если никакое допустимое соответствие CA не найдено.
    • VERIFY_IDENTITY: Аналог VERIFY_CA, но дополнительно проверяет, что сертификат сервера соответствует узлу, к которому предпринято соединение.

    Использование опции --ssl-ca или --ssl-capath подразумевает --ssl-mode=VERIFY_CA , если --ssl-mode явно не установлена иначе.

    Если --ssl-mode является явной, использование значения кроме VERIFY_CA или VERIFY_IDENTITY с явным --ssl-ca или --ssl-capath производит предупреждение, что никакая проверка сертификата сервера не будет сделана, несмотря на определяемые опции сертификата CA.

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

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

  • --tls-version=protocol_list

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

    На стороне сервера вместо этого может использоваться переменная 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.

Автогенерпция файлов и 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 И RSA составляют 2048 битов.

  • Сертификат SSL CA самоподписан.
  • Сертификаты клиента и сервера подписаны сертификатом CA и ключом, используя алгоритм подписи sha256WithRSAEncryption.
  • Сертификаты SSL используют Common Name (CN) с соответствующим типом сертификата (CA, Server, Client):
    ca.pem: MySQL_Server_suffix_Auto_Generated_CA_Certificate
    server-cert.pm: MySQL_Server_suffix_Auto_Generated_Server_Certificate
    client-cert.pm: MySQL_Server_suffix_Auto_Generated_Client_Certificate
    
    suffix основано на номере версии MySQL. Для файлов, произведенных mysql_ssl_rsa_setup, суффикс может быть определен явно, используя опцию --suffix.

    Для файлов, произведенных сервером, если получающиеся значения CN превышают 64 символа, часть имени _suffix опущена.

  • У файлов SSL есть пустые значения для Country (C), State or Province (ST), Organization (O), Organization Unit Name (OU) и адреса электронной почты.
  • Файлы SSL, создаваемые сервером или mysql_ssl_rsa_setup , допустимы в течение десяти лет со времени создания.
  • Файлы RSA не истекают.
  • У файлов SSL есть различные порядковые номера для каждой пары сертификата/ключа (1 CA, 2 Server, 3 Client).
  • Файлы, создаваемые автоматически сервером, принадлежат учетной записи, которая выполняет сервер. Файлы, созданные с использованием mysql_ssl_rsa_setup , принадлежат пользователю, который вызвал ту программу. Это может быть изменено на системах, которые поддерживают chown(), если программа вызвана root и опция --uid дана, чтобы определить пользователя, которому должны принадлежать файлы.
  • В Unix режим доступа к файлу 644 для файлов сертификата (то есть, читаемые миром) и 600 для ключевых файлов (то есть, доступны только учетной записью, которая выполняет сервер).

Чтобы видеть содержание сертификата 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
Теперь у Вас есть ряд файлов, которые могут использоваться следующим образом:
  • ca.pem: Используйте это в качестве параметра --ssl-ca на сторонах сервера и сторонах клиента. Сертификат CA, если используется, должен быть тем же самым с обеих сторон.

  • server-cert.pem, server-key.pem: Используйте их в качестве параметров --ssl-cert и --ssl-key на стороне сервера.
  • client-cert.pem, client-key.pem: Используйте их в качестве параметров --ssl-cert и --ssl-key на стороне клиента.

См. раздел 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 (показан ранее в этом разделе), со следующими изменениями:

  • Измените следующие команды Unix:

    # Create clean environment
    shell> rm -rf newcerts
    shell> mkdir newcerts && cd newcerts
    
    В Windows используйте эти команды вместо этого:
    # Create clean environment
    C:\> md c:\newcerts
    C:\> cd c:\newcerts
    
  • Когда символ '\' показывают в конце командной строки, он должен быть удален, и команды введены все в одну строку.

После производства сертификата и ключевых файлов, чтобы использовать их для соединений 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 включает несколько плагинов, которые осуществляют механизмы безопасности:

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

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

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
БиблиотекаНет (встроенный плагин)

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

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

  • Использование программ клиента MySQL mysql_native_password по умолчанию. Опция --default-auth может использоваться в качестве подсказки, который клиентский плагин программа может ожидать использовать:
    shell> mysql --default-auth=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, данной позже в этом разделе.

  • Для клиента возможно передать пароли к серверу, используя шифрование RSA во время процесса соединения клиента, как описано позже.

  • Сервер выставляет две дополнительных системных переменные, sha256_password_private_key_path и sha256_password_public_key_path. Это предназначено, чтобы администратор базы данных установил их в названия файлов пары частного и открытого ключа RSA при запуске сервера, если у ключевых файлов будут имена, которые отличаются от системных значений по умолчанию.
  • Сервер выставляет переменную состояния Rsa_public_key, которая выводит на экран значение открытого ключа RSA.
  • mysql и mysqltest поддерживают опцию --server-public-key-path, чтобы определить файл открытого ключа RSA явно.

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

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

  • Если соединение SSL не используется, но шифрование RSA доступно, пароль посылают в пределах незашифрованного соединения, но пароль RSA-зашифрован, чтобы предотвратить перехват. Когда сервер получает пароль, он дешифрует это. Скремблирование используется в шифровании, чтобы предотвратить повторные нападения.
  • Если соединение SSL не используется, и шифрование RSA недоступно, sha256_password вызывает попытку соединения потерпеть неудачу, потому что пароль нельзя послать, не будучи выставленным как открытый текст.

Как упомянуто ранее, шифрование пароля 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 двумя способами:

  • Администратор базы данных может обеспечить копию файла открытого ключа.

  • Пользователь клиента, который может соединиться с сервером некоторым другим путем, может использовать SHOW STATUS LIKE 'Rsa_public_key' и сохранить возвращенное значение ключа в файле.

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 или частную сеть.

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

  • Установить LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN в значение, которое начинается с 1, Y или y. Это включает плагин для всех соединений клиента.

  • mysql, mysqladmin и mysqlslap понимают опцию --enable-cleartext-plugin, которая включает плагину на основе вызова.
  • Функция C API mysql_options() понимает опцию MYSQL_ENABLE_CLEARTEXT_PLUGIN, которая включает плагин на основе соединения. Кроме того, любая программа, которая использует libmysqlclient и файлы опций может включить плагин включением enable-cleartext-plugin в группе опций, читаемых библиотекой клиента.

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 служит, чтобы проверить пароли и улучшить безопасность. Плагин выставляет ряд системных переменных, которые позволяют Вам определить политику пароля.

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

  • В запросах, которые назначают пароль, поставляемый в качестве значения открытого текста, плагин проверяет пароль по текущей политике пароля и отклоняет, если он слабый (запрос возвращает ошибку ER_NOT_VALID_PASSWORD ). Это затрагивает ALTER USER , CREATE USER, GRANT и SET PASSWORD. Пароли, данные как параметры PASSWORD() будут проверены также.

  • SQL-функция VALIDATE_PASSWORD_STRENGTH() оценивает силу потенциальных паролей. Функция берет параметр пароля и возвращает целое число от 0 (слабый) до 100 (сильный).

Например, пароль открытого текста в следующем запросе проверен. Под политикой пароля значения по умолчанию, которая требует, чтобы пароли были по крайней мере 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. Политика осуществляет все более и более строгие тесты пароля. Следующие описания относятся к значениям параметра по умолчанию, которые могут быть изменены, меняя соответствующие системные переменные.

  • LOW проверяет только длину пароля. Пароли должны быть по крайней мере из 8 символов.

  • MEDIUM добавляет условия, что пароли должны содержать по крайней мере 1 цифру, 1 символ нижнего регистра, 1 символ верхнего регистра и 1 специальный (не алфавитно-цифровой) символ.
  • STRONG добавляет условие, что подстроки пароля длиной 4 символа или больше не должны соответствовать словам в файле словаря, если он был задан.

Кроме того, 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[=value]

    Формат командной строки --validate-password[=value]
    Допустимые значения Тип enumeration
    Значение по умолчанию ON
    Корректные значения ON
    OFF
    FORCE
    FORCE_PLUS_PERMANENT

    Эта опция управляет, как сервер загружает validate_password при запуске. Значение должно быть одной из доступных для плагина опций, как описано в разделе 6.6.2. Например, --validate-password=FORCE_PLUS_PERMANENT говорит серверу загружать плагин при запуске и препятствует тому, чтобы это было удалено в то время, как сервер работает.

    Эта опция доступна только, если плагин validate_password был ранее зарегистрирован INSTALL PLUGIN или загружен --plugin-load . См. раздел 7.5.2.1.

Если 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_check_user_name

    Формат командной строки --validate_password_check_user_name
    Системная переменная Имя validate_password_check_user_name
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Типboolean
    Значение по умолчанию ON

    Сравниваются ли пароли с частью имени пользователя эффективной учетной записи пользователя текущего сеанса и отклонены, если они соответствуют. По умолчанию validate_password_check_user_name включена. Эта переменная управляет именем пользователя, соответствующим независимо от значения validate_password_policy.

    Когда validate_password_check_user_name включена, это имеет эти эффекты:

    • Проверка происходит во всех контекстах для которых плагин validate_password вызван, что включает такие запросы, как ALTER USER, SET PASSWORD и вызовы таких функций, как PASSWORD() и VALIDATE_PASSWORD_STRENGTH().

    • Если пароль то же самое, как имя пользователя или его обратное прочтение, соответствие происходит, и пароль отклонен.
    • Если пароль соответствует имени пользователя, VALIDATE_PASSWORD_STRENGTH() вернет 0, независимо от того, как другие переменные установлены.
    • Имена пользователя, используемые для сравнения, взяты от значений функций USER() и CURRENT_USER() для текущего сеанса. Пользователь, который имеет привилегию SUPER может выполнить запрос, чтобы установить пароль другого пользователя в имя того пользователя.
    • Только часть имени пользователя из функций USER() и CURRENT_USER() используется, часть имени хоста игнорируется. Если имя пользователя пусто, никакое сравнение не сделано.
    • Имя пользователя является чувствительным к регистру. Пароль и значения имени пользователя сравнены как двоичные строки.

  • validate_password_dictionary_file

    Системная переменная Имя validate_password_dictionary_file
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Типfile name

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

    По умолчанию у этой переменной есть пустое значение, и проверки словаря не выполнены. Чтобы включить проверки словаря, Вы должны установить эту переменную в непустое значение. Если файл называют как относительный путь, он интерпретируется относительно каталога серверных данных. Его содержание должно быть одним словом в нижнем регистре на строку. Содержание обработано как набор символов utf8. Максимальный разрешенный размер файла составляет 1 МБ.

    Для файла словаря, который будет использоваться во время проверки пароля, политика пароля должна быть установлена в 2 (STRONG), см. описание validate_password_policy. Каждая подстрока пароля длиной от 4 до 100 символов сравнивается со словами в файле словаря. Любое соответствие заставляет пароль быть отклоненным. Сравнения не являются чувствительными к регистру.

    Для VALIDATE_PASSWORD_STRENGTH() пароль проверен по всей политике, включая STRONG, таким образом, оценка силы включает проверку по словарю независимо от validate_password_policy.

    validate_password_dictionary_file может быть установлена во время выполнения, и назначение значения заставляет названный файл быть считанным без перезапуска.

  • validate_password_length

    Системная переменная Имя validate_password_length
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Тип integer
    Значение по умолчанию 8
    Минимум 0

    Минимальное число символов в пароле, который проверяет validate_password. Эта переменная недоступна, если плагин не установлен.

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

    validate_password_number_count + validate_password_special_char_count +
    (2 * validate_password_mixed_case_count)
    
    Если плагин validate_password корректирует значение validate_password_length из-за предыдущего ограничения, это пишет сообщение в журнал ошибок.
  • validate_password_mixed_case_count

    Системная переменная Имя validate_password_mixed_case_count
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Тип integer
    Значение по умолчанию 1
    Минимум 0

    Минимальное число символов нижнего регистра и символов верхнего регистра, которые должен иметь пароль, если политика MEDIUM или строже. Для данного значения у пароля должно быть это количество символов нижнего регистра и столько же символов верхнего регистра. Эта переменная недоступна, если тот плагин не установлен.

  • validate_password_number_count

    Системная переменная Имя validate_password_number_count
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Тип integer
    Значение по умолчанию 1
    Минимум 0

    Минимальное число числовых символов, которые пароль должен иметь, если политика пароля MEDIUM или строже. Эта переменная недоступна, если тот плагин не установлен.

  • validate_password_policy

    Системная переменная Имя validate_password_policy
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Тип enumeration
    Значение по умолчанию 1
    Корректные значения 0
    1
    2

    Политика пароля, проведенная в жизнь плагином validate_password. Эта переменная недоступна, если плагин не установлен.

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

    validate_password_policy может быть определена, используя числовые значения 0, 1, 2, или соответствующие символические значения LOW, MEDIUM, STRONG. Следующая таблица описывает тесты, выполненные для каждой политики. Для теста длины необходимая длина это значение validate_password_length. Точно так же необходимые значения для других тестов даны другими переменными validate_password_xxx.

    ПолитикаВыполненные тесты
    0 или LOW Длина.
    1 или MEDIUMДлина, нижний регистр/верхний регистр, числа и специальные символы.
    2 или STRONGДлина, нижний регистр/верхний регистр, числа и специальные символы, словарь.
  • validate_password_special_char_count

    Системная переменная Имя validate_password_special_char_count
    Область действия Глобальная
    Динамическая Да
    Допустимые значения Типinteger
    Значение по умолчанию 1
    Минимум 0

    Минимальное число неалфавитно-цифровых символов, которые пароль должен иметь, если политика пароля MEDIUM или строже. Эта переменная недоступна, если плагин не установлен.

Если 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 поддерживает службу брелока, которая позволяет внутренним серверным компонентам и плагинам надежно хранить чувствительную информацию для более позднего извлечения. Выполнение основано на плагине:

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

    Плагин keyring_file для управления ключом шифрования не предназначен как решение для соответствия установленным требованиям. Стандарты безопасности, такие как PCI, FIPS и другие требуют, чтобы использование систем ключевого менеджмента обеспечило управление и защиту ключи шифрования в ключевых хранилищах или модулях безопасности аппаратных средств (HSM).

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

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:

  • Использование загрузки плагина --plugin-load или --plugin-load-add происходит после инициализации InnoDB.

  • Плагины, установленные с использованием INSTALL PLUGIN, зарегистрированы в таблице mysql.plugin и загружены автоматически для последующих перезапусков сервера. Однако, потому что mysql.plugin таблица InnoDB, любые плагины, названные в ней, может быть загружены во время запуска только после инициализации 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 UDF, keyring_udf должен быть включен. Иначе ошибка происходит:

    ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate';
    This function requires keyring_udf plugin which is not installed.
    Please install
    
    См. раздел 7.5.3.3.1.
  • UDF брелока вызывают служебные функции брелока (см. раздел 26.3.2). Служебные функции в свою очередь используют плагин брелока, который установлен. Поэтому, чтобы использовать любые UDF брелока, некоторый основной плагин брелока должен быть включен. Иначе ошибка происходит:
    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.
    
    См. раздел 7.5.3.1.
  • Чтобы использовать любой UDF, пользователь должен обладать привилегией EXECUTE на глобальном уровне. Иначе ошибка происходит:
    ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate';
    The user is not privileged to execute this function.
    User needs to have EXECUTE
    
    Чтобы предоставить на глобальном уровне пользователю привилегию EXECUTE, используйте этот запрос:
    GRANT EXECUTE ON *.* TO user;
    
  • Ключом, сохраненным в брелоке данным пользователем, может управлять позже только тот же самый пользователь. Таким образом, значение функции CURRENT_USER() во время ключевой манипуляции должно быть то же самое, как тогда, когда ключ был сохранен в брелоке. Это ограничение исключает использование UDF брелока для манипуляции ключами всего сервера.

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

  • UDF брелока поддерживают ключевые типы и длины, поддержанные основным плагином брелока, за исключением того, что ключи не могут быть более длинными, чем 2048 байтов (16384 бит).

Чтобы создать новый случайный ключ и сохранить это в брелоке, вызовите 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 доступны:

  • keyring_key_fetch()

    Учитывая ключевое ID, возвращает значение ключа.

    Синтаксис:

    STRING keyring_key_fetch(STRING key_id)
    
    Параметры:

    • key_id: ID ключа как строка.

    Возвращаемые значения:

    Возвращает значение ключа для успеха, NULL, если ключ не существует или NULL и ошибку для отказа.

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

    Пример:

    mysql> SELECT keyring_key_generate('RSA_key', 'RSA', 16);
    +--------------------------------------------+
    | keyring_key_generate('RSA_key', 'RSA', 16) |
    +--------------------------------------------+
    | 1                                          |
    +--------------------------------------------+
    
    mysql> SELECT HEX(keyring_key_fetch('RSA_key'));
    +-----------------------------------+
    | HEX(keyring_key_fetch('RSA_key')) |
    +-----------------------------------+
    | 91C2253B696064D3556984B6630F891A  |
    +-----------------------------------+
    
    mysql> SELECT keyring_key_type_fetch('RSA_key');
    +-----------------------------------+
    | keyring_key_type_fetch('RSA_key') |
    +-----------------------------------+
    | RSA                               |
    +-----------------------------------+
    
    mysql> SELECT keyring_key_length_fetch('RSA_key');
    +-------------------------------------+
    | keyring_key_length_fetch('RSA_key') |
    +-------------------------------------+
    | 16                                  |
    +-------------------------------------+
    
    В качестве примера применена HEX() , чтобы вывести на экран значение ключа, потому что это может содержать непригодные для печатания символы. Пример также использует короткий ключ для краткости, но ключи большей длины обеспечивают лучшую безопасность.
  • keyring_key_generate()

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

    Синтаксис:

    STRING keyring_key_generate(STRING key_id, STRING key_type,
                                INTEGER key_length)
    
    Параметры:

    • key_id: Ключевое ID как строка.

    • key_type: Ключевой тип как строка.
    • key_length: Длина ключа в байтах как целое число. Максимальная длина 2048.

    Возвращаемые значения:

    Возвращает 1 для успеха или NULL и ошибку для отказа.

    Пример:

    mysql> SELECT keyring_key_generate('RSA_key', 'RSA', 384);
    +---------------------------------------------+
    | keyring_key_generate('RSA_key', 'RSA', 384) |
    +---------------------------------------------+
    | 1                                           |
    +---------------------------------------------+
    
  • keyring_key_length_fetch()

    Учитывая ключевое ID, возвращает длину ключа.

    Синтаксис:

    INTEGER keyring_key_length_fetch(STRING key_id)
    
    Параметры:

    • key_id: Ключевое ID как строка.

    Возвращаемые значения:

    Возвращает длину ключа в байтах как целое число для успеха, NULL, если ключ не существует, или NULL и ошибку для отказа.

    Пример:

    См. описание keyring_key_fetch().

  • keyring_key_remove()

    Удаляет ключ с данным ID из брелока.

    Синтаксис:

    INTEGER keyring_key_remove(STRING key_id)
    
    Параметры:

    • key_id: Ключевое ID как строка.

    Возвращаемые значения:

    Возвращает 1 для успеха или NULL для отказа.

    Пример:

    mysql> SELECT keyring_key_remove('AES_key');
    +-------------------------------+
    | keyring_key_remove('AES_key') |
    +-------------------------------+
    | 1                             |
    +-------------------------------+
    
  • keyring_key_store()

    Шифрует и хранит ключ в брелоке.

    Синтаксис:

    INTEGER keyring_key_store(STRING key_id, STRING key_type, STRING key)
    
    Параметры:

    • key_id: Ключевое ID как строка.

    • key_type: Ключевой тип как строка.
    • key: Значение ключа как строка.

    Возвращаемые значения:

    Возвращает 1 для успеха или NULL и ошибку для отказа.

    Пример:

    mysql> SELECT keyring_key_store('new key', 'DSA', 'My key value');
    +-----------------------------------------------------+
    | keyring_key_store('new key', 'DSA', 'My key value') |
    +-----------------------------------------------------+
    | 1                                                   |
    +-----------------------------------------------------+
    
  • keyring_key_type_fetch()

    Учитывая ключевое ID, возвращает ключевой тип.

    Синтаксис:

    STRING keyring_key_type_fetch(STRING key_id)
    
    Параметры:

    • key_id: Ключевое ID как строка.

    Возвращаемые значения:

    Возвращает ключевой тип как строку для успеха, NULL, если ключ не существует, или NULL и ошибку для отказа.

    Пример:

    См. описание keyring_key_fetch().

Поиск

 

Найди своих коллег!

Вы можете направить письмо администратору этой странички, Алексею Паутову. mailto:alexey.v.pautov@mail.ru