20.1. Файл pg_hba.conf #

Аутентификация клиентов управляется конфигурационным файлом, который традиционно называется pg_hba.conf и расположен в каталоге с данными кластера базы данных. (HBA расшифровывается как host-based authentication — аутентификации по имени узла.) Файл pg_hba.conf, со стандартным содержимым, создаётся командой initdb при инициализации каталога с данными. Однако его можно разместить в любом другом месте; см. конфигурационный параметр hba_file.

Файл pg_hba.conf прочитывается при запуске системы, а также в тот момент, когда основной сервер получает сигнал SIGHUP. Если вы редактируете файл во время работы системы, необходимо послать сигнал процессу postmaster (используя pg_ctl reload, вызвав SQL-функцию pg_reload_conf() или выполнив kill -HUP), чтобы он прочел обновлённый файл.

Примечание

Предыдущее утверждение не касается Microsoft Windows: там любые изменения в pg_hba.conf сразу применяются к последующим подключениям.

Системное представление pg_hba_file_rules может быть полезно для предварительной проверки изменений в файле pg_hba.conf или для диагностики проблем, когда перезагрузка этого файла не даёт желаемого эффекта. Строки в этом представлении, содержащие в поле error не NULL, указывают на проблемы в соответствующих строках файла.

Общий формат файла pg_hba.conf — набор записей, по одной на строку. Пустые строки игнорируются, как и любой текст комментария после знака #. Запись может быть продолжена на следующей строке, для этого нужно завершить строку обратной косой чертой. (Обратная косая черта является спецсимволом только в конце строки.) Запись состоит из нескольких полей, разделённых пробелами и/или табуляциями. Поля могут содержать пробелы, если содержимое этих полей заключено в кавычки. Если в кавычки берётся какое-либо ключевое слово в поле базы данных, пользователя или адресации (например, all или replication), то слово теряет своё особое значение и просто обозначает базу данных, пользователя или сервер с данным именем. Обратная косая черта обозначает перенос строки даже в тексте в кавычках или комментариях.

Каждая запись аутентификации обозначает тип соединения, диапазон IP-адресов клиента (если он соотносится с типом соединения), имя базы данных, имя пользователя и способ аутентификации, который будет использован для соединения в соответствии с этими параметрами. Первая запись с соответствующим типом соединения, адресом клиента, указанной базой данных и именем пользователя применяется для аутентификации. Процедур «fall-through» или «backup» не предусмотрено: если выбрана запись и аутентификация не прошла, последующие записи не рассматриваются. Если же ни одна из записей не подошла, в доступе будет отказано.

Каждая запись может быть директивой включения или записью аутентификации. Директивы включения указывают, что нужно обработать дополнительные файлы с записями. Записи будут вставлены вместо директив включения. Директивы включения содержат только два поля: директиву include, include_if_exists или include_dir и включаемый файл или каталог. Путь к файлу или каталогу может задаваться и как абсолютный, и как относительный и заключаться в двойные кавычки. Для формы include_dir будут включены все файлы, не начинающиеся с . и заканчивающиеся на .conf. Набор файлов во включаемом каталоге обрабатывается по порядку имён (определяемому правилами, принятыми в C, т. е. цифры идут перед буквами, а буквы в верхнем регистре — перед буквами в нижнем).

Записи могут иметь следующие форматы:

local         база  пользователь  метод-аутентификации [параметры-аутентификации]
host          база  пользователь  адрес     метод-аутентификации  [параметры-аутентификации]
hostssl       база  пользователь  адрес     метод-аутентификации  [параметры-аутентификации]
hostnossl     база  пользователь  адрес     метод-аутентификации  [параметры-аутентификации]
hostgssenc    база  пользователь  адрес     метод-аутентификации  [параметры-аутентификации]
hostnogssenc  база  пользователь  адрес     метод-аутентификации  [параметры-аутентификации]
host          база  пользователь  IP-адрес  IP-маска      метод-аутентификации  [параметры-аутентификации]
hostssl       база  пользователь  IP-адрес  IP-маска      метод-аутентификации  [параметры-аутентификации]
hostnossl     база  пользователь  IP-адрес  IP-маска      метод-аутентификации  [параметры-аутентификации]
hostgssenc    база  пользователь  IP-адрес  IP-маска      метод-аутентификации  [параметры-аутентификации]
hostnogssenc  база  пользователь  IP-адрес  IP-маска      метод-аутентификации  [параметры-аутентификации]
include             файл
include_if_exists   файл
include_dir         каталог

