Postgresql 中用户权限的最佳实践?

Joh*_*nst 6 mysql database postgresql

我是 postgres 新手,我正在尝试找出在运行 Web 应用程序时如何最好地保护我的数据库。

在 MySQL 中,我倾向于使用管理用户来执行诸如创建数据库、创建表、修改架构、删除表等操作:用于某些应用程序持续使用数据库时不应该发生的所有活动。然后,我有第二个用户(每个应用程序一个),该用户(仅)拥有应用程序所需的权限,例如插入、更新等。这可以避免应用程序错误/黑客造成灾难性后果。

现在我想弄清楚如何在 postgres 中做类似的事情。与 MySQL 不同,postgres 数据库似乎有一个“所有者”。如果我使用上面的方案,管理用户是否应该“拥有”所有应用程序的所有数据库?或者这里有哪些最佳实践?

另外:我只是发现授予“所有表”权限似乎意味着“当前定义的所有表”并且不包括将来的表。与 MySQL 不同,“on foo.*”表示所有当前和未来的表。那是对的吗?有没有办法在授予语句中包含未来的表,或者我每次都重新执行?

Den*_*dov 9

我的最佳实践是:

  1. 为应用程序创建自定义数据库
  2. 为应用程序的自定义数据库创建自定义架构
  3. 创建DDL角色
  4. 创建DML角色
  5. 从 PUBLIC 撤销创建的自定义数据库上的所有内容
  6. 将模式 PUBLIC 上的创建撤销到 DB-ses postgres 并创建自定义数据库
  7. 在 DDL 角色的自定义架构上授予 USAGE 和 CREATE
  8. 仅授予 DML 角色的自定义架构上的 USAGE
  9. 创建具有 DDL 角色的用户以进行 DDL 应用程序操作(用于 Flyway 或 liquibase 迁移、创建/更改/删除实体等)
  10. 创建具有 DML 角色的用户以进行 DML 应用操作(SELECT、INSERT、UPDATE、DELETE)
  11. !在DDL用户下!将自定义架构中的默认权限更改为 DML 角色

看起来像:

我的脚本:

01-init.sql

CREATE DATABASE mysuperdb;

REVOKE ALL ON DATABASE mysuperdb FROM PUBLIC;

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

CREATE ROLE ddl_custom_role WITH ENCRYPTED PASSWORD 'PWDPWD';

GRANT
    CONNECT
    ON DATABASE mysuperdb TO ddl_custom_role;

GRANT
    TEMPORARY
    ON DATABASE mysuperdb TO ddl_custom_role;

CREATE ROLE dml_custom_role WITH ENCRYPTED PASSWORD 'PWDPWD';

GRANT
    CONNECT
    ON DATABASE mysuperdb TO dml_custom_role;

GRANT
    TEMPORARY
    ON DATABASE mysuperdb TO dml_custom_role;
Run Code Online (Sandbox Code Playgroud)

02-init.sql

REVOKE CREATE ON SCHEMA public FROM PUBLIC;
CREATE SCHEMA IF NOT EXISTS mysuperschema;
CREATE USER flywayuser WITH ENCRYPTED PASSWORD 'PWDPWD';
CREATE USER appuser WITH ENCRYPTED PASSWORD 'PWDPWD';
GRANT
    USAGE,
    CREATE
    ON SCHEMA mysuperschema TO ddl_custom_role;
GRANT
    USAGE
    ON SCHEMA mysuperschema TO dml_custom_role;
GRANT
    ALL
    ON ALL SEQUENCES mysuperschema TO ddl_custom_role;
GRANT
    USAGE,
    SELECT
    ON ALL SEQUENCES mysuperschema TO dml_custom_role;
GRANT ddl_custom_role TO flywayuser;
GRANT dml_custom_role TO appuser;
Run Code Online (Sandbox Code Playgroud)

03-init.sql

ALTER DEFAULT PRIVILEGES IN SCHEMA mysuperschema
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dml_custom_role;
Run Code Online (Sandbox Code Playgroud)

运行顺序(注意在哪个用户下运行脚本!):

  1. 在 DB postgres 上的用户 postgres 下:

    psql -U postgres -d postgres -a -f 01-init.sql

  2. 在 DB MYSUPERDB 上的用户 postgres 下:

    psql -U postgres -d mysuperdb -a -f 02-init.sql

  3. 在 DB MYSUPERDB 上的用户 FLYWAYUSER 下:

    psql -U Flywayuser -d mysuperdb -a -f 03-init.sql

因此,您有一个用于迁移的用户(flywayuser),它可以创建、更改、删​​除表,而另一用户(appuser)只能访问创建flywayuser的表的SELECT、INSERT、DELETE、UPDATE

  • 感谢分享!我建议避免为“dml_custom_role”和“ddl_custom_role”设置密码,因为这实际上会创建用户。 (2认同)

Pol*_*k-Z 1

最好让事情保持简单。如果您的两层设置适合您,我建议保留它,而不是在为数据库所有权创建附加角色时引入额外的管理开销。如果您需要添加更多不同级别的权限,您可能会重新考虑。