postgresql支持的认证方法非常多,除了自身的密码认证以外,还支持很多其他认证服务。
详见
<a href="https://www.postgresql.org/docs/9.6/static/auth-methods.html">https://www.postgresql.org/docs/9.6/static/auth-methods.html</a>
本文主要给大家讲一下ident认证和peer认证。
这两种认证方法的目的是获取客户端连接数据库的操作系统用户,检查map中是否存在,判断是否允许连接数据库。
ident 认证,客户端和数据库建立tcp会话后(假设会话的连接信息是client_ip:12345 <-> db_ip:5432),数据库通过ident协议询问客户端所在ip地址的ident server (默认是113监听端口),询问内容:使用client_ip:12345端口连接db_ip:5432的操作系统用户是谁?
协议可以参考一下rfc 文档。
如图:

peer认证,目的和ident认证一样,都是要拿到客户端的操作系统用户名,只不过peer对应的是unix socket连接(客户端和数据库在同一个操作系统中),所以是通过系统调用来获取客户端的用户名,系统调用是getpeereid().
在获取到客户端的os用户名之后,postgresql会通过pg_hba.conf中配置的map名与pg_ident.conf中配置的映射关系,以及客户端提供的数据库用户名,判断是否允许登陆数据库。
如图
我这里举一个peer认证的例子
这个配置的含义:
当客户端使用unix socket连接数据库时,使用ident认证。 当客户端的os用户是digoal时,允许它以数据库用户postgres连接数据库。
当连接的数据库用户不在map中时,报错。
pg_ident.conf还支持规则表达式,具体用法见
<a href="https://www.postgresql.org/docs/9.6/static/auth-username-maps.html">https://www.postgresql.org/docs/9.6/static/auth-username-maps.html</a>
<a href="https://www.postgresql.org/docs/9.6/static/functions-matching.html#posix-syntax-details">https://www.postgresql.org/docs/9.6/static/functions-matching.html#posix-syntax-details</a>
ident的方法略复杂,需要在客户端部署ident server,可参考以下文档进行配置
<a href="https://wiki.archlinux.org/index.php/identd_setup">https://wiki.archlinux.org/index.php/identd_setup</a>
ident针对tcp会话,即通过tcp连接数据库时。
peer针对unix socket会话,即通过unix socket 连接数据库时。
如果你的主机是数据库和其他业务共用,或者你不太相信你的os环境的话,如何加固你的数据库呢?
假设root用户是可信任的,启动数据库的digoal用户是可信任的,你可以这样加固。
禁止所有的trust认证,同时对root和digoal用户,使用peer认证方法。
其他用户要连,对不起,不允许,请提供密码。
(这种加固,仅仅针对不能修改pg_hba.conf的用户,所以说root和启动数据库的用户必须是可信任的)
例子
.1. 使用某个非启动数据库的普通用户通过unix socket连接并监控数据库。
root 超级用户
digoal 启动数据库的用户
nobody 某监控用户(没有login shell,不允许登陆)
配置
监控脚本示例
以nobody用户运行监控脚本
<a href="https://www.postgresql.org/docs/9.6/static/auth-methods.html#auth-ident">https://www.postgresql.org/docs/9.6/static/auth-methods.html#auth-ident</a>