Администрирование MySQL

Безопасность

Разбить на страницы
Показывать лекцию целиком

В лекции 2, "Общее администрирование MySQL", уже были затронуты такие важные аспекты безопасности, как установка пароля основного MySQL-пользователя root и настройка учетных записей пользователей. В этой лекции детально описываются следующие моменты.

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

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

  • Какой риск несет в себе подключение пользователей к серверу через сеть (внешняя безопасность) и как его минимизировать.

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

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

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

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

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

    Максимальную защиту необходимо обеспечить следующим категориям.

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

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

    Важность подобной защиты еще более подчеркивается тем фактом, что в файлах журналов регистрируются даже запросы с операторами grant и SET password, включающие пароли. (Вообще-то, в MySQL используется шифрование паролей, однако оно применяется только после установления соединения с предварительной проверкой пароля. Процесс же установки пароля включает выполнение таких операторов, как GRANT, INSERT и SET PASSWORD. В файлы журналов они заносятся в обычной текстовой форме.) Взломщику, получившему доступ к файлам журналов, достаточно запустить команду grep, чтобы раскрыть важную информацию операторов grant и password.

  • Не следует предоставлять пользователям компьютера, на котором установлен сервер, права записи для файлов каталога данных, поскольку они могут легко повредить файлы состояния и таблицы баз данных. Не менее опасен и доступ с правами чтения. Обладая возможностью чтения файлов таблицы, очень легко "украсть" эти файлы и позволить другому серверу MySQL самому показать содержимое таблицы в виде простого текста. Как? Да очень просто.

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

  • Запустите сценарий mysql_install_db для инициализации каталога данных. Это позволит получить доступ к серверу в качестве MySQL-пользователя root, получив полный контроль над механизмом доступа. Параллельно будет создана база данных test.

  • Скопируйте файлы, соответствующие "украденной" таблице или таблицам в подкаталог test каталога данных сервера.

  • Запустите второй сервер. Вот те на! Доступ к таблицам открыт. Оператор show tables from test указывает на наличие копий "украденных" таблиц, а с помощью оператора SELECT * можно увидеть их содержимое.

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

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

    Для определения, расположены ли в каталоге данных какие-либо незащищенные файлы и подкаталоги, достаточно запустить в нем команду ls -l. Найдите все файлы и каталоги, для которых активизированы "групповые" или "другие" полномочия. Вот для примера краткий список незащищенных элементов каталога данных, среди которых встречаются и подкаталоги баз данных.

    % ls -l
      total 10148
      drwxrwxr-x   11 mysqladm  wheel    1024  May   8  12:20 .
      drwxr-xr-x   22 root      wheel     512  May   8  13:31 ..
      drwx------    2 mysqladm  mysqlgrp  512  Apr  16  15:57 menagerle
      drwxrwxr-x    2 mysqladm  wheel     512  Jan  25  20:43 mysql
      drwxrwxr-x    7 mysqladm  wheel     512  Aug  31   1998 sql-bench
      drwxrwxr-x    2 mysqladm  wheel    1536  May   6  06:11 test
      drwx------    2 mysqladm  wheel    1024  May   8  18:43 tmp

    Как видите, для доступа к одним каталогам используются правильные полномочия, для других — нет. Такая ситуация стала результатом использования сервера в течение долгого периода времени. Менее ограничивающие полномочия созданы более старыми версиями серверов, которые были менее жестки в отношении прав доступа, чем новые. (Обратите внимание, что наиболее ограничивающие доступ каталоги menagerie и tmp имеют более позднее время создания.) Последние версии MySQL обязательно проверят, чтобы эти файлы смогли прочитать только пользователи, под именем которых работает сервер.

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

  • Перейдите в каталог данных:

    % cd DATADIR
  • Присвойте права владения всеми файлами каталога данных одной учетной записи, под управлением которой запускается сервер. (Эту операцию необходимо выполнить, зарегистрировавшись в качестве пользователя root.) В данном пособии для такой учетной записи используются имя пользователя mysqladm и группы mysqlgrp. Изменить права владения можно с помощью одной из следующих команд:

    # chown -R mysqladm.mysqlgrp . 
    # find . -follow -type d -print|xargs chown mysqladm.mysqlgrp
  • Измените режим доступа к каталогу данных и каталогам баз данных, чтобы прочитать их смог только пользователь mysqladm. В результате этого доступ к каталогу данных не смогут получить другие пользователи. Изменить режим можно с помощью одной из приведенных ниже команд, зарегистрировавшись в качестве пользователя root или mysqladm (последнее предпочтительней, поскольку позволяет минимизировать число команд, запущенных пользователем root ):

    % chmod -R go-rwx 
    % find . -follow -type d -print | xargs chmod go-rwx
  • Теперь права владения и режим содержимого каталога данных присвоены пользователю mysqladm. Осталось убедиться, что сервер отныне будет запускаться в качестве пользователя mysqladm, поскольку только этот пользователь имеет доступ к каталогу данных. Процедура запуска сервера в качестве нового пользователя (не root ) детально описана в лекции 2, "Общее администрирование MySQL".

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

    % ls -l
    	total 10148
    	drwxrwxr-x   11 mysqladm  wheel    1024  May   8  12:20 .
    	drwxr-xr-x   22 root      wheel     512  May   8  13:31 ..
    	drwx------    2 mysqladm  mysqlgrp  512  Apr  16  15:57 menagerle
    	drwxrwxr-x    2 mysqladm  wheel     512  Jan  25  20:43 mysql
    	drwxrwxr-x    7 mysqladm  wheel     512  Aug  31   1998 sql-bench
    	drwxrwxr-x    2 mysqladm  wheel    1536  May   6  06:11 test
    	drwx------    2 mysqladm  wheel    1024  May   8  18:43 tmp
    	...

    Внешняя безопасность: защита сетевого доступа

    Система безопасности MySQL достаточно гибка, поскольку позволяет настроить привилегии доступа пользователей множеством различных способов. Как правило, установка привилегий реализуется с помощью операторов GRANT и revoke, которые изменяют таблицы разрешений, управляющие клиентским доступом. Некоторые администраторы, тем не менее, все еще используют старые версии MySQL, которые не поддерживают эти операторы (до версии MySQL 3.22.11). Иногда также администраторы замечают, что при установке с помощью операторов GRANT и REVOKE привилегии функционируют не так, как хотелось бы. В подобных ситуациях весьма полезным может оказаться знание таблиц разрешений MySQL и принципов использования их сервером для определения полномочий. Владеющий подобными знаниями администратор может добавлять, удалять или изменять привилегии пользователей посредством изменения собственно таблиц разрешений. Более того, исследование таблиц позволяет гораздо быстрей диагностировать проблемы, связанные с доступом.

    Автор предполагает, что читатель уже ознакомился с материалом лекции 3 "Управление пользовательскими учетными записями", лекции 2 "Общее администрирование MySQL" и разобрался в принципах работы операторов grant и revoke. Их применение — удобный способ установки пользовательских учетных записей MySQL и связанных с ними привилегий. Но эти операторы являют собой лишь оболочку. Реальные действия выполняются в таблицах разрешений сервера MySQL.

    Структура и содержимое таблиц разрешений MySQL

    Управление доступом к базам данных MySQL для клиентов, подключившихся к серверу через сеть, осуществляется с помощью содержимого таблиц разрешений. Эти таблицы входят в состав базы данных mysql и инициализируются в процессе инсталляции MySQL на компьютере. В табл. 1 и 2 представлено краткое описание структур пяти таблиц разрешений:

    user, db, host, 
    tables_priv И columns_priv.
    Структура таблиц разрешений user, db и host
    Столбцы области доступа
    user db host
    host host host
    user db db
    password user
    Столбцы привилегий базы данных / таблицы
    Alter priv Alter priv Alter priv
    Create priv Create priv Create priv
    Delete priv Delete priv Delete priv
    Drop priv Drop priv Drop priv
    Index priv Index priv Index priv
    Insert priv Insert priv Insert priv
    References priv References priv References priv
    Select priv Select priv Select priv
    Update priv Update priv Update priv
    Столбцы административных привилегий
    File priv Grant priv Grant priv
    Grant priv
    Process priv
    Reload priv
    Shutdown priv
    Структура таблиц привилегий tables privt и columns privt
    Столбцы области доступа
    Tables priv columns priv
    Host Host
    Db Db
    User User
    Table name Table name
    Column name
    Столбец привилегий
    Table priv Column priv

    Таблицы разрешений содержат следующую информацию.

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

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

  • host. Таблица host применяется вместе с таблицей db и определяет привилегии доступа к базам данных определенного компьютера. Уровень этого контроля более высокий, чем при использовании одной лишь таблицы db. Операторы GRANT и REVOKE не могут изменять содержимое этой таблицы, поэтому на некоторых компьютерах она вообще не используется.

  • tables_priv. Таблица tables_priv определяет привилегии доступа к таблицам. Эти привилегии применимы ко всем столбцам определенной таблицы.

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

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

    Таблицы tablespriv и columspriv впервые появились в MySQL версии 3.22.11 (вместе с оператором grant ). Поэтому администраторы старых версий MySQL могут найти в базе данных mysql своего сервера только таблицы user, db и host. Если же эти таблицы не появляются даже после обновления до версии 3.22.11 или более поздней, запустите для их создания сценарий mysql_fix_privileges_tables.

    Отсутствие таблицы rowpriv объясняется невозможностью предоставления в MySQL привилегий на уровне строк. Нельзя, например, предоставить пользователю доступ только к отдельным строкам таблицы. Обеспечить подобную возможность реально можно только посредством написания соответствующей программы. Для блокировки данных на уровне записей можно использовать функцию get_lock().

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

    Столбцы области применения таблицы разрешений

    Столбцы области применения таблицы разрешений определяют, когда же применяются записи таблиц. Каждый элемент таблицы разрешений включает значения столбцов User и Host. Эти значения определяют, что данный элемент применяется при подключении определенного пользователя ( User ) к конкретному компьютеру ( Host ). (Таблица Host является исключением в этом отношении. Она используется особым способом, который в данной лекции не рассматривается.) Кроме того, другие таблицы могут содержать дополнительные столбцы. Таблица db, например, включает также столбец Db, определяющий базу данных, к которой применяется запись. Аналогичным образом таблицы tables_priv и columns_priv содержат поля области, которые ограничивают область применения записи до отдельной таблицы базы данных или отдельного столбца таблицы.

    Столбцы привилегий таблицы разрешений

    Таблицы разрешений включают также столбцы привилегий. Именно они определяют, какие привилегии предоставляются описанному в столбцах области пользователю. Поддерживаемые сервером MySQL привилегии приведены в списке, представленном ниже. В этом списке указываются названия привилегий, используемые в строке оператора GRANT. В большинстве случаев названия столбцов привилегий таблиц user, db и host сходны (по очевидным причинам) с названиями привилегий. Столбец Select_priv, например, соответствует привилегии SELECT.

    Привилегии баз данных и таблиц

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

  • ALTER. Позволяет использовать оператор alter table. Вообще, ALTER — это привилегия первого уровня. Для обработки таблиц необходимо предоставить дополнительные привилегии в зависимости от того, какие операции необходимо выполнять.

  • CREATE. Позволяет создавать базы данных и таблицы, но не индексы.

  • DELETE. Позволяет удалять записи из таблиц.

  • DROP. Позволяет удалять таблицы и базы данных, но не индексы.

  • INDEX. Позволяет создавать и удалять индексы в таблице.

  • INSERT. Позволяет вставлять новые записи в таблицы.

  • REFERENCES. В настоящее время не используется.

  • SELECT. Позволяет извлекать данные из таблиц с помощью операторов select. Эту привилегию необязательно присваивать для исполнения операторов select, не связанных с таблицами, например, SELECT NOW() ИЛИ SELECT 4/2

  • UPDATE. Позволяет изменять записи таблицы.

  • Административные привилегии

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

  • FILE. Позволяет давать серверу задание на считывание или запись файлов. Эту привилегию рекомендуется присваивать лишь в особых случаях. Поэтому сервер также предпринимает определенные меры предосторожности, позволяющие установить границы применения этой привилегии. Так, пользователи могут считывать файлы, которые доступны для чтения во всей системе. Невозможно записать файл, который уже существует на диске. Это позволяет избегать путаницы с критически важными файлами сервера, например /etc/passwd, или файлами чужих баз данных. Отсутствие подобного ограничения может привести к полной замене содержимого таблиц разрешений базы данных mysql.

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

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

  • PROCESS. Позволяет просматривать информацию о выполняемых внутри сервера нитях (процессах) с помощью оператора SHOW

  • PROCESSLIST или команды mysqladmin processlist. Эта же привилегия позволяет завершить выполнение процесса с помощью оператора KILL или команды mysqladmin kill.

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

  • reload. Позволяет выполнять множество операций администрирования сервера, например запускать SQL-оператор FLUSH или выполнять такие mysqladmin -команды, как reload, refresh, flush-hosts, flush-logs, flush-privileges и flush-tables. Даже несмотря на административные функции, эта привилегия не является опасной.

  • shutdown. Позволяет завершать работу сервера с помощью команды mysqladmin shutdown.

  • В таблицах user, db и host каждая привилегия определена в отдельном столбце. Все эти столбцы описаны типом ENUMC"N", "Y", и по умолчанию каждая привилегия имеет значение "n" (отключена). Привилегии таблиц tables_priv и column_priv представлены с помощью типа set, благодаря чему привилегии могут определяться различными комбинациями в одном столбце. Более эффективное представление привилегий в последних двух таблицах объясняется тем, что они появились гораздо позже, чем первые три. (Вполне возможно, что в будущем таблицы user, db и host будут реорганизованы и привилегии в них будут задаваться с помощью типа set.)

    Например, столбец Table_priv таблицы tables_priv определяется следующим образом:

    SET('Select','Insert','Update','Delete','Create',
       'Drop','Grant', 'Reference','Index','Alter')

    Столбец Column_priv таблицы column_priv определяется так:

    SET ('Select' , 'Insert','Update','Reference')

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

    Таблица user, помимо всего прочего, содержит несколько привилегий, которые отсутствуют во всех других таблицах разрешений: File priv, Process priv, Reload_priv и Shutdown_priv. Эти привилегии применяются к выполняемым сервером операциям, не связанным с отдельной базой данных или таблицей. Ведь при необходимости завершения работы сервера вовсе не обязательно проверять, над какой базой данных в настоящее время ведется работа.

    Как сервер управляет доступом клиентов

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

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

    Содержимое столбцов области доступа

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

    Host. Значение столбца Host может представлять собой имя компьютера или его IP-адрес. Значение localhost соответствует локальному компьютеру, однако рекомендуется использовать его только в том случае, если данный компьютер действительно имеет имя localhost. Представим ситуацию, когда локальный компьютер имеет имя pit.viper.snake и для одного пользователя имеется две записи в таблице user. Одна запись в столбце Host имеет значение localhost, а вторая — pit-viper.snake.net. Первая запись будет использоваться только при подключении к компьютеру localhost, а вторая — к компьютеру pit-viper.snake.net. Если необходимо, чтобы пользователи имели возможность подключиться с помощью любого из этих способов, следует оставить обе эти записи в таблице user.

    Значения столбца Host также можно задать с помощью шаблона. Так, можно использовать распространенные в SQL символы "%" и "_", имеющие такое же значение, как и в строке запроса с оператором like. (REGEX-шаблоны для этих целей неприменимы.) Символы шаблона SQL можно применять при определении как имен, так и IP-адресов. Строке %.wisc.edu, например, соответствуют все компьютеры домена wisc.edu, а строке %.edu — компьютеры всех подключенных к сети организаций системы образования. Аналогичным образом, строка 192.168.% описывает все компьютеры подсети класса В 192.168, а строка 192.168.3.% — все компьютеры подсети класса С 192.168.3.

    Значение "%" определяет все компьютеры и дает возможность пользователю подключиться из любой точки. Пустое значение столбца Host аналогично значению "!". (Исключение: в таблице db пустое значение столбца Host указывает на необходимость проверки таблицы host для получения более детальной информации)

    В версиях MySQL серии 3.23 можно также определить числа IP-адресов с помощью маски сети, отражающей разрядность сетевого номера. Строка 192.168.128.0/17, например, определяет 17 разрядный сетевой номер. Ей соответствует любой компьютер, первые 17 разрядов IP-адреса которого аналогичны разрядам адреса 192 .168 .128.

  • User. Имена пользователей могут задаваться буквенными или пустыми значениями. В последнем случае сможет подключиться любой пользователь. Значение "%" и пустое значение в столбце User — это не одно и то же. Оно соответствует пользователю с именем "%". Надо признать, такое имя встречается довольно редко.

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

  • Password. Значения этого столбца могут быть либо пустыми, либо буквенными. Специальные символы в них использовать нельзя. Пустое значение не является аналогией "любого пароля". Когда в таблице определено пустое значение столбца Password, пользователь не должен определять пароль вовсе.

    Значения паролей хранятся в зашифрованном, а не в обычном текстовом виде. Пользователи не смогут подключиться к серверу, если в столбец Password записываются обычные текстовые значения! Оператор GRANT и команда mysqladmin password автоматически шифруют пароль. Поэтому при непосредственной записи паролей с помощью команд INSERT, replace, update и set password следует зашифровать их значения с помощью команды PASSWORD("new_password").

  • Db. Значения столбца Db в таблицах columns_priv и tables_priv обязательно должны представлять собой текстовые имена баз данных. Использование специальных символов и пустых значений запрещается. В таблицах db и host эти значения можно определить как в виде текстовых значений, так и с помощью SQL-символов "%" и "_". Пустое значение и значение % позволяют получить доступ к любой базе данных.

  • Table_name, Column_name. Значения этих столбцов представляют собой текстовые записи имен таблиц и столбцов. Использование специальных символов и пустых значений запрещается.

    Регистр символов в некоторых столбцах области играет важное значение, а в остальных столбцах значения могут быть записаны как строчными, так и прописными буквами. Регистры символов в таких столбцах воспринимаются сервером по-разному. Это показано в табл. 3. Необходимо заметить, что регистр значений столбца Table_name всегда имеет значение, хотя учет регистра в именах таблиц в запросах зависит от файловой системы, под управлением которой работает сервер (под управлением UNIX выбор регистра важен, а под управлением Windows — нет).

    Учет регистра в столбцах области таблиц разрешений
    Столбец Учет регистра
    Host нет
    User да
    Password да
    Db да
    Table name да
    Column name нет
  • Проверка запроса

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

  • При первоначальном подключении сервер проверяет записи таблицы user, пытаясь определить глобальные привилегии подключающегося пользователя. Если таковые имеются и, более того, являются достаточными для выполнения запроса, сервер обрабатывает запрос.

  • Если имеющихся глобальных привилегий недостаточно, сервер ищет дополнительные привилегии в таблице db. Если найденные привилегии позволяют выполнить запрос, сервер его обрабатывает.

  • Как хранятся пароли в таблице user

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

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

  • Если набора глобальных привилегий и привилегий баз данных недостаточно, сервер продолжает поиск сначала в таблице tables_priv, a потом и в columns_priv.

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

  • Говоря на языке булевой алгебры, привилегии таблиц разрешений используются сервером следующим образом: user OR db OR tables_priv OR columns_priv

    Некоторые читатели уже, возможно, задаются вопросом, почему в этой записи указывается четыре таблицы разрешений, хотя на самом деле их пять. Совершенно верно. Правильней было бы переписать ее следующим образом: user OR (db AND host) OR tables_pnv OR columns_priv

    Упрощенный вариант был представлен исключительно для того, чтобы показать, что таблица host не подвержена влиянию операторов grant и REVOKE. Администраторы, управляющие привилегиями пользователей с помощью операторов grant и revoke, могут забыть о таблице host по следующим причинам.

  • Проверяя привилегии уровня базы данных, сервер ищет запись для клиента в таблице db. Пустое значение столбца Host означает примерно следующее: проверьте таблицу host, чтобы определить, какие компьютеры могут получать доступ к базе данных.

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

    Привилегии объединяются посредством логического оператора and. Это означает, что пользователь будет иметь привилегии только в том случае, когда записи о нем будут представлены в обеих таблицах. Таким образом, пользователю может присваиваться базовый набор привилегий в записи таблицы db. Согласно записям таблицы host, получить их можно будет только с определенных компьютеров. Так, например, можно предоставить доступ к базам данных со всех компьютеров домена, но убрать эти привилегии для пользователей компьютеров, расположенных в менее защищенной области.

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

    Например, если новый пользователь создается администратором путем добавления новой записи в таблицу user с помощью оператора insert, он не сможет сразу же подключиться к серверу. Начинающих администраторов (а иногда и вполне опытных) это зачастую весьма сильно раздражает, хотя решение этой проблемы предельно просто: достаточно указать серверу перезагрузить таблицы разрешений сразу после внесения изменений. Это можно осуществить с помощью оператора FLUSH PRIVILEGES или команды mysqladmin flush-privileges (либо mysqladmin reload, если используется более старая версия, не поддерживающая flush-privileges ).

    Порядок сравнения столбцов

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

    Считывая содержимое таблицы user, сервер сортирует ее записи, согласно значениям столбцов Host и User. Доминирующую роль здесь играет значение столбца Host (т.е. записи с одинаковыми значениями столбца Host размещаются рядом, а затем упорядочиваются по значению User ). Однако выполняемая сортировка не является лексикографической, или, скорее, является таковой лишь частично. Основной принцип — более высокий приоритет символьных значений по сравнению со специальными символами. Это означает, что если пользователь подключается к компьютеру boa.snake.net, а в таблице имеются записи со значениями boa.snake.net и %.snake.net, то будет выбрана именно первая запись. Аналогичным образом, значение %.snake.net имеет больший приоритет, чем %.net, которое, в свою очередь, более приоритетно, чем %. Точно так же обрабатываются и IP-адреса. Порядок приоритетности значений для пользователя, подключающегося с компьютера с IP-адресом 192.168.3.14, будет выглядеть следующим образом: 192.168.3.14, 192.168.3.%, 192.168.%, 192.% и %.

    Как минимизировать риск при работе с таблицами разрешений

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

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

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

    CREATE TABLE etc_passwd (pwd_entry TEXT); 
    LOAD DATA INFILE "/etc/passwd" INTO TABLE etc_passwd; 
    SELECT * FROM etc_passwd;

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

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

  • Создайте таблицу со столбцом LONGBLOB.

    USE test 
    CREATE TABLE tmp (b LONGBLOB)
  • Используйте таблицу для записи содержимого файла всех нужных таблиц, а затем запишите это содержимое в файл своей базы данных.

    LOAD DATA INFILE "./other_db/x.frm" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.frm" 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    DELETE FROM tmp 
    LOAD DATA INFILE "./other_db/x.ISD" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.ISD" 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    DELETE FROM tmp 
    LOAD DATA INFILE "./other_db/x.ISM" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.ISM" 
    FIELDS ESCAPED BY " LINES TERMINATED BY "
  • В результате создана новая таблица, содержащая информацию таблицы other_db.x, к которой имеется полный доступ.

  • Чтобы избежать подобных атак, установите права доступа к содержимому каталога данных в соответствии с инструкциями, представленными в пункте "Внутренняя безопасность: защита доступа к каталогу данных". Можно также при запуске сервера использовать опцию —skip-show- database. Это запретит пользователям запускать операторы SHOW database и show tables для баз данных, к которым им запрещен доступ, и не позволит пользователям случайно найти базу данных или таблицу, доступ к которым им не должен предоставляться.

    Иногда и привилегия ALTER используется таким образом, о котором даже и не подозревают администраторы. Предположим, например, что администратор желает предоставить пользователю user1 доступ к таблице table1, но не к таблице table2. Обладающий привилегией alter пользователь может легко обойти это ограничение, переименовав с помощью оператора ALTER TABLE таблицу table2 в table1.

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

    Установка пользователей без помощи оператора grant

    Администраторы MySQL, работающие с версиями до 3.22.11, не могут использовать операторы GRANT (или revoke ) для создания пользователей и настройки привилегий доступа. Для достижения тех же целей они могут непосредственно изменять содержимое таблиц разрешений. Гораздо проще это сделать тем администраторам, которые знают, каким образом оператор GRANT изменяет таблицы разрешений. По сути, те же операции можно выполнять и самостоятельно, применяя операторы insert.

    (Другое дело, что оператор INSERT может быть достаточно неудобным и трудно используемым. Именно этим и объясняется зачастую упрощенное применение grant.)

    В строке оператора grant определяется имя пользователя, имя компьютера и иногда пароль. В таблице user для пользователя создается запись и соответствующие значения записываются в столбцы User. Host и Password. Если администратор определяет какие-либо глобальные привилегии в операторе GRANT, они записываются в столбец привилегий записи. Однако следует помнить, что оператор grant шифрует записываемый пароль, а оператор insert — нет. Поэтому при настройке пользователей с помощью операторов insert необходимо применять функцию password ().

    При определении привилегий уровня базы данных имя пользователя и компьютера заносятся соответственно в столбцы User и Host таблицы db. Имя таблицы, к которой предоставляются привилегии, записывается в столбец Db, а сами привилегии — в столбец привилегий. Подобные операции выполняются и при определении полномочий уровня таблиц и столбцов. Для записи имени пользователя, компьютера, названия базы данных и, если необходимо, имени таблицы или столбца заносятся соответствующие значения в поля таблиц tables__priv и columns_priv. Присваиваемые привилегии записываются в столбцы привилегий.

    Все описанные выше операции можно выполнить и не прибегая к помощи оператора GRANT. He забывайте также, что после непосредственного изменения таблиц разрешений необходимо указать серверу перезагрузить их. Иначе изменения окажутся незамеченными. Для повторной загрузки можно запустить команду mysqladmin flush-privileges или mysqladmin reload.

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

    GRANT ALL ON *.* ТО ethel@localhost IDENTIFIED BY "coffee" 
    WITH GRANT OPTION

    Этот оператор создает запись для компьютера ethel@localhost в таблице user и активизирует для нее все привилегии. Те же привилегии можно присвоить и с помощью оператора insert:

    INSERT INTO user VALUES ("localhost","ethel", PASSWORD("coffee"), 
    "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")

    И это только один оператор insert! Более того, в зависимости от используемой версии MySQL, он может еще и не работать. Если структура таблиц разрешений была случайно изменена, число столбцов привилегий может не равняться четырнадцати. Чтобы проверить количество столбцов в каждой таблице разрешений, воспользуйтесь оператором SHOW COLUMNS, а затем соответствующим образом измените операторы insert.

    Следующий оператор GRANT также создает пользователя со статусом суперпользователей, однако только для одной привилегии:

    GRANT RELOAD ON *.* ТО flush@localhost IDENTIFIED BY "flushpass"

    Этот оператор уже рассматривался в лекции 2, "Общее администрирование MySQL", когда речь шла о создании пользователя flush. Равноценный предыдущей строке оператор insert в этом примере не такой сложный, как в предыдущем. Ведь гораздо проще указать имена столбцов и определить значение только в одном столбце привилегий. Во всех других столбцах по умолчанию будет установлено значение "n":

    INSERT INTO user (Host, User, Password, Reload priv) 
    VALUES("localhost", "flush", PASSWORD("flushpass") , "Y")

    Привилегии уровня базы данных присваиваются с помощью предложения ON db_name, а не ON *.*:

    GRANT ALL ON samp_db.* TO boris@localhost IDENTIFIED BY "ruby"

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

    INSERT INTO user (Host, User, Password) 
    VALUES("localhost", "boris", PASSWORD("ruby")) 
    INSERT INTO db VALUES("localhost", "samp_db", "boris", 
    "Y","Y","Y","Y","Y","Y","N","Y","Y", "Y"

    Столбец со значением "N" соответствует привилегии GRANT. Для оператора grant уровня базы данных с окончанием WITH GRANT option в этом столбце можно установить значение "у".

    Настройка привилегий уровня таблицы и столбца осуществляется посредством выполнения оператора INSERT для таблиц tables priv и columnspriv. Безусловно, если версия MySQL не включает оператор GRANT, то она не включает и эти таблицы, поскольку появились они одновременно. Если же администратор по определенным причинам желает манипулировать данными таблиц tables priv и columns priv без помощи оператора grant, он должен проявлять осторожность, поскольку невозможно активизировать привилегии в отдельных столбцах. Необходимо установить в одном из столбцов tables priv. Tables priv или columns priv. Column_priv значение SET, состоящее из активизируемых привилегий. Например, чтобы предоставить пользователю привилегии SELECT и INSERT для таблицы, установите в столбце Table priv соответствующей записи таблицы tables priv значение "Select, Insert".

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

    Если администратор желает избежать непосредственного изменении таблиц разрешений, можно воспользоваться сценариями mysqlaccess и mysql setpermissions, входящими в состав дистрибуции MySQL.

    Головоломка с привилегиями (продолжение)

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

    GRANT ALL ON samp db.* TO fred@%.snake .net IDENTIFIED BY "cocoa"

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

    % mysql -u fred -pcocoa samp_db 
    ERROR 1045: Access denied for user: 'fred@localhost' 
    (Using password: YES)

    Почему же так происходит? Чтобы понять это, необходимо разобраться, как сценарий mysql install db создает исходные таблицы разрешений и как сервер проверяет соответствие данных клиентских соединений и записей таблицы user. При инициализации баз данных в процессе работы mysql install db создает записи в таблице user со следующим значениями таблиц Host и User.

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | pit-viper.snake.net | root |
    | localhost           |      |
    | pit-viper.snake.net |      |
    +---------------------+------+

    Первые две записи позволяют пользователю root подключиться к локальному компьютеру, определив либо localhost, либо собственно имя компьютера. Вторые две записи разрешают анонимное соединение с локальным компьютером. При добавлении записи для пользователя fred таблица принимает следующий вид:

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | pit-viper.snake.net | root |
    | localhost           |      |
    | pit-viper.snake.net |      |
    | %.snake.net         | fred |
    +---------------------+------+

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

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | localhost           |      |
    | pit-viper.snake.net | root |
    | pit-viper.snake.net |      |
    | %.snake.net         | fred |
    +---------------------+------+

    Две записи для компьютера localhost располагаются рядом. Запись для пользователя root размещается первой, поскольку она является более полной. Аналогичным образом и в таком же порядке размещаются и записи компьютера pit-viper.snake.net. Все эти записи имеют в столбце Host буквенные значения безо всяких специальных символов, поэтому и располагаются перед записью для пользователя fred, включающей один специальный символ. Соответственно, записи анонимных пользователей имеют приоритет перед записью пользователя fred.

    Когда пользователь fred предпринимает попытку подключиться к серверу с локального компьютера, его данным соответствует запись с пустым именем пользователя, которая в порядке сортировки располагается перед записью с %.snake.net. Поскольку анонимные пользователи не применяют пароли, то и эта запись включает пустое значение пароля. Поскольку fred вводит пароль при подключении, возникает несоответствие, и соединение не устанавливается.

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

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

    mysql> DELETE FROM user WHERE User = ";

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

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

    Страницы:

    В лекции 2, "Общее администрирование MySQL", уже были затронуты такие важные аспекты безопасности, как установка пароля основного MySQL-пользователя root и настройка учетных записей пользователей. В этой лекции детально описываются следующие моменты.

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

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

  • Какой риск несет в себе подключение пользователей к серверу через сеть (внешняя безопасность) и как его минимизировать.

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

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

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

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

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

    Максимальную защиту необходимо обеспечить следующим категориям.

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

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

    Важность подобной защиты еще более подчеркивается тем фактом, что в файлах журналов регистрируются даже запросы с операторами grant и SET password, включающие пароли. (Вообще-то, в MySQL используется шифрование паролей, однако оно применяется только после установления соединения с предварительной проверкой пароля. Процесс же установки пароля включает выполнение таких операторов, как GRANT, INSERT и SET PASSWORD. В файлы журналов они заносятся в обычной текстовой форме.) Взломщику, получившему доступ к файлам журналов, достаточно запустить команду grep, чтобы раскрыть важную информацию операторов grant и password.

  • Не следует предоставлять пользователям компьютера, на котором установлен сервер, права записи для файлов каталога данных, поскольку они могут легко повредить файлы состояния и таблицы баз данных. Не менее опасен и доступ с правами чтения. Обладая возможностью чтения файлов таблицы, очень легко "украсть" эти файлы и позволить другому серверу MySQL самому показать содержимое таблицы в виде простого текста. Как? Да очень просто.

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

  • Запустите сценарий mysql_install_db для инициализации каталога данных. Это позволит получить доступ к серверу в качестве MySQL-пользователя root, получив полный контроль над механизмом доступа. Параллельно будет создана база данных test.

  • Скопируйте файлы, соответствующие "украденной" таблице или таблицам в подкаталог test каталога данных сервера.

  • Запустите второй сервер. Вот те на! Доступ к таблицам открыт. Оператор show tables from test указывает на наличие копий "украденных" таблиц, а с помощью оператора SELECT * можно увидеть их содержимое.

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

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

    Для определения, расположены ли в каталоге данных какие-либо незащищенные файлы и подкаталоги, достаточно запустить в нем команду ls -l. Найдите все файлы и каталоги, для которых активизированы "групповые" или "другие" полномочия. Вот для примера краткий список незащищенных элементов каталога данных, среди которых встречаются и подкаталоги баз данных.

    % ls -l
      total 10148
      drwxrwxr-x   11 mysqladm  wheel    1024  May   8  12:20 .
      drwxr-xr-x   22 root      wheel     512  May   8  13:31 ..
      drwx------    2 mysqladm  mysqlgrp  512  Apr  16  15:57 menagerle
      drwxrwxr-x    2 mysqladm  wheel     512  Jan  25  20:43 mysql
      drwxrwxr-x    7 mysqladm  wheel     512  Aug  31   1998 sql-bench
      drwxrwxr-x    2 mysqladm  wheel    1536  May   6  06:11 test
      drwx------    2 mysqladm  wheel    1024  May   8  18:43 tmp

    Как видите, для доступа к одним каталогам используются правильные полномочия, для других — нет. Такая ситуация стала результатом использования сервера в течение долгого периода времени. Менее ограничивающие полномочия созданы более старыми версиями серверов, которые были менее жестки в отношении прав доступа, чем новые. (Обратите внимание, что наиболее ограничивающие доступ каталоги menagerie и tmp имеют более позднее время создания.) Последние версии MySQL обязательно проверят, чтобы эти файлы смогли прочитать только пользователи, под именем которых работает сервер.

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

  • Перейдите в каталог данных:

    % cd DATADIR
  • Присвойте права владения всеми файлами каталога данных одной учетной записи, под управлением которой запускается сервер. (Эту операцию необходимо выполнить, зарегистрировавшись в качестве пользователя root.) В данном пособии для такой учетной записи используются имя пользователя mysqladm и группы mysqlgrp. Изменить права владения можно с помощью одной из следующих команд:

    # chown -R mysqladm.mysqlgrp . 
    # find . -follow -type d -print|xargs chown mysqladm.mysqlgrp
  • Измените режим доступа к каталогу данных и каталогам баз данных, чтобы прочитать их смог только пользователь mysqladm. В результате этого доступ к каталогу данных не смогут получить другие пользователи. Изменить режим можно с помощью одной из приведенных ниже команд, зарегистрировавшись в качестве пользователя root или mysqladm (последнее предпочтительней, поскольку позволяет минимизировать число команд, запущенных пользователем root ):

    % chmod -R go-rwx 
    % find . -follow -type d -print | xargs chmod go-rwx
  • Теперь права владения и режим содержимого каталога данных присвоены пользователю mysqladm. Осталось убедиться, что сервер отныне будет запускаться в качестве пользователя mysqladm, поскольку только этот пользователь имеет доступ к каталогу данных. Процедура запуска сервера в качестве нового пользователя (не root ) детально описана в лекции 2, "Общее администрирование MySQL".

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

    % ls -l
    	total 10148
    	drwxrwxr-x   11 mysqladm  wheel    1024  May   8  12:20 .
    	drwxr-xr-x   22 root      wheel     512  May   8  13:31 ..
    	drwx------    2 mysqladm  mysqlgrp  512  Apr  16  15:57 menagerle
    	drwxrwxr-x    2 mysqladm  wheel     512  Jan  25  20:43 mysql
    	drwxrwxr-x    7 mysqladm  wheel     512  Aug  31   1998 sql-bench
    	drwxrwxr-x    2 mysqladm  wheel    1536  May   6  06:11 test
    	drwx------    2 mysqladm  wheel    1024  May   8  18:43 tmp
    	...

    Внешняя безопасность: защита сетевого доступа

    Система безопасности MySQL достаточно гибка, поскольку позволяет настроить привилегии доступа пользователей множеством различных способов. Как правило, установка привилегий реализуется с помощью операторов GRANT и revoke, которые изменяют таблицы разрешений, управляющие клиентским доступом. Некоторые администраторы, тем не менее, все еще используют старые версии MySQL, которые не поддерживают эти операторы (до версии MySQL 3.22.11). Иногда также администраторы замечают, что при установке с помощью операторов GRANT и REVOKE привилегии функционируют не так, как хотелось бы. В подобных ситуациях весьма полезным может оказаться знание таблиц разрешений MySQL и принципов использования их сервером для определения полномочий. Владеющий подобными знаниями администратор может добавлять, удалять или изменять привилегии пользователей посредством изменения собственно таблиц разрешений. Более того, исследование таблиц позволяет гораздо быстрей диагностировать проблемы, связанные с доступом.

    Автор предполагает, что читатель уже ознакомился с материалом лекции 3 "Управление пользовательскими учетными записями", лекции 2 "Общее администрирование MySQL" и разобрался в принципах работы операторов grant и revoke. Их применение — удобный способ установки пользовательских учетных записей MySQL и связанных с ними привилегий. Но эти операторы являют собой лишь оболочку. Реальные действия выполняются в таблицах разрешений сервера MySQL.

    Структура и содержимое таблиц разрешений MySQL

    Управление доступом к базам данных MySQL для клиентов, подключившихся к серверу через сеть, осуществляется с помощью содержимого таблиц разрешений. Эти таблицы входят в состав базы данных mysql и инициализируются в процессе инсталляции MySQL на компьютере. В табл. 1 и 2 представлено краткое описание структур пяти таблиц разрешений:

    user, db, host, 
    tables_priv И columns_priv.
    Структура таблиц разрешений user, db и host
    Столбцы области доступа
    user db host
    host host host
    user db db
    password user
    Столбцы привилегий базы данных / таблицы
    Alter priv Alter priv Alter priv
    Create priv Create priv Create priv
    Delete priv Delete priv Delete priv
    Drop priv Drop priv Drop priv
    Index priv Index priv Index priv
    Insert priv Insert priv Insert priv
    References priv References priv References priv
    Select priv Select priv Select priv
    Update priv Update priv Update priv
    Столбцы административных привилегий
    File priv Grant priv Grant priv
    Grant priv
    Process priv
    Reload priv
    Shutdown priv
    Структура таблиц привилегий tables privt и columns privt
    Столбцы области доступа
    Tables priv columns priv
    Host Host
    Db Db
    User User
    Table name Table name
    Column name
    Столбец привилегий
    Table priv Column priv

    Таблицы разрешений содержат следующую информацию.

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

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

  • host. Таблица host применяется вместе с таблицей db и определяет привилегии доступа к базам данных определенного компьютера. Уровень этого контроля более высокий, чем при использовании одной лишь таблицы db. Операторы GRANT и REVOKE не могут изменять содержимое этой таблицы, поэтому на некоторых компьютерах она вообще не используется.

  • tables_priv. Таблица tables_priv определяет привилегии доступа к таблицам. Эти привилегии применимы ко всем столбцам определенной таблицы.

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

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

    Таблицы tablespriv и columspriv впервые появились в MySQL версии 3.22.11 (вместе с оператором grant ). Поэтому администраторы старых версий MySQL могут найти в базе данных mysql своего сервера только таблицы user, db и host. Если же эти таблицы не появляются даже после обновления до версии 3.22.11 или более поздней, запустите для их создания сценарий mysql_fix_privileges_tables.

    Отсутствие таблицы rowpriv объясняется невозможностью предоставления в MySQL привилегий на уровне строк. Нельзя, например, предоставить пользователю доступ только к отдельным строкам таблицы. Обеспечить подобную возможность реально можно только посредством написания соответствующей программы. Для блокировки данных на уровне записей можно использовать функцию get_lock().

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

    Столбцы области применения таблицы разрешений

    Столбцы области применения таблицы разрешений определяют, когда же применяются записи таблиц. Каждый элемент таблицы разрешений включает значения столбцов User и Host. Эти значения определяют, что данный элемент применяется при подключении определенного пользователя ( User ) к конкретному компьютеру ( Host ). (Таблица Host является исключением в этом отношении. Она используется особым способом, который в данной лекции не рассматривается.) Кроме того, другие таблицы могут содержать дополнительные столбцы. Таблица db, например, включает также столбец Db, определяющий базу данных, к которой применяется запись. Аналогичным образом таблицы tables_priv и columns_priv содержат поля области, которые ограничивают область применения записи до отдельной таблицы базы данных или отдельного столбца таблицы.

    Столбцы привилегий таблицы разрешений

    Таблицы разрешений включают также столбцы привилегий. Именно они определяют, какие привилегии предоставляются описанному в столбцах области пользователю. Поддерживаемые сервером MySQL привилегии приведены в списке, представленном ниже. В этом списке указываются названия привилегий, используемые в строке оператора GRANT. В большинстве случаев названия столбцов привилегий таблиц user, db и host сходны (по очевидным причинам) с названиями привилегий. Столбец Select_priv, например, соответствует привилегии SELECT.

    Привилегии баз данных и таблиц

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

  • ALTER. Позволяет использовать оператор alter table. Вообще, ALTER — это привилегия первого уровня. Для обработки таблиц необходимо предоставить дополнительные привилегии в зависимости от того, какие операции необходимо выполнять.

  • CREATE. Позволяет создавать базы данных и таблицы, но не индексы.

  • DELETE. Позволяет удалять записи из таблиц.

  • DROP. Позволяет удалять таблицы и базы данных, но не индексы.

  • INDEX. Позволяет создавать и удалять индексы в таблице.

  • INSERT. Позволяет вставлять новые записи в таблицы.

  • REFERENCES. В настоящее время не используется.

  • SELECT. Позволяет извлекать данные из таблиц с помощью операторов select. Эту привилегию необязательно присваивать для исполнения операторов select, не связанных с таблицами, например, SELECT NOW() ИЛИ SELECT 4/2

  • UPDATE. Позволяет изменять записи таблицы.

  • Административные привилегии

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

  • FILE. Позволяет давать серверу задание на считывание или запись файлов. Эту привилегию рекомендуется присваивать лишь в особых случаях. Поэтому сервер также предпринимает определенные меры предосторожности, позволяющие установить границы применения этой привилегии. Так, пользователи могут считывать файлы, которые доступны для чтения во всей системе. Невозможно записать файл, который уже существует на диске. Это позволяет избегать путаницы с критически важными файлами сервера, например /etc/passwd, или файлами чужих баз данных. Отсутствие подобного ограничения может привести к полной замене содержимого таблиц разрешений базы данных mysql.

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

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

  • PROCESS. Позволяет просматривать информацию о выполняемых внутри сервера нитях (процессах) с помощью оператора SHOW

  • PROCESSLIST или команды mysqladmin processlist. Эта же привилегия позволяет завершить выполнение процесса с помощью оператора KILL или команды mysqladmin kill.

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

  • reload. Позволяет выполнять множество операций администрирования сервера, например запускать SQL-оператор FLUSH или выполнять такие mysqladmin -команды, как reload, refresh, flush-hosts, flush-logs, flush-privileges и flush-tables. Даже несмотря на административные функции, эта привилегия не является опасной.

  • shutdown. Позволяет завершать работу сервера с помощью команды mysqladmin shutdown.

  • В таблицах user, db и host каждая привилегия определена в отдельном столбце. Все эти столбцы описаны типом ENUMC"N", "Y", и по умолчанию каждая привилегия имеет значение "n" (отключена). Привилегии таблиц tables_priv и column_priv представлены с помощью типа set, благодаря чему привилегии могут определяться различными комбинациями в одном столбце. Более эффективное представление привилегий в последних двух таблицах объясняется тем, что они появились гораздо позже, чем первые три. (Вполне возможно, что в будущем таблицы user, db и host будут реорганизованы и привилегии в них будут задаваться с помощью типа set.)

    Например, столбец Table_priv таблицы tables_priv определяется следующим образом:

    SET('Select','Insert','Update','Delete','Create',
       'Drop','Grant', 'Reference','Index','Alter')

    Столбец Column_priv таблицы column_priv определяется так:

    SET ('Select' , 'Insert','Update','Reference')

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

    Таблица user, помимо всего прочего, содержит несколько привилегий, которые отсутствуют во всех других таблицах разрешений: File priv, Process priv, Reload_priv и Shutdown_priv. Эти привилегии применяются к выполняемым сервером операциям, не связанным с отдельной базой данных или таблицей. Ведь при необходимости завершения работы сервера вовсе не обязательно проверять, над какой базой данных в настоящее время ведется работа.

    Как сервер управляет доступом клиентов

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

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

    Содержимое столбцов области доступа

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

    Host. Значение столбца Host может представлять собой имя компьютера или его IP-адрес. Значение localhost соответствует локальному компьютеру, однако рекомендуется использовать его только в том случае, если данный компьютер действительно имеет имя localhost. Представим ситуацию, когда локальный компьютер имеет имя pit.viper.snake и для одного пользователя имеется две записи в таблице user. Одна запись в столбце Host имеет значение localhost, а вторая — pit-viper.snake.net. Первая запись будет использоваться только при подключении к компьютеру localhost, а вторая — к компьютеру pit-viper.snake.net. Если необходимо, чтобы пользователи имели возможность подключиться с помощью любого из этих способов, следует оставить обе эти записи в таблице user.

    Значения столбца Host также можно задать с помощью шаблона. Так, можно использовать распространенные в SQL символы "%" и "_", имеющие такое же значение, как и в строке запроса с оператором like. (REGEX-шаблоны для этих целей неприменимы.) Символы шаблона SQL можно применять при определении как имен, так и IP-адресов. Строке %.wisc.edu, например, соответствуют все компьютеры домена wisc.edu, а строке %.edu — компьютеры всех подключенных к сети организаций системы образования. Аналогичным образом, строка 192.168.% описывает все компьютеры подсети класса В 192.168, а строка 192.168.3.% — все компьютеры подсети класса С 192.168.3.

    Значение "%" определяет все компьютеры и дает возможность пользователю подключиться из любой точки. Пустое значение столбца Host аналогично значению "!". (Исключение: в таблице db пустое значение столбца Host указывает на необходимость проверки таблицы host для получения более детальной информации)

    В версиях MySQL серии 3.23 можно также определить числа IP-адресов с помощью маски сети, отражающей разрядность сетевого номера. Строка 192.168.128.0/17, например, определяет 17 разрядный сетевой номер. Ей соответствует любой компьютер, первые 17 разрядов IP-адреса которого аналогичны разрядам адреса 192 .168 .128.

  • User. Имена пользователей могут задаваться буквенными или пустыми значениями. В последнем случае сможет подключиться любой пользователь. Значение "%" и пустое значение в столбце User — это не одно и то же. Оно соответствует пользователю с именем "%". Надо признать, такое имя встречается довольно редко.

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

  • Password. Значения этого столбца могут быть либо пустыми, либо буквенными. Специальные символы в них использовать нельзя. Пустое значение не является аналогией "любого пароля". Когда в таблице определено пустое значение столбца Password, пользователь не должен определять пароль вовсе.

    Значения паролей хранятся в зашифрованном, а не в обычном текстовом виде. Пользователи не смогут подключиться к серверу, если в столбец Password записываются обычные текстовые значения! Оператор GRANT и команда mysqladmin password автоматически шифруют пароль. Поэтому при непосредственной записи паролей с помощью команд INSERT, replace, update и set password следует зашифровать их значения с помощью команды PASSWORD("new_password").

  • Db. Значения столбца Db в таблицах columns_priv и tables_priv обязательно должны представлять собой текстовые имена баз данных. Использование специальных символов и пустых значений запрещается. В таблицах db и host эти значения можно определить как в виде текстовых значений, так и с помощью SQL-символов "%" и "_". Пустое значение и значение % позволяют получить доступ к любой базе данных.

  • Table_name, Column_name. Значения этих столбцов представляют собой текстовые записи имен таблиц и столбцов. Использование специальных символов и пустых значений запрещается.

    Регистр символов в некоторых столбцах области играет важное значение, а в остальных столбцах значения могут быть записаны как строчными, так и прописными буквами. Регистры символов в таких столбцах воспринимаются сервером по-разному. Это показано в табл. 3. Необходимо заметить, что регистр значений столбца Table_name всегда имеет значение, хотя учет регистра в именах таблиц в запросах зависит от файловой системы, под управлением которой работает сервер (под управлением UNIX выбор регистра важен, а под управлением Windows — нет).

    Учет регистра в столбцах области таблиц разрешений
    Столбец Учет регистра
    Host нет
    User да
    Password да
    Db да
    Table name да
    Column name нет
  • Проверка запроса

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

  • При первоначальном подключении сервер проверяет записи таблицы user, пытаясь определить глобальные привилегии подключающегося пользователя. Если таковые имеются и, более того, являются достаточными для выполнения запроса, сервер обрабатывает запрос.

  • Если имеющихся глобальных привилегий недостаточно, сервер ищет дополнительные привилегии в таблице db. Если найденные привилегии позволяют выполнить запрос, сервер его обрабатывает.

  • Как хранятся пароли в таблице user

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

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

  • Если набора глобальных привилегий и привилегий баз данных недостаточно, сервер продолжает поиск сначала в таблице tables_priv, a потом и в columns_priv.

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

  • Говоря на языке булевой алгебры, привилегии таблиц разрешений используются сервером следующим образом: user OR db OR tables_priv OR columns_priv

    Некоторые читатели уже, возможно, задаются вопросом, почему в этой записи указывается четыре таблицы разрешений, хотя на самом деле их пять. Совершенно верно. Правильней было бы переписать ее следующим образом: user OR (db AND host) OR tables_pnv OR columns_priv

    Упрощенный вариант был представлен исключительно для того, чтобы показать, что таблица host не подвержена влиянию операторов grant и REVOKE. Администраторы, управляющие привилегиями пользователей с помощью операторов grant и revoke, могут забыть о таблице host по следующим причинам.

  • Проверяя привилегии уровня базы данных, сервер ищет запись для клиента в таблице db. Пустое значение столбца Host означает примерно следующее: проверьте таблицу host, чтобы определить, какие компьютеры могут получать доступ к базе данных.

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

    Привилегии объединяются посредством логического оператора and. Это означает, что пользователь будет иметь привилегии только в том случае, когда записи о нем будут представлены в обеих таблицах. Таким образом, пользователю может присваиваться базовый набор привилегий в записи таблицы db. Согласно записям таблицы host, получить их можно будет только с определенных компьютеров. Так, например, можно предоставить доступ к базам данных со всех компьютеров домена, но убрать эти привилегии для пользователей компьютеров, расположенных в менее защищенной области.

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

    Например, если новый пользователь создается администратором путем добавления новой записи в таблицу user с помощью оператора insert, он не сможет сразу же подключиться к серверу. Начинающих администраторов (а иногда и вполне опытных) это зачастую весьма сильно раздражает, хотя решение этой проблемы предельно просто: достаточно указать серверу перезагрузить таблицы разрешений сразу после внесения изменений. Это можно осуществить с помощью оператора FLUSH PRIVILEGES или команды mysqladmin flush-privileges (либо mysqladmin reload, если используется более старая версия, не поддерживающая flush-privileges ).

    Порядок сравнения столбцов

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

    Считывая содержимое таблицы user, сервер сортирует ее записи, согласно значениям столбцов Host и User. Доминирующую роль здесь играет значение столбца Host (т.е. записи с одинаковыми значениями столбца Host размещаются рядом, а затем упорядочиваются по значению User ). Однако выполняемая сортировка не является лексикографической, или, скорее, является таковой лишь частично. Основной принцип — более высокий приоритет символьных значений по сравнению со специальными символами. Это означает, что если пользователь подключается к компьютеру boa.snake.net, а в таблице имеются записи со значениями boa.snake.net и %.snake.net, то будет выбрана именно первая запись. Аналогичным образом, значение %.snake.net имеет больший приоритет, чем %.net, которое, в свою очередь, более приоритетно, чем %. Точно так же обрабатываются и IP-адреса. Порядок приоритетности значений для пользователя, подключающегося с компьютера с IP-адресом 192.168.3.14, будет выглядеть следующим образом: 192.168.3.14, 192.168.3.%, 192.168.%, 192.% и %.

    Как минимизировать риск при работе с таблицами разрешений

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

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

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

    CREATE TABLE etc_passwd (pwd_entry TEXT); 
    LOAD DATA INFILE "/etc/passwd" INTO TABLE etc_passwd; 
    SELECT * FROM etc_passwd;

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

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

  • Создайте таблицу со столбцом LONGBLOB.

    USE test 
    CREATE TABLE tmp (b LONGBLOB)
  • Используйте таблицу для записи содержимого файла всех нужных таблиц, а затем запишите это содержимое в файл своей базы данных.

    LOAD DATA INFILE "./other_db/x.frm" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.frm" 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    DELETE FROM tmp 
    LOAD DATA INFILE "./other_db/x.ISD" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.ISD" 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    DELETE FROM tmp 
    LOAD DATA INFILE "./other_db/x.ISM" INTO TABLE tmp 
    FIELDS ESCAPED BY " LINES TERMINATED BY " 
    SELECT * FROM tmp INTO OUTFILE "y.ISM" 
    FIELDS ESCAPED BY " LINES TERMINATED BY "
  • В результате создана новая таблица, содержащая информацию таблицы other_db.x, к которой имеется полный доступ.

  • Чтобы избежать подобных атак, установите права доступа к содержимому каталога данных в соответствии с инструкциями, представленными в пункте "Внутренняя безопасность: защита доступа к каталогу данных". Можно также при запуске сервера использовать опцию —skip-show- database. Это запретит пользователям запускать операторы SHOW database и show tables для баз данных, к которым им запрещен доступ, и не позволит пользователям случайно найти базу данных или таблицу, доступ к которым им не должен предоставляться.

    Иногда и привилегия ALTER используется таким образом, о котором даже и не подозревают администраторы. Предположим, например, что администратор желает предоставить пользователю user1 доступ к таблице table1, но не к таблице table2. Обладающий привилегией alter пользователь может легко обойти это ограничение, переименовав с помощью оператора ALTER TABLE таблицу table2 в table1.

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

    Установка пользователей без помощи оператора grant

    Администраторы MySQL, работающие с версиями до 3.22.11, не могут использовать операторы GRANT (или revoke ) для создания пользователей и настройки привилегий доступа. Для достижения тех же целей они могут непосредственно изменять содержимое таблиц разрешений. Гораздо проще это сделать тем администраторам, которые знают, каким образом оператор GRANT изменяет таблицы разрешений. По сути, те же операции можно выполнять и самостоятельно, применяя операторы insert.

    (Другое дело, что оператор INSERT может быть достаточно неудобным и трудно используемым. Именно этим и объясняется зачастую упрощенное применение grant.)

    В строке оператора grant определяется имя пользователя, имя компьютера и иногда пароль. В таблице user для пользователя создается запись и соответствующие значения записываются в столбцы User. Host и Password. Если администратор определяет какие-либо глобальные привилегии в операторе GRANT, они записываются в столбец привилегий записи. Однако следует помнить, что оператор grant шифрует записываемый пароль, а оператор insert — нет. Поэтому при настройке пользователей с помощью операторов insert необходимо применять функцию password ().

    При определении привилегий уровня базы данных имя пользователя и компьютера заносятся соответственно в столбцы User и Host таблицы db. Имя таблицы, к которой предоставляются привилегии, записывается в столбец Db, а сами привилегии — в столбец привилегий. Подобные операции выполняются и при определении полномочий уровня таблиц и столбцов. Для записи имени пользователя, компьютера, названия базы данных и, если необходимо, имени таблицы или столбца заносятся соответствующие значения в поля таблиц tables__priv и columns_priv. Присваиваемые привилегии записываются в столбцы привилегий.

    Все описанные выше операции можно выполнить и не прибегая к помощи оператора GRANT. He забывайте также, что после непосредственного изменения таблиц разрешений необходимо указать серверу перезагрузить их. Иначе изменения окажутся незамеченными. Для повторной загрузки можно запустить команду mysqladmin flush-privileges или mysqladmin reload.

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

    GRANT ALL ON *.* ТО ethel@localhost IDENTIFIED BY "coffee" 
    WITH GRANT OPTION

    Этот оператор создает запись для компьютера ethel@localhost в таблице user и активизирует для нее все привилегии. Те же привилегии можно присвоить и с помощью оператора insert:

    INSERT INTO user VALUES ("localhost","ethel", PASSWORD("coffee"), 
    "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")

    И это только один оператор insert! Более того, в зависимости от используемой версии MySQL, он может еще и не работать. Если структура таблиц разрешений была случайно изменена, число столбцов привилегий может не равняться четырнадцати. Чтобы проверить количество столбцов в каждой таблице разрешений, воспользуйтесь оператором SHOW COLUMNS, а затем соответствующим образом измените операторы insert.

    Следующий оператор GRANT также создает пользователя со статусом суперпользователей, однако только для одной привилегии:

    GRANT RELOAD ON *.* ТО flush@localhost IDENTIFIED BY "flushpass"

    Этот оператор уже рассматривался в лекции 2, "Общее администрирование MySQL", когда речь шла о создании пользователя flush. Равноценный предыдущей строке оператор insert в этом примере не такой сложный, как в предыдущем. Ведь гораздо проще указать имена столбцов и определить значение только в одном столбце привилегий. Во всех других столбцах по умолчанию будет установлено значение "n":

    INSERT INTO user (Host, User, Password, Reload priv) 
    VALUES("localhost", "flush", PASSWORD("flushpass") , "Y")

    Привилегии уровня базы данных присваиваются с помощью предложения ON db_name, а не ON *.*:

    GRANT ALL ON samp_db.* TO boris@localhost IDENTIFIED BY "ruby"

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

    INSERT INTO user (Host, User, Password) 
    VALUES("localhost", "boris", PASSWORD("ruby")) 
    INSERT INTO db VALUES("localhost", "samp_db", "boris", 
    "Y","Y","Y","Y","Y","Y","N","Y","Y", "Y"

    Столбец со значением "N" соответствует привилегии GRANT. Для оператора grant уровня базы данных с окончанием WITH GRANT option в этом столбце можно установить значение "у".

    Настройка привилегий уровня таблицы и столбца осуществляется посредством выполнения оператора INSERT для таблиц tables priv и columnspriv. Безусловно, если версия MySQL не включает оператор GRANT, то она не включает и эти таблицы, поскольку появились они одновременно. Если же администратор по определенным причинам желает манипулировать данными таблиц tables priv и columns priv без помощи оператора grant, он должен проявлять осторожность, поскольку невозможно активизировать привилегии в отдельных столбцах. Необходимо установить в одном из столбцов tables priv. Tables priv или columns priv. Column_priv значение SET, состоящее из активизируемых привилегий. Например, чтобы предоставить пользователю привилегии SELECT и INSERT для таблицы, установите в столбце Table priv соответствующей записи таблицы tables priv значение "Select, Insert".

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

    Если администратор желает избежать непосредственного изменении таблиц разрешений, можно воспользоваться сценариями mysqlaccess и mysql setpermissions, входящими в состав дистрибуции MySQL.

    Головоломка с привилегиями (продолжение)

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

    GRANT ALL ON samp db.* TO fred@%.snake .net IDENTIFIED BY "cocoa"

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

    % mysql -u fred -pcocoa samp_db 
    ERROR 1045: Access denied for user: 'fred@localhost' 
    (Using password: YES)

    Почему же так происходит? Чтобы понять это, необходимо разобраться, как сценарий mysql install db создает исходные таблицы разрешений и как сервер проверяет соответствие данных клиентских соединений и записей таблицы user. При инициализации баз данных в процессе работы mysql install db создает записи в таблице user со следующим значениями таблиц Host и User.

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | pit-viper.snake.net | root |
    | localhost           |      |
    | pit-viper.snake.net |      |
    +---------------------+------+

    Первые две записи позволяют пользователю root подключиться к локальному компьютеру, определив либо localhost, либо собственно имя компьютера. Вторые две записи разрешают анонимное соединение с локальным компьютером. При добавлении записи для пользователя fred таблица принимает следующий вид:

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | pit-viper.snake.net | root |
    | localhost           |      |
    | pit-viper.snake.net |      |
    | %.snake.net         | fred |
    +---------------------+------+

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

    +---------------------+------+
    | Host                | User |
    +---------------------+------+
    | Localhost           | root |
    | localhost           |      |
    | pit-viper.snake.net | root |
    | pit-viper.snake.net |      |
    | %.snake.net         | fred |
    +---------------------+------+

    Две записи для компьютера localhost располагаются рядом. Запись для пользователя root размещается первой, поскольку она является более полной. Аналогичным образом и в таком же порядке размещаются и записи компьютера pit-viper.snake.net. Все эти записи имеют в столбце Host буквенные значения безо всяких специальных символов, поэтому и располагаются перед записью для пользователя fred, включающей один специальный символ. Соответственно, записи анонимных пользователей имеют приоритет перед записью пользователя fred.

    Когда пользователь fred предпринимает попытку подключиться к серверу с локального компьютера, его данным соответствует запись с пустым именем пользователя, которая в порядке сортировки располагается перед записью с %.snake.net. Поскольку анонимные пользователи не применяют пароли, то и эта запись включает пустое значение пароля. Поскольку fred вводит пароль при подключении, возникает несоответствие, и соединение не устанавливается.

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

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

    mysql> DELETE FROM user WHERE User = ";

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

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

    Вернуться к учебному плану