GCP SQL Postgres проблема с привилегиями: не удается выполнить запрос с пользователем postgres с сгенерированной базой данных symfony - PullRequest
0 голосов
/ 09 сентября 2018

Я пытаюсь решить эту проблему с помощью облачного SQL-компонента Google Cloud Platform. Мой технический стек состоит из размещения моего приложения в развертывании Google Kubernetes Engine (GKE) с использованием прокси-сервера Cloud SQL для подключения к базе данных в модулях. Бэкэнд - это проект Symfony.

Я выполняю следующие шаги для создания и заполнения базы данных (без успеха):

  1. Создание экземпляра Cloud SQL Postgres
  2. Добавить прокси в контейнер k8s для подключения к экземпляру Cloud SQL со всеми учетными данными, как описано в документации GCP
  3. Введите мой модуль Symfony (phpfpm) и выполните команду php bin/console doctrine:schema:update --force, чтобы обновить схему. Запросы выполняются в базе данных, поэтому создается схема и т. Д.
  4. Я пытаюсь открыть базу данных из соединения консоли SQL в GCP с пользователем postgres и пытаюсь выполнить простой запрос select * from foo;. Ответ Insufficient privilege: 7 ERROR: permission denied for relation

Как запросить данные в базе данных у пользователя postgres?

РЕДАКТИРОВАТЬ:

У меня такая ситуация с пользователями:

     Role name     |                         Attributes                         |           Member of           
-------------------+------------------------------------------------------------+-------------------------------
 acando14          | Create role, Create DB                                     | {cloudsqlsuperuser,proxyuser}
 cloudsqladmin     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 cloudsqlagent     | Create role, Create DB                                     | {cloudsqlsuperuser}
 cloudsqlreplica   | Replication                                                | {}
 cloudsqlsuperuser | Create role, Create DB                                     | {}
 postgres          | Create role, Create DB                                     | {cloudsqlsuperuser,acando14}
 proxyuser         | Create role, Create DB                                     | {cloudsqlsuperuser}

А у меня такая ситуация в таблицах:

              List of relations
 Schema |      Name       | Type  |  Owner   
--------+-----------------+-------+----------
 public | article         | table | acando14

Если я использую postgres, пользователь вошел в мою базу данных symfony works:

symfony => select * from article;
 id | model_id | code | size 
----+----------+------+------
(0 rows)

Но если я использую сервер для выполнения кода, ответ будет:

SQLSTATE [42501]: недостаточно прав: 7 ОШИБКА: отказано в разрешении для сотрудника по связям с PDOException (код: 42501): SQLSTATE [42501]: Недостаточно прав: 7 ОШИБКА: в разрешении отказано для связи .. на

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

Спасибо, с уважением

1 Ответ

0 голосов
/ 09 сентября 2018

Пользователь по умолчанию postgres в облачном SQL (GCP) Google Cloud Platform (PostgreSQL) не является суперпользователем экземпляра ( ссылка на документы GCP ):

При создании нового экземпляра Cloud SQL для PostgreSQL ... пользователь postgres входит в роль cloudsqlsuperuser и имеет следующие атрибуты (привилегии): CREATEROLE, CREATEDB и LOGIN. Он не имеет атрибутов SUPERUSER или REPLICATION.

Атрибут superuser дает пользователю возможность обойти все проверки разрешений и, соответственно, он может перейти в любое место в экземпляре базы данных для чтения данных из любой базы данных ( Ссылка на документацию PostgreSQL ):

Суперпользователь базы данных обходит все проверки разрешений, кроме права на вход.

В типичном развертывании PostgreSQL вне GCP пользователь postgres действительно является суперпользователем. Это отклонение в облачном SQL нарушает обычное соглашение, ожидаемое от Postgres, что пользователь postgres всегда может получить доступ и изменить любой объект в кластере в силу этих прав суперпользователя.

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

Я предполагаю, что вы используете отдельного выделенного пользователя для своего развертывания k8s для подключения к базе данных, а не пользователя postgres. По умолчанию роль этого пользователя будет принадлежать объектам, созданным операцией заполнения схемы. Согласно документации GRANT этот владелец по умолчанию будет иметь полный набор привилегий для объекта:

Если столбец «Права доступа» для данного объекта пуст, это означает, что объект имеет права по умолчанию (то есть столбец привилегий равен нулю). Привилегии по умолчанию всегда включают все привилегии для владельца ...