Значения полей описаны ниже:

local

Управляет подключениями через Unix-сокеты. Без подобной записи подключения через Unix-сокеты невозможны.

host

Управляет подключениями, устанавливаемыми по TCP/IP. Записи host соответствуют подключениям c SSL и без SSL, а также подключениям, защищённым механизмами GSSAPI и не защищённым GSSAPI.

Примечание

Удалённое соединение по TCP/IP невозможно, если сервер запущен без определения соответствующих значений для параметра конфигурации listen_addresses, поскольку по умолчанию система принимает подключения по TCP/IP только для локального адреса замыкания localhost.

hostssl

Управляет подключениями, устанавливаемыми по TCP/IP с применением шифрования SSL.

Чтобы использовать эту возможность, сервер должен быть собран с поддержкой SSL. Более того, механизм SSL должен быть включён параметром конфигурации ssl (подробнее об этом в Разделе 18.9). В противном случае запись hostssl не играет роли (не считая предупреждения о том, что ей не будут соответствовать никакие подключения).

hostnossl

Этот тип записей противоположен hostssl, ему соответствуют только подключения по TCP/IP без шифрования SSL.

hostgssenc

Управляет подключениями, устанавливаемыми по TCP/IP, для которых применяется шифрование GSSAPI.

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

hostnogssenc

Этот тип записей противоположен hostgssenc; ему соответствуют только подключения по TCP/IP без шифрования GSSAPI.

база

Определяет, каким именам баз данных соответствует эта запись. Значение all определяет, что подходят все базы данных. Значение sameuser определяет, что данная запись соответствует, только если имя запрашиваемой базы данных совпадает с именем запрашиваемого пользователя. Значение samerole определяет, что запрашиваемый пользователь должен быть членом роли с таким же именем, как и у запрашиваемой базы данных. (samegroup — это устаревший, но допустимый вариант значения samerole.) Суперпользователи, несмотря на то, что они имеют полные права, считаются включёнными в samerole, только когда они явно входят в такую роль, непосредственно или косвенно. Значение replication показывает, что запись соответствует, когда запрашивается подключение для физической репликации, но не когда запрашивается подключение для логической. Имейте в виду, что для подключений физической репликации не указывается какая-то конкретная база данных, в то время как для подключений логической репликации должна указываться конкретная база. Любое другое значение воспринимается как имя определённой базы PostgreSQL или регулярное выражение. Несколько регулярных выражений и/или имён баз данных можно указать, разделяя их запятыми.

Если имя базы данных начинается с косой черты (/), оставшаяся часть имени обрабатывается как регулярное выражение. (Подробнее синтаксис регулярных выражений PostgreSQL описан в Подразделе 9.7.3.1.)

Также можно задать отдельный файл с именами баз данных и/или регулярными выражениями, написав имя файла после знака @.

пользователь

Указывает, какому имени (или именам) пользователя базы данных соответствует эта запись. Значение all указывает, что запись соответствует всем пользователям. Любое другое значение задаёт либо имя конкретного пользователя базы данных, либо регулярное выражение (если это значение начинается с /), либо имя группы (если это значение начинается с +). (Напомним, что в PostgreSQL нет никакой разницы между пользователем и группой; знак + означает «совпадение любых ролей, которые прямо или косвенно являются членами роли», тогда как имя без знака + является подходящим только для этой конкретной роли.) В связи с этим, суперпользователь рассматривается как член роли, только если он явно является членом этой роли, прямо или косвенно, а не только потому, что он является суперпользователем. Несколько регулярных выражений и/или имён пользователей можно указать, разделяя их запятыми.

Если имя пользователя начинается с косой черты (/), оставшаяся часть имени обрабатывается как регулярное выражение. (Подробнее синтаксис регулярных выражений PostgreSQL описан в Подразделе 9.7.3.1.)

Также можно задать отдельный файл с именами пользователей и/или регулярными выражениями, написав имя файла после знака @.

адрес

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

