【问题标题】:How to setup vault and Postgres in Google cloud to have the correct permissions?如何在谷歌云中设置保险库和 Postgres 以获得正确的权限?
【发布时间】:2018-06-27 19:30:13
【问题描述】:

问题

我正在尝试在 Google Cloud 中设置 Hashicorp vault 和 Postgres。

我正在使用 liquibase 来管理架构,当它进行迁移时,它会从保管库中检索用户名/密码,然后在该用户下运行以执行迁移。

但是,默认 postgres 用户或任何其他尝试使用该表的用户无法接收到 ERROR: permission denied for relation

如果我理解正确,用户是在以postgres 的角色登录时创建的。这一切都在本地工作,但谷歌云的东西似乎以一种截然不同的方式设置。

这里有一些输出可以查看数据库的设置:

\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 选项,它都无济于事。

当前问题

是否所有者需要是cloudsqlsuperuser组而不是临时所有者?

有没有办法将其设为默认值,而不必确保我的所有表都是由正确的所有者创建的?

使用本地 docker 实例复制

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下创建用户模拟Vault用户创建

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"

【问题讨论】:

  • 是的,我知道如果我将 superuser 添加到 postgres 角色中,这将起作用,但是 google-cloud-sql 不允许超级用户访问...

标签: postgresql permissions google-cloud-sql hashicorp-vault


【解决方案1】:

我认为这里的问题与在该临时用户下创建的新表有关 - 您的其他用户将无权访问它。有几种方法可以尝试解决这个问题。

首先是在创建每个表后为其授予权限。您必须根据您想要授予访问权限的角色进行相应调整,但如果您只希望 所有 用户(当前和未来)拥有完全访问权限),您可以使用 GRANT ALL PRIVILEGES ON <table> TO public; 作为声明here.

更好的解决方案可能是只使用一个用户来创建所有表。即使用户名相同,您仍然可以让 Vault 按需为其生成新密码并自动撤销对它的访问。为此,您必须手动创建用户并首先为其授予所需的权限 - 假设您将其命名为 migrator

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

然后更改您的保险柜配置以在您请求凭据时添加登录权限,并在您撤销它们时将其删除:

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 (docs here) 使您不必为创建的每个新表授予权限。例如,如果您知道所有用户都应该有权访问所有内容:

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

我不确定如果您删除作为表所有者的用户,postgres 会如何反应,但如果有问题,那么这个解决方案也可以解决这个问题。

【讨论】:

  • 这该死的接近我最终的工作。我已经发布了我最终解决的问题的答案。感谢您的建议!
【解决方案2】:

简短摘要

您必须在表/序列/函数创建过程之后运行REASSIGN OWNED BY "$VAULT_USERNAME" TO "cloudsqlsuperuser" 才能重新分配回公共角色。

更长的答案

Postgres 9.6 CREATE TABLE will by default create the table under the user's role。因为保管库用户被设计为临时凭证,所以我们还需要确保在临时角色下创建的对象被重新分配回某种通用角色。在我在 Google Cloud 中概述的特定情况下,我们将重新分配给 cloudsqlsuperuser

我发现可以使用的一个命令是 REASSIGN OWNED BY current_user to "cloudsqlsuperuser" 命令,该命令将获取该临时用户拥有的所有对象并分配回该公共角色。

奖励:liquibase 配置

我正在使用 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 在一切都完成后运行,并且每次都运行。非常重要的位是 runAlwaysrunOrder 元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多