Альтернативы

  • (рекомендуется) Создайте выделенную роль, которую можно разделить между postgres пользователем и любыми другими пользователями, с которыми вы входите в базу данных, чтобы заполнить ее схему.

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

    Например, для этой цели вы можете использовать роль cloudsqlsuperuser, в которой автоматически участвуют все пользователи, созданные в консоли и встроенные в postgres. Однако я бы порекомендовал создать пользовательскую роль для этой цели:

    CREATE ROLE symfonyapp;
    GRANT symfonyapp TO postgres;
    GRANT symfonyapp TO <your_k8s_application_user>;
    

    Позже, при создании объектов базы данных, убедитесь, что вы взяли на себя роль symfonyapp, прежде чем делать это. На консоли запустите:

    SET ROLE symfonyapp;
    

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

  • Создайте роль, как указано выше, и назначьте ее пользователю postgres. Кроме того, присвойте роли атрибут LOGIN и установите пароль, который позволит вам войти в экземпляр базы данных, используя имя роли и пароль напрямую. В этом случае пользователь postgres наследует привилегии роли (например, принадлежащие ему объекты), а возможность входа в систему напрямую устраняет необходимость вызова SET ROLE при первом подключении.

  • Для уже созданных объектов вы можете настроить их владельца в соответствии с пользовательской ролью с помощью команды ALTER <TYPE> <name> OWNER TO symfonyapp; например:

    ALTER TABLE mytable OWNER TO symfonyapp;
    

Невозможно напрямую предоставить атрибут роли SUPERUSER пользователю postgres, поскольку у вас нет доступа к пользователю с правами SUPERUSER для этого! (Только суперпользователи могут делать других пользователей суперпользователями.) Google Cloud SQL для Postgres документация отмечает конкретное исключение поддержки любых функций, которые требуют привилегий суперпользователя, поэтому этот маршрут вам недоступен. Единственный суперпользователь - это пользователь cloudsqladmin, созданный по умолчанию и используемый Google для выполнения административных операций на уровне экземпляра от вашего имени; Вы могли бы сбросить пароль и войти в систему под этой учетной записью, чтобы предоставить привилегии суперпользователя, но я не рекомендую делать это, поскольку это может нарушить другие управляемые функции.


Рабочий пример

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

                                        List of roles
     Role name     |                         Attributes                         |      Member of
-------------------+------------------------------------------------------------+---------------------
 cloudsqladmin     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 cloudsqlagent     | Create role, Create DB                                     | {cloudsqlsuperuser}
 cloudsqlreplica   | Replication                                                | {}
 cloudsqlsuperuser | Create role, Create DB                                     | {}
 postgres          | Create role, Create DB                                     | {cloudsqlsuperuser}

Кроме того, новым базам данных, созданным с помощью вкладки «Базы данных» в Cloud Console, по умолчанию назначено право собственности на роль cloudsqlsuperuser. (Как показано в приведенном выше списке ролей, роль cloudsqlsuperuser наследуется пользователем postgres.)

                                  List of databases
  Name  |       Owner       | Encoding |  Collate   |   Ctype    | Access privileges
--------+-------------------+----------+------------+------------+-------------------
 testdb | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 |

Соответственно, члены роли cloudsqlsuperuser будут иметь разрешения на создание объектов в базе данных по умолчанию. Однако при этом им по умолчанию будет назначен владелец, который их создал, а не родительская роль:

testdb=> CREATE TABLE sometable (id SERIAL NOT NULL);
CREATE TABLE
testdb=> \dt sometable
           List of relations
 Schema |   Name    | Type  |  Owner
--------+-----------+-------+----------
 public | sometable | table | testuser

Если мы вызовем SET ROLE cloudsqlsuperuser перед созданием нашей таблицы, владелец теперь будет использовать по умолчанию роль cloudsqlsuperuser, что позволит postgres и другим членам роли разрешения по умолчанию, назначенные роли по умолчанию:

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

testdb=> SET ROLE cloudsqlsuperuser;
SET
testdb=> CREATE TABLE anothertable (id SERIAL NOT NULL);
CREATE TABLE
testdb=> \dt anothertable;
                 List of relations
 Schema |     Name     | Type  |       Owner
--------+--------------+-------+-------------------
 public | anothertable | table | cloudsqlsuperuser
(1 row)

Для производственного использования, как отмечено в разделе «Альтернативы», я рекомендую использовать выделенную роль, а не встроенную роль cloudsqlsuperuser.

...