Диапазон IP-адресов указывается в виде начального адреса диапазона, дополненного косой чертой (/) и длиной маски CIDR. Длина маски задаёт количество старших битов клиентского IP-адреса, которые должны совпадать с битами IP-адреса диапазона. Биты, находящиеся правее, в указанном IP-адресе должны быть нулевыми. Между IP-адресом, знаком / и длиной маски CIDR не должно быть пробельных символов.

Типичные примеры диапазонов адресов IPv4, указанных таким образом: 172.20.143.89/32 для одного компьютера, 172.20.143.0/24 для небольшой и 10.6.0.0/16 для крупной сети. Диапазон адресов IPv6 может выглядеть как ::1/128 для одного компьютера (это адрес замыкания IPv6) или как fe80::7a31:c1ff:0000:0000/96 для небольшой сети. 0.0.0.0/0 представляет все адреса IPv4, а ::0/0 — все адреса IPv6. Чтобы указать один компьютер, используйте длину маски 32 для IPv4 или 128 для IPv6. Опускать замыкающие нули в сетевом адресе нельзя.

Запись, сделанная в формате IPv4, подойдёт только для подключений по IPv4, а запись в формате IPv6 подойдёт только для подключений по IPv6, даже если представленный адрес находится в диапазоне IPv4-в-IPv6.

Вы также можете прописать значение all, чтобы указать любой IP-адрес, samehost, чтобы указать любые IP-адреса данного сервера, или samenet, чтобы указать любой адрес любой подсети, к которой сервер подключён напрямую.

Если определено имя компьютера (всё, что не является диапазоном IP-адресов или специальным ключевым словом, воспринимается как имя компьютера), то оно сравнивается с результатом обратного преобразования IP-адреса клиента (например, обратного DNS-запроса, если используется DNS). При сравнении имён компьютеров регистр не учитывается. Если имена совпали, выполняется прямое преобразование имени (например, прямой DNS-запрос) для проверки, относится ли клиентский IP-адрес к адресам, соответствующим имени. Если двусторонняя проверка пройдена, запись считается соответствующей компьютеру. (В качестве имени узла в файле pg_hba.conf должно указываться то, что возвращается при преобразовании IP-адреса клиента в имя, иначе строка не будет соответствовать узлу. Некоторые базы данных имён позволяют связать с одним IP-адресом несколько имён узлов, но операционная система при попытке разрешить IP-адрес возвращает только одно имя.)

Указание имени, начинающееся с точки (.), соответствует суффиксу актуального имени узла. Так, .example.com будет соответствовать foo.example.com (а не только example.com).

Когда в pg_hba.conf указываются имена узлов, следует добиться, чтобы разрешение имён выполнялось достаточно быстро. Для этого может быть полезен локальный кеш разрешения имён, например, nscd. Вы также можете включить конфигурационный параметр log_hostname, чтобы видеть в журналах имя компьютера клиента вместо IP-адреса.

Эти поля не применимы к записям local.

Примечание

Пользователи часто задаются вопросом, почему имена серверов обрабатываются таким сложным, на первый взгляд, способом, с разрешением двух имён, включая обратный запрос клиентского IP-адреса. Это усложняет процесс в случае, если обратная DNS-запись клиента не установлена или включает в себя нежелательное имя узла. Такой способ избран, в первую очередь, для повышения эффективности: в этом случае соединение требует максимум два запроса разрешения, один прямой и один обратный. Если есть проблема разрешения с каким-то адресом, то она остаётся проблемой этого клиента. Гипотетически, могла бы быть реализована возможность во время каждой попытки соединения выполнять только прямой запрос для разрешения каждого имени сервера, упомянутого в pg_hba.conf. Но если список имён велик, процесс был бы довольно медленным, а в случае наличия проблемы разрешения у одного имени сервера, это стало бы общей проблемой.

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

Обратите внимание, что такое поведение согласуется с другими популярными реализациями контроля доступа на основе имён, такими как Apache HTTP Server и TCP Wrappers.

IP-адрес
IP-маска

Эти два поля могут быть использованы как альтернатива записи IP-адрес/длина-маски. Вместо того, чтобы указывать длину маски, в отдельном столбце указывается сама маска. Например, 255.0.0.0 представляет собой маску CIDR для IPv4 длиной 8 бит, а 255.255.255.255 представляет маску CIDR длиной 32 бита.

Эти поля не применимы к записям local.

метод-аутентификации

