您可以通过手动编辑文件或调用命令来设置Postgres 的各种配置参数。postgresql.conf
ALTER SYSTEM
这些配置设置之一是listen_addresses
. 引用文档:
指定服务器用于侦听来自客户端应用程序的连接的 TCP/IP 地址。该值采用逗号分隔的主机名和/或数字 IP 地址列表的形式。特殊条目 * 对应于所有可用的 IP 接口。条目 0.0.0.0 允许监听所有 IPv4 地址, :: 允许监听所有 IPv6 地址。如果列表为空,则服务器根本不会侦听任何 IP 接口,在这种情况下,只能使用 Unix 域套接字连接到它。默认值为 localhost,它只允许建立本地 TCP/IP “环回”连接。虽然客户端身份验证(第 20 章)允许对谁可以访问服务器进行细粒度控制,但 listen_addresses 控制哪些接口接受连接尝试,这可以帮助防止在不安全的网络接口上重复的恶意连接请求。此参数只能在服务器启动时设置。
➥ 这是否意味着listen_addresses
理论上停止了预认证攻击?
Postgres 服务器和传入连接之间是否存在任何可能导致漏洞利用的连接?还是会在没有任何参与的情况下阻止被禁止的传入连接?
当然,理想情况下,主机操作系统上的防火墙也将到位,以阻止不需要的传入连接。但是,出于本问题的目的,让我们忽略防火墙。
listen_addresses
在 postgres 看到它们之前过滤连接是的。如果 PostgreSQL 的 postmaster 没有监听给定的接口(由其本地地址标识),则没有远程主机可以通过该接口连接到它。操作系统会报告 TCP 端口已关闭,并向连接主机发送 TCP RST;PostgreSQL 代码永远无法到达,因此无法利用 PostgreSQL 错误,即使是预授权错误。1 .
listen_addresses
阻止预授权漏洞No.
listen_addresses
在操作系统级别配置侦听 TCP 套接字,仅将其绑定到指定的网络接口2。它过滤远程主机指定的连接目标地址。操作系统根本不会告诉 PostgreSQL 与其他接口的连接。请注意,同样的情况并非如此
pg_hba.conf
。pg_hba.conf
控制远程主机源地址过滤和身份验证配置。PostgreSQL postmaster确实会处理任何进入监听地址的连接,然后被pg_hba.conf
配置拒绝。您可以通过配置操作系统防火墙规则在 PostgreSQL 看到连接之前进行基于发件人地址的过滤。这些将通过阻止连接到达 PostgreSQL 来防止 PostgreSQL 预授权攻击。
因此,如果您知道只有网络 111.1.0.0/16 中的主机有任何业务连接到您的 PostgreSQL,那么相应地配置防火墙规则是个好主意。您应该设置
pg_hba.conf
为后备,但防火墙规则应该阻止任何人甚至试图连接到 postgres 本身。了解身份验证流程
要连接到 postgres,您必须通过一系列“门”。忽略此解释的 UNIX 套接字,我们有:
listen_addresses
- postgres 必须在接口上侦听,否则操作系统将 TCP 端口视为关闭/etc/hosts.allow
和/etc/hosts.deny
) 都必须允许连接。(假设它们在您的操作系统上受支持并且 postgres 被编译以使用它们)pg_hba.conf
host
,hostssl
or规则hostnossl
pg_hba.conf
规则不能指定reject
LOGIN
在 PostgreSQL 目录中有选项CONNECT
对请求的数据库具有权限。(默认情况下,public
所有用户所属的角色都具有CONNECT
权限,但您可以REVOKE
这样做,并且GRANT
仅对特定用户或角色/组具有权限)。如果一个连接在早期阶段被阻塞,它永远不会与后面的阶段交互。我还没有检查 dbname 与用户名权限检查的确切顺序,但其余的都是正确的。
我在这里忽略
pg_ident.conf
了用户名映射、客户端证书 DN 映射、SSPI/GSSAPI 和低级身份验证方法等细节。现在,如果您使用 UNIX 套接字(
unix_socket_directories
,以及libpq
host
作为路径或完全省略的地址),PostgreSQL 阶段是相同的,除了pg_hba.conf
匹配不检查源地址并查找local
行而不是host
,hostssl
或hostnossl
行。peer
支持 auth 模式以要求 unix 用户名与 postgres 用户名匹配。手册中的详细信息。将 PostgreSQL 暴露在 Internet 上
让我注意到 PostgreSQL 的 pre-auth 攻击并非完全闻所未闻,而是很少见。直接在 Internet 上公开 PostgreSQL 是相当常规的。
您应该使用
hostssl
inpg_hba.conf
来强制 SSL 连接以保护身份验证交换并使随意扫描更加困难。并且您应该采取与任何其他 Internet 公开服务相同的保护措施:使用 fail2ban 或类似的,使用 IDS,监控日志,并使用防火墙规则排除任何您知道没有业务连接的东西。但是,如果您不需要将 PostgreSQL 公开到 Internet,请不要这样做。特别是,如果您只需要环回连接,请将 PostgreSQL 绑定到环回地址
127.0.0.1
和::1
. 或者更好的是,使用unix sockets。也可以看看
listen_addresses
pg_hba.conf
1攻击者仍然可以利用网络堆栈中的操作系统漏洞。或者(非常不可能)他们可能能够使用诸如源地址欺骗之类的技巧来欺骗有缺陷的操作系统,让其将初始数据包发送到 PostgreSQL,即使它绑定到不同的接口也是如此。任何现代的、合理配置的操作系统都会阻止这种情况发生。
2在内部,每个
listen_addresses
条目都用于创建一个单独的侦听 TCP 套接字。对于类 UNIX 操作系统,它被传递给bind(...)
每个套接字上的调用。请参见postmaster.c
第 1012 行if (ListenAddresses)
,以及第 532 行附近的StreamServerPort
适配器。src/backend/libpq/pqcomm.c