17.9. 用 SSL 进行安全的 TCP/IP 连接

PostgreSQL有一个内建的通过SSL进行加密的客户端/服务器端的通讯, 这样可以增加安全性。这个特性要求在客户端和服务器端都安装OpenSSL 并且在编译PostgreSQL的时候打开(参阅Chapter 15)。

当编译了SSL进去以后,可以通过将postgresql.conf中的ssl 设置为on打开PostgreSQL服务器的SSL支持。 服务器将在同一个 TCP 端口上同时监听标准的和 SSL 的连接, 并且将与任何正在连接的客户端进行协商,协商是否使用SSL 。缺省时, 这是根据客户端的选项而定的。参阅Section 19.1 获取如何强制服务器端只使用SSL进行某些或者全部连接的信息。

PostgreSQL读取系统范围的OpenSSL 配置文件。缺省的,这个文件名为openssl.cnf,位于openssl version -d 报告的目录中。这个缺省可以通过设置环境变量OPENSSL_CONF为所需配置文件的名称重写。

OpenSSL支持多种不同强度的密码和认证算法。 当一列密码可以在OpenSSL配置文件中指定时, 可以通过修改postgresql.conf中的ssl_ciphers, 指定数据库服务器专用的密码。

Note: 使用NULL-SHANULL-MD5可能有身份验证开销而没有加密开销。 不过,中间人能够读取和通过客户端和服务器的通信。此外,加密开销相比身份认证的开销是极小的。 有这些原因建议不使用NULL加密。

要在SSL模式中启动服务器,必须包含包含服务器证书和私钥的文件。缺省的, 这些文件分别命名为server.crtserver.key,存在于服务器的数据目录里, 但是其他名字和位置可以用配置参数ssl_cert_filessl_key_file 指定。在Unix系统,server.key的权限禁止任何world或group访问; 通过命令chmod 0600 server.key来做。如果私钥受密码保护,服务器将会提示输入密码, 将会等到输入后启动。

在有些情况下,服务器证书可能由一个"中间"认证授权签名,而不是直接由受信任的客户端。 若要使用这样的证书,请追加授权签名证书到server.crt文件,然后其父颁发机构的证书, 然后直到一个客户端信任的"根"授权。server.crt包含多个证书, 在任何情况下都应包括根证书。

17.9.1. 使用客户端证书

如果需要客户端提供受信任的证书,把认证中心(CAs)的证书放在你信任的在数据目录下的 root.crt文件里,并且设置postgresql.conf里的参数 ssl_ca_fileroot.crt,设置pg_hba.conf 里适当的hostssl行参数clientcert为1。 然后将在SSL连接启动时从客户端请求该证书。(Section 31.18描述了如何在客户端安装证书。) 服务器将验证客户端的证书是由受信任的认证中心之一签发的。如果参数ssl_crl_file 也设置了,那么证书撤销列表(CRL)项也要检查。 (参阅http://h71000.www7.hp.com/DOC/83final/BA554_90007/ch04s02.html 图标显示SSL证书的使用。)

pg_hba.conf文件中clientcert选项对于所有的认证方法都可用, 但仅适用hostssl指定的行。当clientcert没有指定或设置为0, 服务器将仍然对其CA列表验证提供的客户端证书,如果配置了,它将不会坚持提交客户端证书。

请注意root.crt列出顶级的CA,这些CA被认为是受签约客户端证书信任的。 原则上不需要列出标记服务器证书的CA,尽管在大多数情况下,客户端证书也将信任的该CA。

如果你设置客户端证书,你可能希望用cert认证方法,因此使证书控制用户身份验证, 以及提供连接安全。参阅Section 19.3.10获取详细信息。

17.9.2. SSL服务器文件的使用

Table 17-2概述了与在服务器上设置SSL相关的文件。(显示的文件名字是默认的或典型的名字。 本地配置的名字可能会不同。)

Table 17-2. SSL服务器文件的使用

文件 内容 作用
ssl_cert_file ($PGDATA/server.crt) 服务器证书 发送到客户端标识服务器的身份
ssl_key_file ($PGDATA/server.key) 服务器私钥 证明服务器证书是由所有者发送,并不表示证书所有者是可信的
ssl_ca_file ($PGDATA/root.crt) 受信任的认证中心 检查该客户端证书由受信任的认证中心签署
ssl_crl_file ($PGDATA/root.crl) 由认证中心吊销的证书 客户端证书不能在此列表中

文件server.keyserver.crtroot.crtroot.crl(或他们配置的供选择的名字)仅在服务器启动时检查; 如果你修改了它们,那么必须重启服务器才能生效。

17.9.3. 创建自签名的证书

要为服务器创建一个快速自认证的证书,使用下面的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.crt

将证书变成自签名的证书,并且复制密钥和证书到服务器能找到的地方。最后执行操作:

chmod og-rwx server.key

因为如果其权限比这更高,服务器将拒绝该文件。更多关于怎样创建服务器私钥和证书的细节, 请参考OpenSSL文档。

你可以用一个自认证的证书进行测试,但是在生产环境中应该使用一个由认证中心(CA, 全球的CA或者区域的CA都可以)签发的证书, 这样客户端才能够识别服务器的身份。如果所有客户都是本地组织的,建议使用本地CA。