首页 文章

如何在Google Cloud 中设置保险库和Postgres以获得正确的权限?

提问于
浏览
1

问题

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

我使用liquibase来管理模式,当它进行迁移时,它从Vault检索用户名/密码,然后在该用户下运行以执行迁移 .

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

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

以下是一些输出,以查看数据库的设置:

\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}}";"

我和任何其他角色一起玩 . 在这一点上我到底该怎么办,似乎无论我能通过什么选项,它都没有帮助 .

当前问题

是业主需要成为cloudsqlsuperuser组而不是temp ownwer?

有没有办法使其成为默认值,而不是必须确保我的所有表都是使用正确的所有者创建的?

使用本地docker实例进行复制

Docker Command to start Postgres Database

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

Contents of 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;

Creating user under postgres simulating vault user creation

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

Create test table from testuser

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

Try and select table demonstrating error

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

2 回答

  • 1

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

    第一种是为每个表授予权限后,必须根据您想要访问的角色对其进行相应的调整,但如果您只想让 all 用户(当前和未来)拥有完全访问权限,则可以使用 GRANT ALL PRIVILEGES ON <table> TO public; 如上所述here.

    A better solution might be 仅使用单个用户来创建所有表 . 您仍然可以让Vault根据需要为其生成新密码,并自动撤消对其的访问权限,即使用户名相同也是如此 . 要做到这一点,你必须 manually 创建用户并给它你想要的权限 - 假设你给它命名 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 PRIVILEGESdocs here)来保护您不必为每个创建的新表授予权限 . 例如,如果您知道所有用户都应该有权访问所有内容:

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

    如果你删除一个表所有者的用户,我不确定postgres会如何反应,但如果有问题,那么这个解决方案也会解决这个问题 .

  • 0

    Short Summary

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

    Longer Answer

    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" 命令,它将获取该临时用户拥有的所有对象并分配回该公共角色 .

    Bonus: 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 在所有内容完成后运行并且每次都运行 . 非常重要的位是 runAlwaysrunOrder 元素 .

相关问题