PostgreSQL ACL Server

Обновлено: 14 февраля, 2025

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

Рассматривать мы будем исключительно боевое окружение так как тестовые и сервера разработки как водится — “проходной двор”.

Обзор будет состоять из 3 частей:

  • Доступ к серверу;
  • Доступ к объектам;
  • Доступ к данным;

Сегодня мы рассмотрим вопросы доступа к серверу баз данных PostgreSQL

Доступ к серверу PostgreSQL

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

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

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

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

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

  • С серверов приложений пользователями приложений;
  • С серверов реплик пользователем репликации;

Можно еще добавить сюда сервера бекапов, но только для пользователя реплики, ибо делать pg_dump удаленно — моветон.

Администратор соединятся удаленно не может в принципе. Отсюда первое правило pg_hba.conf:

host    all         postgres    127.0.0.1/32    password

Пароль в основном как защита от дурака, так как на сервере работают службы мониторинга которые в теории могут удаленно выполнить команду shell. А пароль знаю не только я — значит знают все. Так же я не использую Unix Socket так как PostgreSQL у меня работает в контейнере и с корневой машины сокет доступен через файловую систему, а значит правила local распространяется как на контейнер так и на корневую машину.

Далее определяемся с группами внешних серверов, здесь несколько вариантов:

Netmask

Сервера приложений и сервера реплик (баз данных) выделены в отдельные сегменты приватной сети (например: 10.1.0.0/16 и 10.2.0.0/16 соответственно) и соединения осуществляются по приватным адресам, тогда запись для пользователей приложений и реплик будет выглядеть так:

host    all         postgres    127.0.0.1/32    password
host    all         +project    10.1.0.0/16     password
host    replication replica     10.2.0.0/16     password

DNS

Можно сделать записи в /etc/hosts для серверов приложений и серверов реплик. Только следует иметь ввиду что резолвится будет только первая запись с соответствующим IP адресом:

/etc/hosts

1.1.1.1     server01.production
4.3.2.1     server02.production
2.3.4.5     server03.database
5.6.7.8     server04.database

pg_hba.conf

host    all         postgres    127.0.0.1/32    password
host    all         +project    .production     password
host    replication replica     .database       password

Коннектор

У меня же стоит коннектор pgbouncer и пользователи приложений соединяются через порт 6432, а реплики через родной 5432, а в firewall настроен доступ к этим портам для соответствующих групп серверов. Парольная авторизация для пользователей приложений не нужна, так как пароль проверяет pgbouncer. В итоге pg_hba.conf имеет вид:

host    all         postgres    127.0.0.1/32    password
host    all         +project    127.0.0.1/32    trust
host    replication replica     10.0.0.0/8      password

Теперь разберем подробнее, что за пользователь +project и база данных replication.

Начнем с простого:

  • базы данных replication конечно нет, но это ключевое слово, которое говорит о том, что требуется просто сопоставить пользователя с хостом, а база данных ему не важна. И действительно, репликация оперирует всем экземпляром PostgreSQL и отдельные базы данных ему не важны (в логической репликации работают совсем другие механизмы).
  • +project — роль пользователей приложений, то есть, если все пользователи приложений принадлежат этой роли, для этого создается роль project:
CREATE ROLE projects 
    NOINHERIT 
    NOREPLICATION 
    LOGIN 
    PASSWORD 'any password';

А все остальные пользователи создаются с участием этой роли:

CREATE ROLE {{ project role }}
        NOINHERIT
        NOREPLICATION
        LOGIN
        PASSWORD '{{ some password }}'
    IN ROLE projects;

Наследовать привилегии от роли projects или нет (NOINHERIT) — дело вкуса, я так не делаю, так как это может внести некоторую путаницу.

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

В некоторых случаях можно временно предоставить определенные права пользователю, например CREATEDB, на момент инициализации приложения и разворачивании базовой схемы данных. Но после этого данное право следует отключить, если оно не требуется функционально в процессе работы (CREATEDB — это не только CREATE DATABASE, но еще и DROP DATABASE).

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

А вот доступ к определенным базам данных определяется на уровне объектов PostgreSQL. И это мы рассмотрим в следующем обзоре.

Резюме

Понятно, что такое использование pg_hba.conf не является «таблеткой» от всех болезней, но для типовых случаем подойдет более чем;

Ссылки по теме:

Опубликовано: 14 февраля, 2025

ЕЩЕ СТАТЬИ ПО ДАННОЙ ТЕМЕ

Поддержка Postgre SQL

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