Указывает метод аутентификации, когда подключение соответствует этой записи. Варианты выбора приводятся ниже; подробности в Разделе 20.3. Все значения воспринимаются с учётом регистра и должны быть записаны в нижнем регистре, даже аббревиатуры типа ldap.

trust

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

reject

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

scram-sha-256

Проверяет пароль пользователя, производя аутентификацию SCRAM-SHA-256. За подробностями обратитесь к Разделу 20.5.

md5

Проверяет пароль пользователя, производя аутентификацию SCRAM-SHA-256 или MD5. За подробностями обратитесь к Разделу 20.5.

password

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

gss

Для аутентификации пользователя использует GSSAPI. Этот способ доступен только для подключений по TCP/IP. За подробностями обратитесь к Разделу 20.6. Он может применяться в сочетании с шифрованием GSSAPI.

sspi

Для аутентификации пользователя использует SSPI. Способ доступен только для Windows. За подробностями обратитесь к Разделу 20.7.

ident

Получает имя пользователя операционной системы клиента, связываясь с сервером Ident, и проверяет, соответствует ли оно имени пользователя базы данных. Аутентификация ident может использоваться только для подключений по TCP/IP. Для локальных подключений применяется аутентификация peer. За подробностями обратитесь к Разделу 20.8.

peer

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

ldap

Проводит аутентификацию, используя сервер LDAP. За подробностями обратитесь к Разделу 20.10.

radius

Проводит аутентификацию, используя сервер RADIUS. За подробностями обратитесь к Разделу 20.11.

cert

Проводит аутентификацию, используя клиентский сертификат SSL. За подробностями обратитесь к Разделу 20.12.

pam

Проводит аутентификацию, используя службу подключаемых модулей аутентификации (PAM), предоставляемую операционной системой. За подробностями обратитесь к Разделу 20.13.

bsd

Проводит аутентификацию, используя службу аутентификации BSD, предоставляемую операционной системой. За подробностями обратитесь к Разделу 20.14.

параметры-аутентификации

После поля метод-аутентификации может идти поле (поля) вида имя=значение, определяющее параметры метода аутентификации. Подробнее о параметрах, доступных для различных методов аутентификации, рассказывается ниже.

Помимо описанных далее параметров, относящихся к различным методам, есть один общий параметр аутентификации clientcert, который можно задать в любой записи hostssl. Он может принимать значения verify-ca и verify-full. В обоих случаях клиент должен предоставить годный (доверенный) сертификат SSL, но вариант verify-full дополнительно требует, чтобы значение cn (Common Name, Общее имя) в сертификате совпадало с именем пользователя или применимым сопоставлением. Это указание работает подобно методу аутентификации cert (см. Раздел 20.12), но позволяет связать проверку клиентских сертификатов с любым методом аутентификации, поддерживающим записи hostssl.

В любой записи, включающей аутентификацию по клиентскому сертификату (то есть в записи с методом аутентификации cert или с параметром clientcert), в дополнительном параметре clientname можно выбрать сопоставляемый при проверке элемент учётных данных в клиентском сертификате. Этот параметр может иметь одно из двух значений. Если указано значение clientname=CN (оно подразумевается по умолчанию), имя пользователя сопоставляется с полем Common Name (CN). Если указано значение clientname=DN — с полем Distinguished name (DN). Этот вариант, вероятно, будет лучше использовать с сопоставлениями имён пользователей. Сравнение DN выполняется в формате RFC 2253. Извлечь поле DN в этом формате из клиентского сертификата можно так:

openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//"

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

include

Эта строка будет заменена на содержимое указанного файла.

include_if_exists

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

include_dir

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

Файлы, включённые в конструкции, начинающиеся с @, читаются, как список имён, разделённых запятыми или пробелами. Комментарии предваряются знаком #, как и в файле pg_hba.conf, и вложенные @ конструкции допустимы. Если только имя файла, начинающегося с @ не является абсолютным путём.

Поскольку записи файла pg_hba.conf рассматриваются последовательно для каждого подключения, порядок записей имеет большое значение. Обычно более ранние записи определяют чёткие критерии для соответствия параметров подключения, но для методов аутентификации допускают послабления. Напротив, записи более поздние смягчают требования к соответствию параметров подключения, но усиливают их в отношении методов аутентификации. Например, некто желает использовать trust аутентификацию для локального подключения по TCP/IP, но при этом запрашивать пароль для удалённых подключений по TCP/IP. В этом случае запись, устанавливающая аутентификацию trust для подключения адреса 127.0.0.1, должна предшествовать записи, определяющей аутентификацию по паролю для более широкого диапазона клиентских IP-адресов.

