Аутентификация клиента
Аутентификация клиентов занимает центральное место в PostgreSQL. Без
нее пришлось бы либо пожертвовать возможностью удаленного подключения,
либо слепо разрешать каждому, кто подключается к серверу, выборку и даже
модификацию данных. PostgreSQL предоставляет в ваше распоряжение несколько
механизмов аутентификации клиентов, и вы как администратор базы данных
должны выбрать тот механизм, который лучше подходит для вашей системы.
В PostgreSQL 7.1.x клиентский доступ на уровне хоста задается в файле
pg_hba.conf. Права и ограничения, описанные в этом файле, не следует путать
с правами доступа к объектам базы данных, установленными для пользователей
PostgreSQL. Файл pg_hba.conf позволяет задать тип аутентификации на уровне
хоста, выполняемой перед подключением к базе данных, после которого вступают
в силу права пользователей.
ПРИМЕЧАНИЕ
Файл pg_hba.conf находится в каталоге данных PostgreSQL
(например, /usr/local/pgsql/data) и создается автоматически при выполнении
команды initdb в процессе установки PostgreSQL.
Аутентификация PostgreSQL на уровне хоста отличается высокой гибкостью
и большим разнообразием настраиваемых параметров. Например, доступ к базе
данных можно ограничить отдельными хостами или предоставить его семейству
IP-адресов при помощи сетевых масок. С каждым хостом связывается специальная
запись, представленная отдельной строкой в файле pg_hba.conf.
Используя хостовые записи, можно ограничить доступ пользователя одной
конкретной базой данных или разрешить ему доступ ко всем базам. Более
того, при поступлении запроса на подключение пользователя с заданного
хоста можно потребовать, чтобы пользователь прошел аутентификацию по таблице
пользователей PostgreSQL.
Проще говоря, файл pg_hba.conf определяет, кому, с какого компьютера
и к каким базам данных разрешено подключение, а также каким образом должна
проходить проверка для предоставления доступа.
ВНИМАНИЕ
В механизме удаленной аутентификации пароли могут пересылаться
по сети в обычном текстовом виде. Все зависит от того, организовали ли
вы шифрование клиентского сеанса. Прежде чем разрешать пользователям удаленное
подключение к базам данных PostgreSQL, необходимо хорошо разобраться в
том, как ваше приложение взаимодействует с PostgreSQL.
Аутентификация с использованием паролей
Пароли используются для подтверждения личности пользователей PostgreSQL
и предотвращения посторонних подключений. В PostgreSQL 7.1.x пароли хранятся
в текстовом виде в системной таблице pg_shadow, структура которой описана
в табл. 8.1. Хотя пароли хранятся в виде простого текста, просмотр содержимого
таблицы pg_shadow разрешен только суперпользователям PostgreSQL.
Таблица 8.1. Структура таблицы pg_shadow
Поле |
Тип |
usenatne |
name |
usesysld |
integer- |
usecreatedb |
boolean |
usetrace |
boolean |
usesuper |
boolean |
usecatupd |
boolean |
passwd |
text |
val until |
abstime |
Системная таблица pg_shadow доступна из любой базы данных. Из этого
следует, что пользовательский доступ не ограничивается конкретной базой.
Если данные некоторого пользователя присутствуют в таблице pg_shadow,
то этот пользователь сможет подключиться к любой базе данных на серверном
компьютере (конечно, если ему вообще разрешено подключение).
Пароли обычно задаются в PostgreSQL при создании учетной записи пользователя
(командой CREATE USER) или при ее дальнейших модификациях (командой ALTER
USER). Кроме того, пароль можно изменить вручную командой UPDATE. Дополнительная
информация о назначении паролей приведена в главе 10.
Если пароль не задан, по умолчанию используется псевдозначение NULL.
При включении парольной аутентификации в файле pgjiba.conf попытки подключения
со стороны пользователей, не имеющих паролей, всегда завершаются неудачей.
С другой стороны, если подключение устанавливается с доверенного хоста
(как, например, local host по умолчанию), любой пользователь сможет подключиться
с паролем NULL. Для доверенных хостов пароли полностью игнорируются.
ПРИМЕЧАНИЕ
Команда GRANT ограничивает доступ к таблицам в базе данных.
За дополнительной информацией обращайтесь к главе 10.
Если ваши требования к безопасности выходят за рамки абсолютного минимума,
одной парольной аутентификации на сервере PostgreSQL будет недостаточно.
Любой аутентифицироваыный пользователь сможет обратиться к любой базе
данных в системе, а передаваемые в текстовом виде пароли могут попасть
в посторонние руки. Если вы планируете организовать доступ к базе данных
через Интернет, обязательно прочитайте следующие подразделы. В них рассматриваются
файл pg_hba.conf и шифрование сеансов.
Файл pg_hba.conf
В начале главы уже упоминалось о том, что файл pg_hba.conf обеспечивает
аутентификацию клиента на сервере PostgreSQL. Файл состоит из записей,
описывающих хосты и предоставляемые им права (например, база данных, к
которой разрешено подключение, метод аутентификации и т. д.).
Когда приложение обращается к серверу с запросом на подключение, в этот
запрос включается имя пользователя PostgreSQL и база данных, к которой
он намеревается подключиться. В зависимости от настройки хоста также может
передаваться пароль.
ПРИМЕЧАНИЕ
PostgreSQL ведет собственные таблицы пользователей и паролей,
не имеющие отношения к системным таблицам. Данные пользователей PostgreSQL
не обязаны совпадать с данными пользователей операционной системы.
Получив запрос на подключение, PostgreSQL обращается к файлу pgjiba.conf
и проверяет, разрешен ли доступ к указанной базе данных хосту, на котором
работает приложение. Если подключения с этого хоста разрешены, PostgreSQL
проверяет условия, которым должно удовлетворять приложение для успешного
подключения. Это относится как к локальным, так и к удаленным подключениям.
Для каждого запроса на подключение сервер читает из файла pgjiba.conf
сведения о способе аутентификации. Проверка производится при каждом подключении
к серверу PostgreSQL, поэтому после добавления, изменения или удаления
записей из файла pg_hba.conf перезапускать PostgreSQL не нужно. В листинге
8.1 приведен простой пример файла pgjiba.conf.
Листинг 8.1. Простой файл pgjiba.conf
# PostgreSQL HOST ACCESS CONTROL FILE f
# Configured Hosts:
local all trust
host all 127.0.0.1 255.255.255.255 trust
host booktown 192.168.1.3 255.255.255.255 ident sales
host all 192.168.1.4 255.255.255.255 ident audit
При инициализации подключения PostgreSQL читает файл pg_hba.conf сверху
вниз по одной записи. Как только найдена подходящая запись, PostgreSQL
прекращает поиск и разрешает или отвергает подключение в зависимости от
результата. Если PostgreSQL не находит подходящей записи в файле pg_hba.conf,
подключение автоматически отвергается.
Даже если пользователю разрешается подключение к базе данных, права
доступа к таблицам по-прежнему продолжают действовать. Если пользователь
подключается к базе данных, но не может получить данные из таблицы, проверьте,
что ему разрешено выполнение команды SELECT для этой таблицы. В клиенте
командной строки psql права доступа к таблицам базы данных проверяются
при помощи команды \z. В любом другом интерфейсе к PostgreSQL для получения
этой информации можно воспользоваться запросом, приведенным в листинге
8.2.
Листинг 8.2. Проверка прав доступа
testdb=# SELECT relname as "Relation", relacl
as "Access permissions"
testdb-# FROM pg_class
testdb-# WHERE relkind IN Cr', 'V. 'S')
testdb-# AND relname !- '*pg_'
testdb-# ORDER BY relname;
Relation I Access permissions
foo {"=arwR"."jdrake=arwR"}
myjlist {"=","jdrake=arwR"."jworsley=r"}
(2 rows)
Структура файла pg_hba.conf
Конфигурационный файл pg_hba.conf содержит серию записей, определяющих
параметры аутентификации клиентов с заданных хостов. Структура этого файла
позволяет легко изменить его в соответствии с вашими требованиями.
В этом файле IP-адрес хоста (или интервал адресов) связывается с некоторой
базой данных (или всеми базами) и одним из нескольких методов аутентификации.
Для локальных подключений вместо внешнего IP-адреса используется обозначение
local host или 127.0.0.1. Синтаксис файла pg_hba.conf должен удовлетворять
ряду правил.
Во-первых, каждая строка файла содержит одну хостовую запись, при этом
перенос записей на следующую строку не разрешен. Во-вторых, каждая запись
содержит несколько полей, разделенных табуляциями или пробелами. Количество
полей определяемой хостовой записи напрямую связано с ее типом. В листинге
8.3 приведены две записи; в первой поля разделены пробелами, а во второй
- символами табуляции.
Листинг 8.3. Разделение полей в записях
pg_hba.conf пробелами и табуляциями
host all 127.0.0.1 255.255.255.255 trust
host all 127.0.0.1 255.255.255.255 trust
Файл pg_hba.conf может содержать комментарии, строки которых начинаются
с символа #. Примеры комментариев приведены в листинге 8.4.
Листинг 8.4. Комментарии в файле pgjiba.conf
# Book Town host entries
#
#
host all 127.0.0.1 255.255.255.255 trust
Хостовые записи, содержащиеся в файле pg_hba.conf, делятся на три общих
типа (тип всегда задается первым словом каждой записи).
- host. Записи типа host описывают удаленные хосты, которым разрешено
подключаться к серверу PostgreSQL. Для правильной работы записей типа
host серверный модуль PostgreSQL postmaster должен быть запущен с ключом
-i (TCP/IP).
- local. С семантической точки зрения запись типа local аналогична
записи типа host. Тем не менее в ней не нужно указывать хосты, которым
разрешено подключение. Запись local используется для клиентских подключений
с того компьютера, на котором работает сервер PostgreSQL.
- hostssl. Запись типа hostssl используется для указания хостов (удаленных
или локальных), которым разрешено подключение к серверу PostgreSQL с
использованием протокола SSL, обеспечивающего шифрование всех взаимодействий
между клиентом и сервером. Протокол SSL должен поддерживаться как клиентом,
так и сервером. Серверный процесс postmaster должен быть запущен с ключами
-1 (SSL) и -1 (TCP/IP).
ПРИМЕЧАНИЕ
Ключи, с которыми запускается процесс postmaster, описаны
в главе 9.
В листинге 8.5 приведен обобщенный синтаксис всех типов записей файла
pg_hba.conf. Обратите внимание: все типы записей практически идентичны,
разве что в записях типа local не нужно указывать IP-адрес или сетевую
маску - подключение заведомо осуществляется с компьютера, на котором работает
PostgreSQL.
Листинг 8.5. Синтаксис записей файла pg_hba.conf
# Запись типа "local"
local база_дднных метод^аутентификации [ параметр ]
# Запись типа "host"
host база_данных 1р_адрес сетевая_наска метод_аутентификации
[ параметр ]
# Запись типа "hostssl"
hostssl база_данных тр_адрес сетевая_маска метод_аутентификации
[ параметр ]
ПРИМЕЧАНИЕ
Помните, что каждая запись в файле pg_hba.conf должна полностью
умещаться в одной строке. Перенос записей на другую строку запрещен.
Ниже перечислены компоненты записей pg_hba.conf, упоминаемые в листинге
8.5.
- база_данных. Имя базы данных, к которой разрешено подключаться заданному
хосту. Возможны три варианта:
- ключевое слово al 1 означает, что клиент может подключиться к
любой базе данных, обслуживаемой сервером PostgreSQL;
- ключевое слово sameuser означает, что клиент может подключаться
только к базе данных, имя которой совпадает с именем аутентифицироваиного
пользователя;
- если в записи указывается конкретное имя базы данных, клиент сможет
подключиться только к этой базе.
- ip_adpec, сетевая ^маска. Поля ip_adpec и сетевая_маска определяют
либо конкретный IP-адрес, либо интервал IP-адресов, которым разрешено
подключение к серверу PostgreSQL. Интервал задается в виде сетевой маски,
описывающей IP-сеть. При указании отдельного IP-адреса поле сетевой
маски должно быть равно 255.255~. 255.255.
ПРИМЕЧАНИЕ
За информацией о сетевых масках обращайтесь на сайт Linux
Networking HOWTO (http://www. thelinuxreview.com/howto/networking) или
к системному администратору.
- метод_аутентификации. Метод аутентификации, который должен использоваться
сервером при подключении пользователя к PostgreSQL. Ниже перечислены
допустимые значения этого поля.
- trust. Хост объявляется доверенным, то есть любой пользователь
с него подключается к базе данных PostgreSQL без пароля. Таким образом,
вы автоматически доверяете всем пользователям хоста. Естественно,
это весьма рискованный метод, если заданный хост недостаточно хорошо
защищен или предоставляет доступ посторонним пользователям.
- reject. Доступ к PostgreSQL для соответствующего хоста/пользователя
автоматически отклоняется. Такая настройка подходит лишь в том случае,
если хост заведомо не должен получать доступ к серверу PostgreSQL.
- password. Для получения доступа пользователь должен ввести пароль,
который совпадает с паролем, хранящимся в глобальной системной таблице
pg_shadow с именем этого пользователя. Пароль пересылается в текстовом
виде.
- crypt. Этот метод аналогичен методу password, но в нем пароль
пересылается не в простом текстовом виде, а с применением простой
схемы шифрования, которая не обеспечивает надежной защиты, но это
все же лучше, чем простая пересылка пароля в текстовом виде, как
в методе password.
- krb4, krb5. Используется система аутентификации Kerberos версий
4 и 5. Вопросы установки и настройки Kerberos выходят за рамки темы
книги, но если вы захотите организовать аутентификацию с использованием
Kerberos, такой вариант существует.
- ident. При запросе на подключение от хоста с IP-адресом, заданным
в файле pg_hba.conf, должна применяться карта идентификации. У метода
имеется один обязательный параметр, значением которого является
либо специальное ключевое слово sameuser, либо имя карты, определенной
в файле pgjdent.conf. Дополнительная информация о картах идентификации
приведена в пункте «Файл pg_ident.conf>>.
- параметр. Поле параметра может быть обязательным или необязательным
в зависимости от выбранного метода аутентификации. В PostgreSQL 7.1.x
оно обязательно только для метода Ident.
ВНИМАНИЕ
Методы password и crypt рекомендуется использовать лишь
в сочетании с внешним механизмом шифрования. Информация о применении единого
механизма шифрования для всего трафика PostgreSQL приведена в разделе
«Шифрование сеанса».
Примеры записей в файле pg_hba.conf
В этом разделе приведены некоторые примеры записей в файле pg_hba.conf.
Запись, приведенная в листинге 8.6, разрешает подключиться к любой (all)
базе данных без пароля (trust) всем пользователям хоста с IP-адресом 192.168.1.10.
Листинг 8.6. Один доверенный хост
host all 192.168.1.10 255.255.255.255 trust
Следующая запись (листинг 8.7) запрещает подключение всем пользователям
с IP-адреса 192.168.1.10. Для этого в режиме аутентификации reject вместо
базы данных указывается ключевое слово all.
Листинг 8.7. Запрет доступа с одного хоста
host all 192.168.1.10 255.255.255.255 reject
Следующая запись (листинг 8.8) разрешает подключение к базе данных templatel
с хоста 192.168.1.10 любому пользователю, указавшему правильный пароль.
Режим crypt обеспечивает шифрование пароля в процессе аутентификации.
Листинг 8.8. Один хост, одна база данных
host templatel 192.168.1.10 255.255.255.255 crypt
Запись в листинге 8.9 разрешает доступ к базам данных без пароля из
небольшой подсети. Подсеть состоит из всех IP-адресов в интервале от 192.168.1.1
до 192.168.1.15. Как упоминалось ранее, за информацией о сетевых масках
следует обращаться на сайт Linux Networking HOWTO (http://www.thelinuxreview.com/howto/
networking) или к администратору сети.
Листинг 8.9. Доверенная подсеть
host all 192.168.1.0 255.255.255.240 trust
Запись, приведенная в листинге 8.10, разрешает доступ с любого хоста
из блока 192.168.1 к базе данных booktown без указания пароля.
Листинг 8.10. Доверенная подсеть
host booktown 192.168.1.0 255.255.255.0 trust
Вспомните, о чем говорилось выше: при проверке очередного подключения
записи файла pg_hba.conf последовательно читаются от начала к концу, и
режим аутентификации определяется первой найденной записью. Если в файле
не обнаруживается ни одного совпадения, подключение полностью запрещается.
Файл pgjdent.conf
Если в хостовой записи указан метод аутентификации ident, PostgreSQL
использует файл pgjdent.conf для отображения идентификационного имени
пользователя на имя пользователя PostgreSQL. «Идентификационное
имя пользователя» предоставляется службой identd (RFC 1413) и определяет
имя системной учетной записи, инициировавшей подключение. В целом этот
метод аутентификации аналогичен методу trust, но с ограничением доступа
по идентификационному имени пользователя.
Как сказано в спецификации протокола ident, «Идентификационный
протокол не предназначен для аутентификации или управления доступом».
Он всего лишь является удобным средством идентификации в сетях, состоящих
из защищенных, хорошо контролируемых компьютеров, и не обеспечивает надежной
защиты при внешнем доступе. Дело в том, что демон identd всего лишь возвращает
имя, описывающее текущего пользователя системы. Например, предоставление
пользователю jworsl ey доступа из подсети IP-адресов создает серьезную
угрозу для безопасности системы, поскольку любой пользователь компьютера,
входящего в эту подсеть, сможет создать учетную запись jworsl еу и успешно
пройти «аутентификацию».
Файл pgjdent.conf должен находиться в одном каталоге с файлом pg_hba.conf.
Путь к этому каталогу определяется переменной среды PGDATA (например,
/usr/local/ pgsql/data). Как и в случае с pg_hba.conf, внесение изменений
в pgjdent.conf не требует перезапуска PostgreSQL.
Содержимое файла pgjdent.conf связывает идентификационные имена с именами
пользователей PostgreSQL при помощи особых определений, называемых картами
идентификации. Карты идентификации обычно применяются в системах, в которых
системные имена пользователей не совпадают с именами пользователей PostgreSQL.
Основные правила определения и использования карт идентификации перечислены
ниже.
- Каждая запись файла определяется в отдельной строке и связывает имя
карты, идентификационное имя пользователя и имя пользователя PostgreSQL.
- Файл pgjdent.conf может содержать несколько карт. Каждая группа строк,
в которых указано общее имя карты, рассматривается как одна карта.
- Типы подключений, относящихся к пользователям данной карты, определяются
содержимым файла pg_hba.conf.
Отдельная запись файла pgjdent.conf состоит из трех полей: имени карты,
идентификационного имени пользователя и преобразованного имени пользователя
PostgreSQL:
HMfljopibi идентификационное_имя KKfl_PostgreSQL
Поля разделяются пробелами или символами табуляции.
- имя_карты. Имя, используемое для ссылок на карту идентификации в
файле pgjiba.conf.
- идентификационное_имя. Идентификационное имя обычно совпадает с именем
пользователя системы, подключающегося к базе данных. Предоставляется
демоном identd, работающим в системе, пытающейся установить связь с
сервером.
- uмя_PostgreSQL. Имя пользователя PostgreSQL, соответствующее заданному
идентификационному имени. Файл может содержать несколько строк с одинаковыми
идентификационными именами, но разными именами PostgreSQL. Это позволяет
сопоставить одной учетной записи системного пользователя несколько учетных
записей пользователей PostgreSQL, относящихся к разным базам данных.
Допустим, на сервере базы данных booktown имеются учетные записи системных
пользователей jdrake, jworsl ey и auditor, принадлежащие соответственно
двум специалистам по сбыту и аудитору.
Для двух групп пользователей было бы логично создать пару карт идентификации.
Предположим, рабочая станция отдела сбыта имеет IP-адрес 192.168.1.3 и
ей необходим доступ только к базе данных booktown. Рабочая станция аудитора
имеет IP-адрес 192.168.1.4 и требует доступа ко всем базам данных. Файл
pgajiba.conf для такого сценария приведен в листинге 8.11.
Листинг 8.11. Выбор режима аутентификации
ident в файле pgajiba.conf
host booktown 192.168.1.3 255.255.255.255 ident sales
host all 192.168.1.4 255.255.255.255 ident audit
Содержимое этого конфигурационного файла означает, что компьютер sales
подключается к базе данных booktown с использованием карты идентификации
sales, а компьютер audit может подключаться к любой базе данных с использованием
карты audit. Обе карты должны быть соответствующим образом настроены в
файле pgjdent.conf. Пример настройки приведен в листинге 8.12.
Листинг 8.12. Пример файла pgjdent.conf
# MAP IDENT POSTGRESQLJJSERNAME
sales jdrake sales
sales jworsley sales
audit, auditor sales
audit auditor postgres
Файл, приведенный в листинге 8.12, разрешает системным пользователям
jdrake и jworsley подключение в качестве пользователя PostgreSQL sales.
Системному пользователю auditor разрешается подключение к PostgreSQL в
качестве пользователя sales или postgres.
ПРИМЕЧАНИЕ
Идентификационное имя пользователя может связываться с
несколькими именами пользователей PostgreSQL, как показано для пользователя
auditor в листинге 8.12.>
Если вы ограничиваетесь автоматической идентификацией удаленных пользователей
по методу ident, файл pgjdent.conf вам не понадобится. В этом случае вместо
имени карты в файле pgjiba.conf указывается специальное ключевое слово
sameuser.
Стоит напомнить, что этот вариант в целом аналогичен методу trust, но
в методе ident sameuser подключения ограничиваются по имени пользователя,
предоставленному демоном identd. Попытка задания имени пользователя PostgreSQL
(например, при помощи ключа -U клиента psql), отличающегося от имени,
передаваемого identd, приводит к отказу в подключении.
Пример использования ключевого слова sameuser приведен в листинге 8.13.
Листинг 8.13. Конфигурирование с использованием
ключевого слова sameuser
host booktown 192.168.1.0 255.255.255.0 ident sameuser
В этой конфигурации любой компьютер из сетевого блока 192.168.1 может
подключиться к базе данных booktown с именем PostgreSQL, совпадающим с
именем пользователя, предоставленным службой identd. Ключевое слово sameuser
заставляет PostgreSQL сравнивать имя пользователя PostgreSQL с именем,
предоставленным identd.
Отказ в аутентификации
Если попытка аутентификации завершается неудачей, PostgreSQL обычно
предоставляет содержательную информацию об ошибке, не ограничиваясь простым
отказом. Ниже перечислены некоторые распространенные сообщения об ошибках
с краткими пояснениями.
- FATAL I: user "testuser" does not exist. Имя пользователя
не найдено в системной таблице pg_shadow; это означает, что учетная
запись пользователя не существует. Создание новых пользователей описано
в главе 10.
- FATAL I: Database "testdb" does not exist In the system
catalog. Указанная база данных не существует. Если при подключении к
PostgreSQL имя базы данных не указано, по умолчанию используется имя
текущего пользователя.
- No pg_hba.conf entry for host 123.123.123.1. user testuser, database
testdb. Связь с сервером была установлена, но сервер не принял подключение.
Причина отказа заключается в том, что сервер не находит в файле pg_hba.conf
запись для пользователя testuser, обращающегося к базе данных testdb
со своего IP-адреса (123.123.123.1).
- Password authentication failed for user 'testuser1. Связь с сервером
была установлена, но в подключении отказано из-за неправильного пароля.
Проверьте введенный пароль и убедитесь в его правильности. Далее следует
проверить настройку аутентификационных пакетов (например, Kerberos или
Ident), если они используются в вашей системе.
Проверьте, назначен ли пароль указанному пользователю. Если файл pg_hba.conf
настроен на проверку паролей, эта проверка производится в любом случае,
даже если пароль не указан. Всем пользователям без пароля присваивается
пароль NULL. Когда такой пользователь пытается подключиться без указания
пароля, пароль NULL сравнивается с NULL - результат равен false.
С другой стороны, если пользователь пытается ввести пароль (пусть даже
пустую строку), введенное значение также сравнивается с NULL и результат
по-прежнему остается равным false. Если в системе требуется аутентификация
с помощью паролей, вы должны назначить пароли всем пользователям. Если
какому-либо пользователю не будет назначен пароль, аутентификация всегда
будет завершаться неудачей и пользователь не сможет подключиться к серверу. |