我可以使用您的帮助使我的Postgres用户访问控制设计更好,更符合最佳实践.我正在帮助推出一个小型的Postgres服务器,但我不是数据库管理员,所以我知道这很危险.
有一台服务器安装了Postgres v9.2.此安装包含多个数据库,每个数据库完全服务于不同的“客户”.换句话说,customer1不会,不应该使用database2,依此类推.在正常操作期间,数据库由匹配的CakePHP实例访问,所有实例都与Postgres位于同一服务器上.虽然可能有可能对此部署进行优化,但我最感兴趣的是Psql角色.
根据我的阅读,似乎有三种类型的角色是有意义的:
>超级用户postgres与非默认密码
>没有超级用户权限的管理员角色,用于例行维护,数据库创建,备份,还原.应该能够对所有客户数据库做任何事情.
>用户角色,只能在各自的数据库中使用CRUD.如果它清理实现,则可以容忍对自己的DB的更多权利.
实现这种设计是我不太自信的地方. 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
您要做的是在数据库级别称为多租户.这可以通过两种方式实现:
>在单个数据库集群中,有些OP所描述的,但是,我个人的选择是:
> postgres用户使用对等身份验证,不允许使用密码连接.在我看来,MD5身份验证是一种不好的做法.如果您遇到任何与数据库一致性或此类问题的麻烦,如果您让postgres使用peer auth,您仍然可以登录.
>每个客户都应该获得自己的架构,而不是数据库.这有多种原因:
>拥有整个数据库会授予很多权限.
>只拥有特定的表会给开发人员带来问题,并且总是要求管理员添加权限和内容.
>因此,在正常设置中,每个人都可以访问其模式中的内容,包括表,视图,触发器等.
>除用户名外,所有连接字符串都使用相同的连接字符串.在postgres中,默认情况下,如果您的模式具有用户名,则它会自动出现在您的search_path中.
>作为安全措施,我会选择不具备能够访问每个架构的管理员用户.您应该通过使用自己的用户转储每个模式或使用Postgresql的PITR技术来进行备份.你仍然需要使用postgres用户来创建新的模式,我会选择sudo规则和脚本.
>许多安全性良好实践建议删除默认模式 – 我们去了.
>如果每个客户的数据库很小并且您有大量客户,则此解决方案非常适合.
>如果您的应用程序处理多租户,它可以为所有客户使用单个连接池.当然,这消除了上面的许多安全增强功能,但可以带来性能优势,特别是当您拥有大量客户时(如果您有500-1000个独立的数据源,并且使用连接池,则会非常压倒性).
>每个客户都有自己的数据库集群.这是我首选的解决方案,特别是因为我通常使用每个客户都有大数据库的应用程序.
>这个带来非常好的数据分离.您可以为每个客户使用单独的存储卷,分配cpu和内存限制(使用docker?).
>在每个客户的实例中需要的灵活性非常好.它们可以是相似的,也可以具有不同的特征.
>非常容易在两个方向(向上和向外)进行缩放.
>我还使用单独的虚拟IP,其中每个群集都侦听连接,使得横向扩展不需要重新配置数据源.
> PITR备份是针对每个客户的,因此与每个架构的多租户相比,恢复单个客户将更容易.
>在复杂的设置中,每个客户可能需要多个数据库,模式,用户和角色等,因此在这些情况下这是一种更好的解决方案.
您也可以使用上述的组合并使用pgBouncer作为路由器.