postgresql - SET SESSION AUTHORIZATION 多用户 mod-perl2 连接缓存的安全设计

标签 postgresql database-connection dbi mod-perl2 apache-dbi

我有一个 mod_perl2.0.4/Apache2.2 网络应用程序在 CentOS 6.4 和 PostgreSQL 9.0 上运行。

直到最近,我还有this setup : Apache::DBI 和 DBI->connect_cached 用于所有连接,开始给出 FATAL: sorry, too many clients already即使在我是唯一用户的开发区域。

为了调试它,我删除了所有对 Apache::DBI 的引用,升级到最新的 DBI,并将所有出现的 connect_cached 替换为普通的 DBI->connect。在我看来,现在建立的连接少了一些,然后就离开了<IDLE> .但是,我意识到我并没有在我的所有语句句柄上调用 disconnect(),因为它听起来像在 Apache::DBI 下它不会有什么不同。

我的连接目前都以同一用户身份连接,然后通过 SET SESSION AUTHORIZATION 根据它是哪个用户降低它们的权限。我这样做是因为其他一些使用数据库的应用程序允许密码登录,这可以将凭据直接传递给数据库,但这个特定的网络应用程序使用荣誉系统登录屏幕,您只需单击您的名字即可登录。因此,它已为 future 的安全做好准备,但目前却很方便。此外,历史记录的数据库触发器等依赖于正确设置 session 用户以跟踪谁做了什么。

因为我担心数据库句柄被错误的 session 用户重用,所以我通过了 { private_user_login => $login_role_name, PrintError => 0, RaiseError => 1, AutoCommit => 1}到 connect_cached 以区分用户的每个连接。但是因为我总是在连接后立即设置 session 授权,我想所有的private_user_login hash 所做的是,对于给定的 Apache 进程,如果最终每个用户设法随机使用给定的 Apache 进程,则可能至少有与用户一样多的数据库连接创建和闲置。同时,因为我没有断开任何 handle ,它们最终会用完。

我的问题是,取出 private_user_login 是否安全?使所有连接句柄看起来相同,减少保持打开的连接数,或者连接句柄是否可以在脚本中间(设置 session 用户后)由不同的人重新使用用户,从而造成竞争条件?此外,尽管 Apache::DBI 的文档说我不需要删除 disconnect()调用,我是否还应该在每个脚本的末尾进行这样的调用,以便 Apache::DBI 可以决定是否断开连接?

换句话说,如果没有我的私有(private)连接变量,当下一个 Apache::DBI->connect() 重用现有连接时,SET SESSION AUTHORIZATION 的效果会持续吗?如果是这样,当一个请求当前正在执行但当前未使用数据库句柄时,是否有可能连接被另一个请求重新使用?

最佳答案

如果可以的话,我推荐一种稍微不同的方法。

在 Apache 中保持简单。如果这是最容易确保安全可靠的方法,则对每个用户使用私有(private) session 。

然后在 PostgreSQL 服务器和您的 Apache 实例之间放置一个 PgBouncer。将其设置为事务池模式。它会愉快地多路复用您的连接,并且会在用户之间切换连接时负责调用 DISCARD ALL。

我认为您仍然可以对通过 PgBouncer 建立的连接使用 SET SESSION AUTHORIZATION。

关于postgresql - SET SESSION AUTHORIZATION 多用户 mod-perl2 连接缓存的安全设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20547480/

相关文章:

node.js - Sequelize 不加入关系

r - 我可以使用 R 中的 DBI 库将一个 SQLite 数据库附加到另一个数据库吗?

mysql - 使用 Perl DBI->MySQL 时如何检查空集

sql - 如何通过索引优化查询 PostgreSQL

sql - 根据连接表的另一列对一列进行双重计数

sql - 检查两个值中哪一个先出现在表中的每条记录之后

MySQL COM_EXECUTE_STMT 失败并出现错误,但该错误没有意义

C#模拟器 'To Many Connections'

java - 本地和远程连接池,Java DBCP

mysql - Perl DBI 的 'SELECT COUNT(*)' 返回什么?