PostgreSQL是应用和影响仅次于Mysql的开源数据库,主要运行在Unix类操作系统,本文以红帽企业版 5.5  为例,介绍PostgreSQL安全配置的方法。

一、 PostgreSQL 安全漏洞
PostgreSQL与其他商业和开源数据库比起来,它所报道的安全漏洞bug已经算是少的了。Common Vulnerabilities and Exposures数据库(http://www.cve.mitre.org/cgi-bin/cvekey.cgi?keyword=postgresql)给出了PostgreSQL及其附属应用程序的78个bug,这远比其他DBMS的数量少。最新的PostgreSQL bug是CVE-2011-1548修正版本发布的。更新内容包括两处处有一定影响的Bug,一个是8.1版本中的autovacuum(自动整理数据库功能),另一个是8.3版本中的GiST索引会导致的数据丢失的可能性,这两个版本的用户应尽快升级。这两个Bug在新发布的版本中均已修复。 对其他版本的更新,用户不必进行数据的导出和导入即可进行新版本的更新,仅需将正在运行的PostgreSQL停止,然后直接更新PostgreSQL的二进制文件即可。用户直接进行多个小版本号的升级时,需对照检查一下软件的发布声明、升级步骤等内容。
目前已知的PostgreSQL漏洞数量少有许多因素。首先PostgreSQL代码的总体质量很高,在产品多年的开发过程中,安全做得比较完整。也可以这样认为,PostgreSQL与其他DBMS相比,它的攻击表面更小一些。证据就在程序的安装过程中,默认情况下,它会防止网络访问、拒绝允许具有特权的用户环境下的操作;当然它也会定期发布bug修复。修复信息在pgsql-announce邮件列表中宣布。它存档于:http://archives.postgresql.org/pgsql-announce/ 上。其他值得监测的列表包括pgsql-bugs、pgsql-hackers和pgsql-patches(也存档在前面的URL上)。安全漏洞已经在这些列表上公开讨论了。记住这些就可以在补丁发布之前采取需要的对策。

二、黑客如何查询PostgreSQL目标
在默认情况下,PostgreSQL并不为网络访问进行配置,所以第一步值得考虑这个问题,即如何确定它当前给出的本地系统访问。这是通过检查pstmaster或postgres进程表来实现的。在Unix系统上,PostgreSQL本地套接字通常都位于/tmp目录下,并且被命名为s.PGSQL.5432。它可以通过“netstat –l”命令列出正在监听的TCP和Unix套接字来确定。许多部署方案需要数据库远程可用。PostgreSQL通常监听TCP的5432端口。因此,攻击者可能会在网络上对各系统进行一次简单的扫描,用来响应端口5432上的TCP SYN数据包,以确定PostgreSQL服务器的存在(下面是使用nmap的例子):
$ nmap -sS 10.0.0.0/24 -p 5432
如果postmaster正在监听,那么管理员可能会选择改变端口,这也许是降低攻击者攻击性的一种迷惑方法。但是,对于检测一个数据包发送者来说,它很简单。PostgreSQL客户机(如psql)就会被用来尝试连接。如果连接源端的用户名、数据库、SSL连接选项和主机已经有pg_hba.conf文件已有记载,那么攻击者就不大可能在初始化检测器上去匹配一个有效的记录。因此,预期的响应就类似于如下所示:
$ psql -h 10.0.0.1 -p 2345 –d test –U test
psql: FATAL:  no pg_hba.conf entry for host "10.0.0.1", user "test",
database "test", SSL off
初始PostgreSQL的协议交换开始于客户机发送一个startup消息给ostmaster,这通常会导致一个ErrorResponse消息(正如以上用友好的方式列出的那样),这个消息是一个身份验证类型的消息,或者一个AuthenticationOK消息。有许多工具可以基于对各种输入进行响应来标识应用程序。一个非常流行的工具amap错误地将PostgreSQL标识为MySQL。然而,如果amap用一b选项切换运行,那么将会显示Error Response消息。

三、保护PostgreSQL数据库的安全性策略
1  使pg_hba.conf文件中各条目尽量受到限制。
默认情况下,安装PostgreSQL时禁用网络访问。大多数部署场景需要远程访问。Pg_ hba.conf应该依据下列考虑进行写入:
  指定单独的主机,与网络范围(或者更坏一点的情况,所有主机)形成对比,除非它是使用拒绝规则。
  使用特定的拒绝规则(置于规则列表的顶端),以便防止从某些网络范围向特定数据库进行访问。
  使用增强SSL连接。
  使用指定的用户名和数据库名,来作为另一层访问控制手段。
  不要使用脆弱的身份验证类型,如trust、password或ident等。使用md5而不是直接隐藏。
2  启用SSL并且使用客户机证书。
应该通过pg_hba.conf规则增强SSL。PostgreSQL 有一个内建的通过SSL进行加密的客户端/服务器端的通讯,这样可以增加安全性。这个特性要求在客户端和服务器端都安装 OpenSSL 并且在编译 PostgreSQL 的时候打开。当编译了 SSL 进去以后,可以通过将 postgresql.conf中的 ssl 设置为 on 打开 PostgreSQL 服务器的 SSL 支持。当开始 SSL 模式后,服务器将在数据目录里查找 server.key 和 server.crt 文件,必须分别包含服务器私钥和证书。在打开 SSL 的服务器运行之前必须先正确的设置这些文件。如果私钥用一个口令保护,那么服务器将提示输入口令,并且在口令成功校验之前不会启动。
服务器将在同一个 TCP 端口上同时监听标准的和 SSL 的连接,并且将与任何正在连接的客户端进行协商,协商是否使用 SSL 。缺省时,这是根据客户端的选项而定的。有关创建服务器私钥和证书的细节信息,可以参考 OpenSSL 的文档。你可以用一个自认证的证书进行测试,但是在生产环境中应该使用一个由认证中心(CA,全球的 CA 或者区域的 CA 都可以)签发的证书,这样客户端才能够识别服务器的身份。要创建一份自认证的证书,可以使用下面的 OpenSSL 命令openssl req -new -text -out server.req填充那些 openssl 向你询问的信息。确保把本地主机名当做"Common Name"输入。该程序将生成一把用口令保护的密钥。小于四字符的口令保护是不被接受的。要移去密钥(如果你想自动启动服务器就得这样),运行下面的命令:
$openssl rsa -in privkey.pem -out server.key
$rm privkey.pem
输入旧口令把现有密钥解锁。然后使用命令:
$openssl req -x509 -in server.req -text -key server.key -out server.crtchmod og-rwx server.key
把证书变成自签名的证书,然后把秘钥和证书拷贝到服务器寻找它们的地方。
如果需要验证客户端的证书,那么在数据目录的root.crt里放置你想校验的CA的证书。如果出现这个证书,那么在SSL连接启动的时候就会要求客户端提供客户端的证书,并且这个证书必须是已经由root.crt里面出现的认证之一签发的。如果root.crl存在的话,证书撤销列表(CRL)项也将被检查。
如果没有 root.crt 文件,那么就不需要检查客户端认证。这个模式下,SSL 提供通讯安全但不保证认证。文件 server.key, server.crt, root.crt, root.crl 只是在服务器启动的时候检查;如果你修改了它们,那么必须重启服务器才能生效。
还可以使用Stunnel创建安全隧道。Stunnel是一个能形成SSL包裹的小型应用程序;将它配置成能使用客户机证书的形式,是非常简单的。可以从http://www.stunnel.org/ 下载Stunnel软件包。 上可找到带Stunnel的PostgreSQL的用途说明。
3  尽量运行单用户系统。
  设计PostgreSQI让它运行在单用户系统上
一些公司在有主机的环境中运行它,这种环境中,第三方包含用户账户(甚至管理系统、)。如果有许多在setuid应用程序中报告的特权提升攻击,就应该避免这种情况。一旦怀有恶意的用户能以超级用户身份执行命令,数据库中的数据就会被破坏。超级用户能用任意多种方法对它进行访问——他们会对pg_ hba.conf进行细微的修改,以使自己被所有数据库信任并进行访问,或者他们能复制数据库文件到另一个系统。
  数据库用户名应该与操作系统用户名不同。
如果攻击者能够通过另一个服务的信息泄露来获得操作系统用户名列表,该措施就会降低蛮力攻击的机会。
  如果数据库必须运行在多用户系统上,那么应该设置Linux域套接字,这样就只有指定的用户或组才能被授权访问。
4  其他方面
  检查客户机应用程序是否使用能基于用户输入构造动态查询的“危险”函数
在任何可能的地方,通过使用(1ibpq)PQexecParams()和PqexecPrepaured()来利用参数化查询。如果通过修改应用程序来使用这些函数是行不通的,那么应该用PQescapeString()转义源白用户输入的有问题字符。在用其他语言开发应用程序时,则应该使用等价的安全查询函数。
  禁用所有不必要的服务
这对Linux 和Windows系统都是适用的。在默认情况下 使用许多Linux系统来安装和使能多网络后台程序(FTP、DNS等等)。Windows系统在安装时会使用许多潜在的不安全服务,例如远程注册表服务和计算机浏览器服务。‘
  服务器应该使用安全补丁来保持更新。
系统管理员应该订阅类似于BugTraq的邮件列表以及相关供应商列表。
  数据库环境中应该包含安全措施,用来隔离对持有敏感信息的服务器的访问
应该配置内部和边界防火墙,这样就可以阻止对PostgreSQL端口进行访问,而个人允许规则则允许从应用程序服务器进行访问。防火墙应该防止外部访问,以及限制内部对端口的访问该措施会减轻信息泄漏攻击。
  保护web服务
如果Web服务器或开发系统被攻陷了,那么攻击者可能从源代码的检查过程中获 取数据库证书(如果Web服务器/Web应用程序包含允许源代码泄露的弱点的话,也会有同样的问题)。如果应用程序写在PHP中,搜索对pg_connect()或 odbc_connect()的调用就会揭露出数据库的主机名、数据库名、端口、用户名和口令,或者Data Source Name。
  防范jode工具
如果被攻陷的系统运行了一个连接到PostgreSQL数据库的Java应用程序,那么很可能会使用PostgreSQL JDBC接口。证书可能存储在.properties文件中,或者会难于编码到应用程序中。如果应用程序源代码是可用的,对DriverManager.getConnection0方法的搜索就会揭露出JDBC URL、用户名和口令。如果源代码不  存在,那么运行类文件上的字符串可能会揭露证书,否则代码就能通过Jode(http://jode.sourceforge.net )等工具被部分反向加入源代码中。
  慎用cron运行数据库客户端
Unix /Linux系统通过装置cron,以设定好的间隔去运行psql,这暗示数据库的pg_hba.conf已经被配置成允许来自那个主机/用户名的、或是包含有效证书的.pgpass文件的可信任访问。cron任务可以通过执行crontab —l命令列出来。Psql是基于终端的PostgreSQL客户机,它使用libpq,即PostgreSQL的CAPI。如果连接需要口令并且还没有指定口令,Libpq会试图从.pgpass文件中读取口令。这个文件存储在用户的home目录下PostgreSQL在使用.pgpass文件数据之前会验证它的 权限;如果环境或组能够访问这个文件,那么它就被认定为不安全和可以忽略的(然而,这并不一定意味着.pgpass中的口令不正确)。

文章如转载,请注明转载自:http://www.5iadmin.com/post/908.html