Postgresql 如何在Google cloud中设置vault和Postgres以获得正确的权限? 问题
我正在尝试在谷歌云中设置和发布博客 我使用liquibase来管理模式,当进行迁移时,它从vault检索用户名/密码,然后在该用户下运行以执行迁移 但是,默认的postgres用户或尝试使用该表的任何其他用户无法访问该表,并收到Postgresql 如何在Google cloud中设置vault和Postgres以获得正确的权限? 问题,postgresql,permissions,google-cloud-sql,hashicorp-vault,Postgresql,Permissions,Google Cloud Sql,Hashicorp Vault,我正在尝试在谷歌云中设置和发布博客 我使用liquibase来管理模式,当进行迁移时,它从vault检索用户名/密码,然后在该用户下运行以执行迁移 但是,默认的postgres用户或尝试使用该表的任何其他用户无法访问该表,并收到错误:关系的权限被拒绝 如果我理解正确,用户是在以postgres角色登录时创建的。这一切都可以在本地运行,但谷歌云的设置方式似乎大不相同 以下是一些输出,以查看数据库的设置情况: \du
错误:关系的权限被拒绝
如果我理解正确,用户是在以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
vault创建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实例进行复制
启动Postgres数据库的Docker命令
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;
在模拟vault用户创建的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"
尝试选择显示错误的表格
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"
我认为这里的问题与在临时用户下创建的新表有关-您的其他用户将没有访问它的权限。有几种方法可以尝试解决这个问题 第一种方法是在创建每个表之后为其授予特权。您必须根据要授予访问权限的角色相应地调整此设置,但如果您只想所有用户(当前和未来)拥有完全访问权限,则可以使用
将所有权限授予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;"
我不确定如果删除一个表所有者的用户,postgres会有什么反应,但如果有问题,那么这个解决方案也会解决。简短摘要
在表/序列/函数创建过程之后,必须运行将“$VAULT\u USERNAME”拥有的重新分配给“cloudsqlsuperuser”
,以重新分配回公共角色
更长的答案
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"
。由于vault用户被设计为临时凭证,因此我们还需要确保在临时角色下创建的对象被重新分配回某种公共角色。在我在Google Cloud中概述的特定案例中,我们将重新分配回cloudsqlsuperuser
我发现一个有效的命令是将当前_用户拥有的重新分配给“cloudsqlsuperuser”
命令,该命令将获取该临时用户拥有的所有对象,并重新分配给该公共角色
奖金:液化配置
我正在使用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>
变更集
在所有事情完成后运行,并且每次都运行。非常重要的是runAlways
和runOrder
元素。是的,我知道如果我将superuser
添加到postgres角色中,这就行了,但是谷歌云sql不允许超级用户访问……这与我最终的工作非常接近。我已经把我最后得出的答案贴出来了。谢谢你的建议!