微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在所有1000个postgres数据库和架构的数据库上创建只读用户

如何解决在所有1000个postgres数据库和架构的数据库上创建只读用户

我使用Vault尝试在Postgres 11.8实例中创建按需临时只读用户

我将拥有:

因此,我正在尝试找到一种方法,授予该只读用户访问每个数据库以及两个模式中所有表的权限。

我想出了以下代码段:

-- Create a new user
CREATE ROLE "my-readonly-user" WITH LOGIN PASSWORD 'test123';

-- Grant access to the two schema's we have
GRANT USAGE ON SCHEMA public TO "my-readonly-user";
GRANT USAGE ON SCHEMA reporting TO "my-readonly-user";

-- Grant access to all tables in our two schema's
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "my-readonly-user";
GRANT SELECT ON ALL TABLES IN SCHEMA reporting TO "my-readonly-user";

-- Grant access to sequences
GRANT USAGE,SELECT ON ALL SEQUENCES IN SCHEMA public TO "my-readonly-user";
GRANT USAGE,SELECT ON ALL SEQUENCES IN SCHEMA reporting TO "my-readonly-user";

-- Grant access to future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO "my-readonly-user";
ALTER DEFAULT PRIVILEGES IN SCHEMA reporting GRANT SELECT ON TABLES TO "my-readonly-user";

它仅适用于1个单一数据库(当前数据库)。如果我以只读用户身份登录并切换到某些数据库,则除了第一个数据库外,我看不到任何表。

集群包含许多数据库,其中包含许多架构。模式(甚至 相同名称)在不同的数据库中是无关的。授予 模式的特权仅适用于 当前数据库(授予时的当前数据库https://stackoverflow.com/a/24923877/1409047

由于这个限制,似乎使上面的拨款片段更加复杂。我应该以某种方式迭代我的所有数据库并运行该代码段吗?我将如何切换数据库?甚至在普通sql中也可能(根据Vault's API的要求)?有人做过吗?

注意:在MysqL中执行相同操作仅需要两行代码,使用通配*.*,而Postgres afaik不支持通配符:

CREATE USER '{{name}}'@'10.0.0.0/255.0.0.0' IDENTIFIED BY '{{password}}';
GRANT SELECT,SHOW DATABASES,SHOW VIEW ON *.* TO '{{name}}'@'10.0.0.0/255.0.0.0';

解决方法

这是一个故意的设计决策,SQL语句不能影响数据库中与您所连接的对象不同的对象。

是的,您将必须遍历集群中的所有数据库并在其中运行脚本。

请注意,您的脚本中有一个错误:您不应为序列授予只读用户USAGE,否则他们可以修改序列值。 SELECT很好。

我要做的是创建一个read_only_group(带有NOLOGIN)并将所有这些权限授予该角色。然后,当有对只读用户的请求时,创建一个用户并将其添加到该组中,以便它继承该组特权。请勿将任何内容授予用户本身,以便在不再需要它时可以轻松DROP

,

如果您想仅使用 Postgres 脚本授予用户只读访问权限,您可以这样做:

CREATE EXTENSION IF NOT EXISTS dblink;

DO 
$$
DECLARE nome_banco TEXT;
DECLARE template_conexao TEXT;
DECLARE string_conexao TEXT;
DECLARE nome_usuario TEXT;
BEGIN
    template_conexao = 'user=foo password=bar dbname=';
    nome_usuario = 'baz';

    FOR nome_banco IN
        SELECT datname FROM pg_database
        WHERE datistemplate = false
    LOOP
        string_conexao = template_conexao || nome_banco;

        perform dblink_exec(string_conexao,'GRANT CONNECT ON DATABASE "' || nome_banco || '" TO ' || nome_usuario);
        perform dblink_exec(string_conexao,'GRANT SELECT ON ALL TABLES IN SCHEMA public TO ' || nome_usuario);
    END LOOP;

END
$$

--DROP EXTENSION IF EXISTS dblink;

它连接到每个数据库,并执行脚本;它可以很容易地适应其他需要对所有数据库执行数据库本地命令的情况。

请记住,出于安全考虑,在执行上述脚本后,您应该删除由上述脚本创建的 dblink 扩展,当然,除非您已经将该扩展用于其他目的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。