Postgres角色最佳实践实施


21

民间,

我可以借助您的帮助使我的Postgres用户访问控制设计更好,并与最佳实践保持一致。我正在帮助推出一个小型生产Postgres服务器,但我不是数据库管理员,所以我知道足够危险。

一台服务器安装了Postgres v9.2。此安装托管多个数据库,每个数据库完全服务于不同的“客户”。换句话说,customer1不会,不应使用database2,依此类推。在正常操作期间,每个数据库都由一个匹配的CakePHP实例进行访问,这些实例均与Postgres位于同一服务器上。尽管可能会对这种部署进行优化,但我对Psql角色最感兴趣。

根据我的读物,似乎三种类型的角色是有意义的:

  • 具有非默认密码的超级用户postgres
  • 不具有用于日常维护,数据库创建,备份和还原的超级用户特权的管理员角色。应该能够对所有客户数据库执行任何操作。
  • 仅具有在各自数据库中进行CRUD的能力的用户角色。如果清理实现,则可以容忍他们自己的DB拥有更多权限。

实施该设计使我信心不足。数据库与表的所有权以及谁应该继承谁的所有权有些混乱。以下是我的数据库和用户。是否有足够的信息来评估实施?

     Role name |                   Attributes                   |     Member of     
    -----------+------------------------------------------------+-------------------
     admin     | Create role, Create DB                         | {user1, user2}
     postgres  | Superuser, Create role, Create DB              | {}
     user1     |                                                | {}
     user2     |                                                | {}

    postgres=# \l
                                 List of databases
       Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
    -----------+----------+----------+---------+-------+-----------------------
     admin     | postgres | UTF8     | en_US   | en_US | =Tc/postgres         +
               |          |          |         |       | postgres=CTc/postgres+
               |          |          |         |       | admin=CTc/postgres
     postgres  | postgres | UTF8     | en_US   | en_US | 
     template0 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US   | en_US | =c/postgres          +
               |          |          |         |       | postgres=CTc/postgres
     user1     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user1=CTc/admin
     user2     | admin    | UTF8     | en_US   | en_US | =Tc/admin            +
               |          |          |         |       | admin=CTc/admin      +
               |          |          |         |       | user2=CTc/admin

为了避免明显的外部连接和密码,pg_hba.conf是这样的:

local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

1
以我的经验,最好的分离方式还带来了很多其他优点,那就是为每个客户运行单独的PostGreSQL群集(例如服务)。这就是我们当前在大型生产环境中正在做的事情,除非数据库的数量变得很大并且每个数据库都非常小,否则我不会做任何不同的事情。当然,应用程序还需要知道如何为每个租户(客户)连接到不同的数据源。
FlorinAsăvoaie15年

在@FlorinAsăvoaie旁边的话。每个数据库都不应该有自己的所有者用户和查询用户吗?这样可以更轻松地将某些用户置于密码库中以进行维护。
hspaans 2015年

Answers:


5

我知道这是一个古老的问题,但是即使现在我仍要尝试回答,因为我必须对此进行一些研究。

您尝试执行的操作在数据库级别称为多租户。这可以通过两种方式实现:

  1. 在单个数据库集群中,OP的描述方式有点类似,但是,我个人的选择是:

    • postgres用户使用对等身份验证,并且不允许使用密码连接。我认为MD5身份验证是一种不良做法。如果您在数据库一致性或此类问题上遇到任何麻烦,如果让postgres使用对等身份验证,您仍然可以登录。
    • 每个客户都应该获得自己的架构而不是数据库。原因有很多:
      • 拥有整个数据库将授予很多特权。
      • 仅拥有特定的表会给开发人员带来麻烦,并且总是需要请管理员添加权限和内容。
      • 这样,在正常设置中,每个人都可以访问在其架构内创建事物的权限,包括表,视图,触发器等。
      • 除用户名外,所有其他人都使用相同的连接字符串。在postgres中,默认情况下,如果您有一个使用用户名的架构,则该架构将自动出现在search_path中。
    • 作为安全措施,我会选择不具有能够访问每个架构的管理员用户。您应该通过使用自己的用户转储每个模式或使用PostgreSQL的PITR技术来进行备份。您仍然需要使用postgres用户来创建新的架构,我将使用sudo规则和一个脚本。
    • 许多安全性良好的做法建议删除默认架构,这样就可以了。
    • 如果每个客户的数据库很小并且您拥有大量客户,则此解决方案非常适合。
    • 如果您的应用程序处理多租户,则可以为所有客户使用单个连接池。当然,这消除了上面的许多安全性增强功能,但可能会带来性能上的好处,特别是当您有大量客户时(如果您拥有500-1000个单独的数据源,并且使用连接池,那将是非常压倒性的)。
  2. 每个客户都有自己的数据库集群。这是我的首选解决方案,尤其是因为我通常使用每个客户都有大型数据库的应用程序。

    • 这带来了很好的数据分离。您可以为每个客户使用单独的存储卷,分配CPU和内存限制(使用docker?)。
    • 每个客户在他们的实例中真正需要的灵活性都很高。它们可以相似或具有不同的特征。
    • 非常容易在两个方向上缩放(向上和向外)。
    • 我还使用了单独的虚拟IP,其中每个群集都侦听连接,从而可以向外扩展以不需要重新配置数据源。
    • PITR备份是针对每个客户的,因此与按方案的多租户相比,还原单个客户将更加容易。
    • 在复杂的设置中,每个客户可能需要多个数据库,架构,用户和角色等。因此,在这种情况下,这是一种更好的解决方案。

您也可以结合使用上述内容,并将pgBouncer用作路由器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.