PostgreSQL 连接攻击(类似DDoS)

less than 1 minute read

背景

客户端请求连接数据库后,会提示客户端输入用户密码,如果客户端不输入密码,那么数据库服务端会在一个超时时间后,断开连接。

也就是说,在服务端主动断开连接前,这个连接实际上需要占用一个SLOT,也就是max_connection中的一个。

https://www.postgresql.org/docs/9.6/static/runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SECURITY

authentication_timeout (integer)  
  
Maximum time to complete client authentication, in seconds.   
  
If a would-be client has not completed the authentication protocol in this much time, the server closes the connection.   
  
This prevents hung clients from occupying a connection indefinitely.   
  
The default is one minute (1m). This parameter can only be set in the postgresql.conf file or on the server command line.  

另一个参数是客户端连接超时参数,与攻击没什么关系,我这里只是拿出来给大家了解一下。

https://www.postgresql.org/docs/9.6/static/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT

connect_timeout  
  
Maximum wait for connection, in seconds (write as a decimal integer string).   
  
Zero or not specified means wait indefinitely.   
  
It is not recommended to use a timeout of less than 2 seconds.  

攻击者可以利用这个规则,并发的发起大量连接请求,但是不提供密码,等待服务端的超时,这样可以把max_connection的连接都占用掉。

现象

用户如果连接被占满,其他正常的请求发起的连接会遇到连接不足的报错。

53300	too_many_connections  
  
同时在pg_stat_activity中查询到的count(*)小于实际的max_connection配置,  
因为没有认证成功的连接还不会出现在pg_stat_activity会话中。  

防范措施

1、不要暴露监听端口。

2、如果监听端口一定要暴露,建议使用源IP鉴权,过滤非法IP,规避大部分攻击。

3、配置pg_hba.conf,鉴权IP,DB,USER,规避大部分的攻击。

4、配置用户、DB级连接限制,即使被攻击了,也可以保证一部分连接是可以被使用。除非攻击者知道所有的数据库名、用户名,对其进行攻击。否则就占用不掉所有连接。

相关问题

即使不是DDoS攻击,用户也可能遇到类似的问题。

例如在数据库非常繁忙时,用户请求响应变慢,用户的应用程序堆积了很多请求,这些请求需要新建与数据库的连接,由于本身数据库非常繁忙响应变慢,加上爆炸性的高并发连接请求使得PG服务端的fork操作变慢,返回auth消息包在此之后(所以造成了类似现象)。

因此用户如果遇到这样的诡异问题,pg_stat_activity中显示的连接数比max_connection小,确无法连接数据库(报too_many_connections的错误),那么可以看看是不出现了DDoS攻击或者是数据库繁忙导致。

Flag Counter

digoal’s 大量PostgreSQL文章入口