ssl-tcp.zh.md 11.5 KB
Newer Older
李少辉-开发者's avatar
李少辉-开发者 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
## 19.9. Secure TCP/IP Connections with SSL

[19.9.1. Basic Setup](ssl-tcp.html#SSL-SETUP)

[19.9.2. OpenSSL Configuration](ssl-tcp.html#SSL-OPENSSL-CONFIG)

[19.9.3. Using Client Certificates](ssl-tcp.html#SSL-CLIENT-CERTIFICATES)

[19.9.4. SSL Server File Usage](ssl-tcp.html#SSL-SERVER-FILES)

[19.9.5. Creating Certificates](ssl-tcp.html#SSL-CERTIFICATE-CREATION)

[](<>)

PostgreSQL has native support for using SSL connections to encrypt client/server communications for increased security. This requires that OpenSSL is installed on both client and server systems and that support in PostgreSQL is enabled at build time (see[Chapter 17](installation.html)).

### 19.9.1. Basic Setup

With SSL support compiled in, the PostgreSQL server can be started with SSL enabled by setting the parameter[ssl](runtime-config-connection.html#GUC-SSL)to`on`in`postgresql.conf`. The server will listen for both normal and SSL connections on the same TCP port, and will negotiate with any connecting client on whether to use SSL. By default, this is at the client's option; see[Section 21.1](auth-pg-hba-conf.html)about how to set up the server to require use of SSL for some or all connections.

To start in SSL mode, files containing the server certificate and private key must exist. By default, these files are expected to be named`server.crt`and`server.key`, respectively, in the server's data directory, but other names and locations can be specified using the configuration parameters[ssl_cert\_文件](runtime-config-connection.html#GUC-SSL-CERT-FILE)[ssl\_钥匙\_文件](runtime-config-connection.html#GUC-SSL-KEY-FILE).

在 Unix 系统上,权限`服务器密钥`必须禁止对世界或群组的任何访问;通过命令实现这一点`chmod 0600 server.key`.或者,该文件可以由 root 拥有并具有组读取访问权限(即,`0640`权限)。该设置适用于证书和密钥文件由操作系统管理的安装。然后应该使运行 PostgreSQL 服务器的用户成为有权访问这些证书和密钥文件的组的成员。

如果数据目录允许组读取访问,则证书文件可能需要位于数据目录之外,以符合上述安全要求。通常,启用组访问以允许非特权用户备份数据库,在这种情况下,备份软件将无法读取证书文件并且可能会出错。

如果私钥受密码保护,服务器将提示输入密码并且在输入密码之前不会启动。默认情况下使用密码会禁用在不重新启动服务器的情况下更改服务器的 SSL 配置的功能,但请参阅[ssl\_密码\_命令\_支持\_重新加载](runtime-config-connection.html#GUC-SSL-PASSPHRASE-COMMAND-SUPPORTS-RELOAD).此外,受密码保护的私钥根本无法在 Windows 上使用。

第一张证书在`server.crt`must be the server's certificate because it must match the server's private key. The certificates of “intermediate” certificate authorities can also be appended to the file. Doing this avoids the necessity of storing intermediate certificates on clients, assuming the root and intermediate certificates were created with`v3_ca`extensions. (This sets the certificate's basic constraint of`CA`to`true`.) This allows easier expiration of intermediate certificates.

It is not necessary to add the root certificate to`server.crt`. Instead, clients must have the root certificate of the server's certificate chain.

### 19.9.2. OpenSSL Configuration

PostgreSQL reads the system-wide OpenSSL configuration file. By default, this file is named`openssl.cnf`and is located in the directory reported by`openssl version -d`. This default can be overridden by setting environment variable`OPENSSL_CONF`to the name of the desired configuration file.

OpenSSL supports a wide range of ciphers and authentication algorithms, of varying strength. While a list of ciphers can be specified in the OpenSSL configuration file, you can specify ciphers specifically for use by the database server by modifying[ssl_ciphers](runtime-config-connection.html#GUC-SSL-CIPHERS)in`postgresql.conf`.

### Note

It is possible to have authentication without encryption overhead by using`NULL-SHA`or`NULL-MD5`ciphers. However, a man-in-the-middle could read and pass communications between client and server. Also, encryption overhead is minimal compared to the overhead of authentication. For these reasons NULL ciphers are not recommended.

### 19.9.3. Using Client Certificates

To require the client to supply a trusted certificate, place certificates of the root certificate authorities (CAs) you trust in a file in the data directory, set the parameter[ssl_ca_file](runtime-config-connection.html#GUC-SSL-CA-FILE)in`postgresql.conf`to the new file name, and add the authentication option`clientcert=verify-ca`or`clientcert=verify-full`to the appropriate`hostssl`line(s) in`pg_hba.conf`. A certificate will then be requested from the client during SSL connection startup. (See[Section 34.19](libpq-ssl.html)for a description of how to set up certificates on the client.)

For a`hostssl`entry with`clientcert=verify-ca`,服务器将验证客户端的证书是否由受信任的证书颁发机构之一签名。如果`clientcert=验证完整`指定时,服务器不仅会验证证书链,还会检查用户名或其映射是否匹配`cn`所提供证书的(通用名称)。请注意,证书链验证始终确保当`证书`使用身份验证方法(请参阅[第 21.12 节](auth-cert.html))。

链接到现有根证书的中间证书也可以出现在[ssl\_约\_文件](runtime-config-connection.html#GUC-SSL-CA-FILE)如果您希望避免将它们存储在客户端上(假设根证书和中间证书是使用`v3_ca`扩展名)。如果参数[ssl_crl\_文件](runtime-config-connection.html#GUC-SSL-CRL-FILE)要么[ssl_crl\_目录](runtime-config-connection.html#GUC-SSL-CRL-DIR)已设置。

`客户证书`身份验证选项可用于所有身份验证方法,但仅在`pg_hba.conf`指定为的行`主机`.什么时候`客户证书`如果未指定,则服务器仅在提供客户端证书并配置 CA 时才根据其 CA 文件验证客户端证书。

有两种方法可以强制用户在登录期间提供证书。

第一种方法利用`证书`认证方法为`主机`中的条目`pg_hba.conf`,以便证书本身用于身份验证,同时还提供 ssl 连接安全性。看[第 21.12 节](auth-cert.html)详情。(没有必要指定任何`客户证书`使用时明确的选项`证书`验证方法。)在这种情况下,`cn`证书中提供的(通用名称)会根据用户名或适用的映射进行检查。

第二种方法结合了任何身份验证方法`hostssl`entries with the verification of client certificates by setting the`clientcert`authentication option to`verify-ca`or`verify-full`. The former option only enforces that the certificate is valid, while the latter also ensures that the`cn`(Common Name) in the certificate matches the user name or an applicable mapping.

### 19.9.4. SSL Server File Usage

[Table 19.2](ssl-tcp.html#SSL-FILE-USAGE)summarizes the files that are relevant to the SSL setup on the server. (The shown file names are default names. The locally configured names could be different.)

**Table 19.2. SSL Server File Usage**

| File | Contents | Effect |
| ---- | -------- | ------ |
| [ssl_cert_file](runtime-config-connection.html#GUC-SSL-CERT-FILE)(`$PGDATA/server.crt`) | server certificate | sent to client to indicate server's identity |
| [ssl_key_file](runtime-config-connection.html#GUC-SSL-KEY-FILE)(`$PGDATA/server.key`) | server private key | proves server certificate was sent by the owner; does not indicate certificate owner is trustworthy |
| [ssl_ca_file](runtime-config-connection.html#GUC-SSL-CA-FILE) | trusted certificate authorities | checks that client certificate is signed by a trusted certificate authority |
| [ssl_crl_file](runtime-config-connection.html#GUC-SSL-CRL-FILE) | certificates revoked by certificate authorities | client certificate must not be on this list |

The server reads these files at server start and whenever the server configuration is reloaded. On Windows systems, they are also re-read whenever a new backend process is spawned for a new client connection.

If an error in these files is detected at server start, the server will refuse to start. But if an error is detected during a configuration reload, the files are ignored and the old SSL configuration continues to be used. On Windows systems, if an error in these files is detected at backend start, that backend will be unable to establish an SSL connection. In all these cases, the error condition is reported in the server log.

### 19.9.5. Creating Certificates

To create a simple self-signed certificate for the server, valid for 365 days, use the following OpenSSL command, replacing*`dbhost.yourdomain.com`*使用服务器的主机名:

```
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
```

然后做:

```
chmod og-rwx server.key
```

因为如果文件的权限比这更自由,服务器将拒绝该文件。有关如何创建服务器私钥和证书的更多详细信息,请参阅 OpenSSL 文档。

虽然自签名证书可用于测试,但应在生产中使用由证书颁发机构 (CA)(通常是企业范围的根 CA)签名的证书。

要创建其身份可以由客户端验证的服务器证书,请首先创建证书签名请求 (CSR) 和公钥/私钥文件:

```
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
```

然后,使用密钥签署请求以创建根证书颁发机构(使用 Linux 上的默认 OpenSSL 配置文件位置):

```
openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt
```

最后,创建一个由新的根证书颁发机构签名的服务器证书:

```
openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key

openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt
```

`服务器.crt``服务器密钥`应该存储在服务器上,并且`根.crt`应该存储在客户端上,以便客户端可以验证服务器的叶证书是否由其受信任的根证书签名。`根密钥`应离线存储以用于创建未来的证书。

还可以创建包含中间证书的信任链:

```
# root
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

# intermediate
openssl req -new -nodes -text -out intermediate.csr \
  -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com"
chmod og-rwx intermediate.key
openssl x509 -req -in intermediate.csr -text -days 1825 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out intermediate.crt

# leaf
openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
  -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
  -out server.crt
```

`服务器.crt``中级.crt`应连接成证书文件包并存储在服务器上。`服务器密钥`也应该存储在服务器上。`根.crt`应该存储在客户端上,以便客户端可以验证服务器的叶证书是否由链接到其受信任的根证书的证书链签名。`根密钥``中间密钥`应离线存储以用于创建未来的证书。