Реализация наилучшей практики ролей Postgres


21

Folks,

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

Существует один сервер с одной установкой Postgres v9.2. Эта установка содержит несколько баз данных, каждая из которых полностью обслуживает своего «клиента». Другими словами, customer1 не будет, не должен использовать database2 и так далее. Во время обычной работы базы данных получают доступ к соответствующему экземпляру CakePHP, все они расположены на том же сервере, что и Postgres. Несмотря на возможную оптимизацию этого развертывания, меня больше всего интересуют роли Psql.

Исходя из того, что я прочитал, кажется, что три типа ролей имеют смысл:

  • Superuser Postgres с паролем не по умолчанию
  • Роль администратора, которая не имеет привилегий суперпользователя для текущего обслуживания, создания БД, резервного копирования, восстановления. Должен быть в состоянии сделать что-нибудь со всеми базами данных клиентов.
  • Роли пользователей с возможностью CRUD в соответствующей базе данных. Больше прав на их собственную БД может быть допущено, если это очищает реализацию.

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

     Role name |                   Attributes                   |     Member of     
    -----------+------------------------------------------------+-------------------
     admin     | Create role, Create DB                         | {user1, user2}
     postgres  | Superuser, Create role, Create DB              | {}
     user1     |                                                | {}
     user2     |                                                | {}

    postgres=# \l
                                 List of databases
       Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
    -----------+----------+----------+---------+-------+-----------------------
     admin     | postgres | UTF8     | en_US   | en_US | =Tc/postgres         +
               |          |          |         |       | postgres=CTc/postgres+
               |          |          |         |       | admin=CTc/postgres
     postgres  | postgres | UTF8     | en_US   | en_US | 
     template0 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     user1     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user1=CTc/admin
     user2     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user2=CTc/admin

Для предотвращения внешних подключений и паролей в открытом виде pg_hba.conf выглядит так:

local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

1
По моему опыту, лучшее разделение, которое также приносит огромное количество других преимуществ, - это запуск отдельных кластеров PostGreSQL (например, сервисов) для каждого клиента. Это то, что мы сейчас делаем для большой производственной среды, и я бы не стал делать это иначе, если бы количество БД не становилось действительно большим, а каждая из них была бы очень маленькой. Разумеется, приложению также необходимо знать, как подключаться к разным источникам данных для каждого арендатора (клиента).
Флорин Asăvoaie

Рядом с @ FlorinAsăvoaie его замечание. Разве у каждой базы данных не должно быть своего собственного владельца и пользователя запроса? Это облегчит помещение определенных пользователей в хранилище паролей для целей обслуживания.
hspaans

Ответы:


5

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

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

  1. В одном кластере базы данных, как описано в ОП, мой личный выбор будет следующим:

    • Пользователь postgres использует одноранговую аутентификацию и не допускает парольные соединения. Аутентификация MD5, на мой взгляд, плохая практика. Если у вас возникнут какие-либо проблемы с согласованностью базы данных или подобными вещами, вы все равно сможете войти, если позволите postgres использовать одноранговую аутентификацию.
    • Каждый клиент должен получить собственную схему, а не базу данных. Есть несколько причин для этого:
      • Владение всей базой данных даст много привилегий.
      • Владение только определенными таблицами создаст проблемы для разработчиков и всегда будет требовать от администраторов добавления разрешений и прочего.
      • Таким образом, в обычной установке каждый из них получит доступ к созданию объектов внутри своей схемы, включая таблицы, представления, триггеры и т. Д.
      • Все они используют одну и ту же строку подключения, кроме имени пользователя. В postgres по умолчанию, если у вас есть схема с именем вашего пользователя, она автоматически указывается в вашем пути поиска.
    • В качестве меры безопасности я бы предпочел не иметь администратора, который мог бы получить доступ к каждой схеме. Вы должны делать резервные копии либо путем выгрузки каждой схемы своим собственным пользователем, либо с использованием техники PITR PostgreSQL. Вам все еще нужно будет использовать пользователя postgres для создания новых схем, я бы выбрал правило sudo и скрипт для этого.
    • Многие передовые практики в области безопасности рекомендуют удалить схему по умолчанию, поэтому - поехали.
    • Это решение очень подходит, если база данных для каждого клиента мала и у вас есть тонны клиентов.
    • Если ваше приложение обрабатывает мультитенантность, оно может использовать единый пул соединений для всех клиентов. Конечно, это устраняет многие из перечисленных выше улучшений безопасности, но может иметь преимущества в производительности, особенно если у вас большое количество клиентов (если у вас есть 500-1000 отдельных источников данных и вы используете пул соединений, это будет весьма подавляющим).
  2. Каждый клиент получает свой кластер базы данных. Это мое предпочтительное решение, особенно потому, что я обычно работаю с приложениями, которые имеют большие базы данных для каждого клиента.

    • Это приносит очень хорошее разделение данных. Вы можете использовать отдельные тома хранения для каждого клиента, распределять ограничения по процессору и памяти (используя docker?).
    • Действительно хорошая гибкость в отношении того, что нужно каждому клиенту в своем случае. Они могут быть похожими или иметь разные черты.
    • Очень легко масштабировать в обоих направлениях (вверх и наружу).
    • Я также использую отдельные виртуальные IP-адреса, где каждый кластер прислушивается к соединениям, что приводит к горизонтальному масштабированию и не требует перенастройки источника данных.
    • Резервные копии PITR выполняются для каждого клиента, поэтому будет проще восстановить одного клиента по сравнению с мультитенантностью для каждой схемы.
    • При сложных настройках каждому клиенту может потребоваться несколько баз данных, схем, пользователей и ролей и т. Д., Так что в этом случае это лучшее решение.

Вы также можете использовать комбинацию из вышеперечисленного и использовать pgBouncer в качестве маршрутизатора.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.