在PostgreSQL中创建真正的只读用户

4xrmg8kj  于 2023-02-08  发布在  PostgreSQL
关注(0)|答案(1)|浏览(173)

我已经在Digital Ocean中扩展了一个PostgreSQL数据库,现在我需要一组用户和数据库,我已经考虑过为它们创建几个数据库(productionstaging等),并且每个数据库有2个关联角色,具有只读和读写权限(production_roproduction_rwstaging_rostaging_rw等)。我的想法是,通过拥有这些角色,我现在可以创建单独的用户,并为他们分配一个角色,以便在发生违规时可以快速更改/删除他们。
我一直在研究这个问题,我能找到的所有页面都有一组类似于in here的指令:

-- Revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE mydatabase FROM PUBLIC;

-- Read-only role
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE mydatabase TO readonly;
GRANT USAGE ON SCHEMA myschema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO readonly;

-- Read/write role
CREATE ROLE readwrite;
GRANT CONNECT ON DATABASE mydatabase TO readwrite;
GRANT USAGE, CREATE ON SCHEMA myschema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA myschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA myschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE ON SEQUENCES TO readwrite;

-- Users creation
CREATE USER reporting_user1 WITH PASSWORD 'some_secret_passwd';
CREATE USER reporting_user2 WITH PASSWORD 'some_secret_passwd';
CREATE USER app_user1 WITH PASSWORD 'some_secret_passwd';
CREATE USER app_user2 WITH PASSWORD 'some_secret_passwd';

-- Grant privileges to users
GRANT readonly TO reporting_user1;
GRANT readonly TO reporting_user2;
GRANT readwrite TO app_user1;
GRANT readwrite TO app_user2;

我仔细地遵循了这些说明,并监视它们中没有一个失败,但是,在成功地运行了所有这些说明之后,我只剩下了一些假定为只读的用户,他们实际上可以创建表,看不到其他用户创建的表,还可以切换数据库。
我哪里做错了?

  • --修改---
    这是\dn+命令的结果:
List of schemas
  Name  |  Owner   |  Access privileges   |      Description
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         |
  • --编辑2---
    下面是我所做的(出于安全原因,我将用户编辑为<USER_A><USER_B>等。这些编辑的用户将与真实用户进行1:1匹配):
$ psql "postgresql://USER_A:<PASSWORD>@<DOMAIN>:<PORT>/<DEFAULT_DB>?sslmode=require"
psql (15.1, server 14.6)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

<DEFAULT_DB>=> \connect production
psql (15.1, server 14.6)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
You are now connected to database "production" as user "USER_A"
production=> \du
                                                                      List of roles
    Role name    |                         Attributes                         |                                 Member of
-----------------+------------------------------------------------------------+---------------------------------------------------------------------------
 USER_B          | Superuser, Replication                                     | {}
 USER_A          | Create role, Create DB, Replication, Bypass RLS            | {pg_read_all_stats,pg_stat_scan_tables,pg_signal_backend,r_production_ro}
 postgres        | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 production_ro   | Cannot login                                               | {}

production=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
WARNING:  no privileges could be revoked for "public"
REVOKE
production=>
qlfbtfca

qlfbtfca1#

如果用户可以创建表,则该用户对相关方案具有CREATE权限。请在psql中查看具有\dn+ public的权限。确定相关权限并对其进行REVOKE
或者,如果您使用PostgreSQL v15或更高版本,则您的数据库用户可能直接或间接是预定义角色pg_write_all_data的成员。请撤销该成员资格。
在您的特定情况下,正确的做法是从PUBLIC(即每个人)撤销模式public上的默认CREATE权限:

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

你说你已经这么做了,但它引起了警告,没有任何效果。这不是PostgreSQL会做的。你必须问修改PostgreSQL的人,在你的例子中是DigitalOcean。

相关问题