Подсказка

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

Примеры записей файла pg_hba.conf показаны в Примере 20.1. Обратитесь к следующему разделу за более подробной информацией по методам аутентификации.

Пример 20.1. Примеры записей pg_hba.conf

# Позволяет любому пользователю локальной системы подключаться
# к любой базе данных, используя любое имя пользователя баз данных, через
# Unix-сокеты (по умолчанию для локальных подключений).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     trust

# То же, но для локальных замкнутых подключений по TCP/IP.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             127.0.0.1/32            trust

# То же, что и в предыдущей строке, но с указанием
# сетевой маски в отдельном столбце
#
# TYPE  DATABASE        USER            IP-ADDRESS      IP-MASK             METHOD
host    all             all             127.0.0.1       255.255.255.255     trust

# То же для IPv6.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             ::1/128                 trust

# То же самое, но с использованием имени узла
# (обычно покрывает и IPv4, и IPv6).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             localhost               trust

# То же самое с использованием регулярного выражения для DATABASE, позволяющего подключиться
# к любым базам данных с именем, начинающимся с "db" и заканчивающимся
# на число, содержащее от 2 до 4 цифр (например, "db1234" или "db12").
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    "/^db\d{2,4}$"  all             localhost               trust

# Позволяет любому пользователю любого компьютера с IP-адресом
# 192.168.93.x подключаться к базе данных "postgres"
# с именем, которое сообщает для данного подключения ident
# (как правило, имя пользователя операционной системы).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    postgres        all             192.168.93.0/24         ident

# Позволяет любому пользователю компьютера 192.168.12.10 подключаться
# к базе данных "postgres", если он передаёт правильный пароль.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    postgres        all             192.168.12.10/32        scram-sha-256

# Позволяет любым пользователям с компьютеров в домене example.com
# подключаться к любой базе данных, если передаётся правильный пароль.
#
# Для всех пользователей требуется аутентификация SCRAM, за исключением
# пользователя 'mike', который использует старый клиент, не поддерживающий
# аутентификацию SCRAM.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             mike            .example.com            md5
host    all             all             .example.com            scram-sha-256

# В случае отсутствия предшествующих строчек с "host", следующие две строки
# откажут в подключении с 192.168.54.1 (поскольку данная запись будет
# выбрана первой), но разрешат подключения GSSAPI с любых других
# адресов. С нулевой маской ни один бит из IP-адреса компьютера
# не учитывается, так что этой строке соответствует любой компьютер.
# Незашифрованные средствами GSSAPI подключения (они "опускаются"
# до третьей строки, так как записи "hostgssenc"
# соответствуют только
# зашифрованные подключения) принимаются, но только с адреса 192.168.12.10.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.54.1/32         reject
hostgssenc all          all             0.0.0.0/0               gss
host    all             all             192.168.12.10/32        gss

# Позволяет пользователям с любого компьютера 192.168.x.x подключаться
# к любой базе данных, если они проходят проверку ident. Если же ident
# говорит, например, что это пользователь "bryanh" и он запрашивает
# подключение как пользователь PostgreSQL "guest1", подключение
# будет разрешено, если в файле pg_ident.conf есть сопоставление
# "omicron", позволяющее пользователю "bryanh" подключаться как "guest1".
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.0.0/16          ident map=omicron

# Если для локальных подключений предусмотрены только эти четыре строки,
# они позволят локальным пользователям подключаться только к своим
# базам данных (базам данных с именами, совпадающими с
# именами пользователей баз данных), кроме пользователей, чьё имя
# заканчивается на "helpdesk", администраторов
# или членов роли "support", которые могут подключиться к любой БД.
# Список имён администраторов содержится в файле $PGDATA/admins.
# Пароли требуются в любом случае.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   sameuser        all                                     md5
local   all             /^.*helpdesk$                           md5
local   all             @admins                                 md5
local   all             +support                                md5

# Последние две строчки выше могут быть объединены в одну:
local   all             @admins,+support                        md5

# В столбце DATABASE также могут указываться списки и имена файлов:
local   db1,db2,@demodbs  all                                   md5