了解PgBouler中的用户管理

2020-07-08 02:03:50

PgBouner是一种流行的PostgreSQL连接代理和池。当PgBouner向客户端应用程序提供PostgreSQL协议接口时,它还处理客户端身份验证。为此,它维护自己的用户和密码目录。这有时会引起混淆,所以在这篇博客文章中,我想试着描述一下它是如何工作的。

在PgBouner中可以通过多种方式定义用户和密码。让我们从最简单的开始。您可以在文本文件中定义用户和密码。此文件的位置由配置参数auth_file设置。它通常被命名为userlist.txt,但是您当然可以使用任何名称。此文件的格式如下:

该文件基本上实现了与PostgreSQL后端中的系统目录pg_authid(以前的pg_dow(以前的pg_user))相同的用途。事实上,PostgreSQL过去常常将自己的用户数据库保存在数据目录中的一个类似文件中,此选项的初衷是您可以将PgBouner直接指向该文件,以便在PostgreSQL和PgBouner之间直接共享用户。但这不再起作用,因为PostgreSQL不再以这种方式工作,所以无论出于何种目的,这现在都是一个文本配置文件。保持此文件与PostgreSQL中定义的用户同步的一种方法是查询pg_authid并以适当的格式将结果转储到此文件中。PgBouler附带的脚本mkauth.py可以用于此目的。

此文件中的密码可能是纯文本密码,也可能是使用MD5或SCRAM加密的密码,具体取决于要使用的身份验证方法。此处不介绍这些身份验证方法的详细信息。也就是说,如果您想要存储加密的密码,那么决定一种以自动或脚本方式维护此信息而不是手动编辑它的方法可能会很有用。

请注意,应限制此文件的访问权限,通常为0600模式。

另一种定义用户的方式是在需要时让PgBouner直接查询PostgreSQL后端。这是由配置参数auth_user设置的,该参数可以全局设置,也可以按数据库设置。设置后,PgBouner使用该用户连接到PostgreSQL后端,并运行由设置auth_query定义的查询来查找用户和密码。如果auth_user本身需要该连接的密码,则需要在userlist.txt中设置密码。但是您也可以设置auth_user不需要密码,也许可以使用TLS证书。(有关使用PgBouler设置TLS的更多信息,请参阅此网络研讨会。)。

这意味着auth_user需要是PostgreSQL端的超级用户。例如,您可以这样做。

但是,最好在后端编写安全定义器函数,该函数可以查找用户,并且只能由特定用户调用。这篇博客文章对如何正确设置这一点进行了广泛的讨论。

还要注意,使用auth_user/auth_query可以为每个数据库提供不同的用户和密码,而auth_file则为整个PgBouner实例定义用户。

最后,如果通过设置auth_type=pam来使用PAM,则系统的工作方式会有所不同。AUTH_FILE和AUTH_USER被忽略。所有用户和密码信息都来自PAM系统。

请注意,在每种情况下,PgBouner维护的用户和密码信息都用于验证从客户端传入的连接以及为传出到服务器的连接提供身份验证信息。这是一个基本的设计决策:就身份验证而言,PgBouner希望成为或多或少透明的连接代理。如果您希望使用不同于PostgreSQL后端的用户名或密码登录到PgBouner,则设置和维护会更加复杂。

这在内部称为“强制用户”。此用户仅存在于到后端服务器的传出连接,否则在PgBouner用户数据库中并不真正存在。

您使用其中哪一个取决于关于整个设置的各种考虑因素。如果您的PostgreSQL服务器本身使用PAM或LDAP进行身份验证,那么在PgBouner中使用PAM也是有意义的。(PgBouner不支持本机LDAP身份验证方法,但可以通过PAM使用LDAP。)。另外,auth_user/auth_query更优雅,从长远来看需要的维护更少,但它最初需要更仔细的设置。AUTH_FILE是一种更传统的设置,如果用户和密码更改很多,则需要更多维护,但它更简单,可能更健壮,也更不令人惊讶。