Как настроить хранилище и Postgres в облаке Google, чтобы иметь правильные разрешения? - PullRequest
0 голосов
/ 04 июня 2018

Проблема

Я пытаюсь настроить Хашикорп хранилище и Postgres в Google Cloud.

Я использую liquibase для управления схемой, и когда она выполняет миграцию, она извлекает имя пользователя / пароль из хранилища, а затем запускается под этим пользователем для выполнения миграции.

Однако по умолчаниюПользователь postgres или любой другой пользователь, который пытается использовать эту таблицу, не может и получает ERROR: permission denied for relation.

Если я правильно понимаю, пользователи создаются при входе в систему как роль postgres.Все это работает локально, но, похоже, все в облаке Google настроено совершенно по-другому.

Вот несколько выводов, чтобы увидеть, как настроена база данных:

\du
                                                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}
 test                             | Create role, Create DB                                     
| {cloudsqlsuperuser}
 v-token-power-watc-p079t4r13s85w | Password valid until              
| {cloudsqlsuperuser}


\dt
                            List of relations
 Schema |         Name          | Type  |              Owner
--------+-----------------------+-------+------------------------------ 
 public | databasechangelog     | table | v-token-power-watc-p079t4r13s85w
 public | databasechangeloglock | table | v-token-power-watc-p079t4r13s85w
 public | test                  | table | v-token-power-watc-p079t4r13s85w

Создание хранилищаSQL выглядит примерно так:

CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; 
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "{{name}}"; 
GRANT cloudsqlsuperuser to "{{name}}";"

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

Текущие вопросы

Неужели владельцем должен быть группа cloudqlsuperuser, а не временный владелец?

Есть ли способ сделать это по умолчанию вместо того, чтобы убедиться, что все мои таблицы созданы с нужным владельцем?

Реплицировать с локальным экземпляром докера

Команда Docker для запуска базы данных Postgres

docker run --rm --name database -v $(pwd)/setup.sql:/docker-entrypoint-initdb.d/setup.sql -e POSTGRES_USER=temp -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=mydb postgres:9.6

Содержимое файла setup.sql

ALTER ROLE postgres RENAME TO cloudsqladmin;
CREATE ROLE cloudsqlsuperuser WITH CREATEDB CREATEROLE;
ALTER DATABASE mydb OWNER TO cloudsqlsuperuser;
CREATE ROLE "postgres" WITH LOGIN CREATEDB CREATEROLE IN ROLE cloudsqlsuperuser;

Создание пользователя в Postgres, имитирующего пользователя хранилищасоздание

docker exec -ti database psql -U postgres -d mydb -c "CREATE ROLE testuser WITH LOGIN IN ROLE cloudsqlsuperuser"

Создать тестовую таблицу из testuser

docker exec -ti database psql -U testuser -d mydb -c "CREATE TABLE test (col1 text)"

Попробуйте выбрать таблицу с ошибкой

docker exec -ti database psql -U postgres -d mydb -c "SELECT * FROM test"

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Краткое резюме

После процесса создания таблицы / последовательности / функции необходимо выполнить REASSIGN OWNED BY "$VAULT_USERNAME" TO "cloudsqlsuperuser", чтобы переназначить общую роль.

Более длинный ответ

Postgres 9.6 CREATE TABLE по умолчанию создаст таблицу под ролью пользователя .Поскольку пользователь хранилища предназначен для использования в качестве временных учетных данных, нам также необходимо убедиться, что объекты, созданные во временных ролях, переназначены на какую-то общую роль.В конкретном случае, который я описал в Google Cloud, мы собираемся переназначить значение cloudsqlsuperuser.

Единственная команда, которую я нашел для работы, - это команда REASSIGN OWNED BY current_user to "cloudsqlsuperuser", которая затем возьмет все объекты, принадлежащие этому временному пользователю, и присвоит эту общую роль.

Бонус: liquibase config

Я использую liquibase для выполнения миграций, и это находится в моем журнале изменений, чтобы исправить разрешения при каждом запуске миграции:

<databaseChangeLog>
    <changeSet author="elindblom" id="fix-permissions" context="" logicalFilePath="fix-permissions" runAlways="true" runOrder="last">
        <sqlFile path="baselines/sql/fix-permissions.sql" splitStatements="false" relativeToChangelogFile="true" stripComments="false"/>
    </changeSet>
   ... rest of your change logs after ...
</databaseChangeLog>

SQL выглядит такэто:

REASSIGN OWNED BY current_user TO "cloudsqlsuperuser";

changeSet запускается после того, как все завершается, и запускается каждый раз.Очень важными битами являются элементы runAlways и runOrder.

0 голосов
/ 06 июня 2018

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

Первый - предоставить привилегии для каждой таблицы после ее создания.Вам нужно будет настроить это в соответствии с ролями, к которым вы хотите предоставить доступ, но если вы просто хотите, чтобы все пользователи (текущие и будущие) имели полный доступ), вы можете использовать GRANT ALL PRIVILEGES ON <table> TO public;, как указано здесь.

Лучшим решением может быть , чтобы использовать только одного пользователя для создания всех таблиц.Вы все еще можете заставить Vault сгенерировать для него новый пароль по требованию и автоматически отменить доступ к нему, даже если имя пользователя совпадает.Для этого вам необходимо вручную создать пользователя и сначала дать ему необходимые привилегии - при условии, что вы назовете его migrator:

CREATE ROLE migrator;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "migrator"; 

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

vault write <role path here, e.g. database/roles/migrator> \
    db_name=<db name here> \
    creation_statements="ALTER ROLE migrator LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';" \
    revocation_statements="ALTER ROLE migrator NOLOGIN;"

Преимущество этого состоит в том, что вы можете использовать ALTER DEFAULT PRIVILEGES ( документы здесь * 1023)*) чтобы избавить вас от необходимости предоставлять привилегии для каждой новой создаваемой таблицы.Например, если вы знаете, что все пользователи должны иметь доступ ко всему:

ALTER DEFAULT PRIVILEGES FOR ROLE migrator GRANT ALL PRIVILEGES ON TABLES TO PUBLIC

Я не уверен, как postgres реагирует, если вы удаляете пользователя, который является владельцем таблицы, но если есть проблемас этим тогда это решение исправило бы это также.

...