diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 4e4645136c6..92c64b43d4a 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -7574,17 +7574,37 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
the server certificate. This means that it is possible to spoof the server
identity (for example by modifying a DNS record or by taking over the server
IP address) without the client knowing. In order to prevent spoofing,
- SSL certificate verification must be used.
+ the client must be able to verify the server's identity via a chain of
+ trust. A chain of trust is established by placing a root (self-signed)
+ certificate authority (CA) certificate on one
+ computer and a leaf certificate signed by the
+ root certificate on another computer. It is also possible to use an
+ intermediate
certificate which is signed by the root
+ certificate and signs leaf certificates.
+ To allow the client to verify the identity of the server, place a root
+ certificate on the client and a leaf certificate signed by the root
+ certificate on the server. To allow the server to verify the identity
+ of the client, place a root certificate on the server and a leaf and
+ optional intermediate certificates signed by the root certificate on
+ the client. Intermediate certificates (usually stored with the leaf
+ certificate) can also be used to link the leaf certificate to the
+ root certificate.
+
+
+
+ Once a chain of trust has been established, there are two ways for
+ the client to validate the leaf certificate sent by the server.
If the parameter sslmode is set to verify-ca,
libpq will verify that the server is trustworthy by checking the
- certificate chain up to a trusted certificate authority
- (CA). If sslmode is set to verify-full,
- libpq will also verify that the server host name matches its
- certificate. The SSL connection will fail if the server certificate cannot
- be verified. verify-full is recommended in most
+ certificate chain up to the root certificate stored on the client.
+ If sslmode is set to verify-full,
+ libpq will also verify that the server host
+ name matches the name stored in the server certificate. The
+ SSL connection will fail if the server certificate cannot be
+ verified. verify-full is recommended in most
security-sensitive environments.
@@ -7601,13 +7621,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
- To allow server certificate verification, the certificate(s) of one or more
- trusted CAs must be
- placed in the file ~/.postgresql/root.crt in the user's home
- directory. If intermediate CAs appear in
- root.crt, the file must also contain certificate
- chains to their root CAs. (On Microsoft Windows the file is named
- %APPDATA%\postgresql\root.crt.)
+ To allow server certificate verification, one or more root certificates
+ must be placed in the file ~/.postgresql/root.crt
+ in the user's home directory. (On Microsoft Windows the file is named
+ %APPDATA%\postgresql\root.crt.) Intermediate
+ certificates should also be added to the file if they are needed to link
+ the certificate chain sent by the server to the root certificates
+ stored on the client.
@@ -7641,11 +7661,12 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
Client Certificates
- If the server requests a trusted client certificate,
- libpq will send the certificate stored in
+ If the server attempts to verify the identity of the
+ client by requesting the client's leaf certificate,
+ libpq will send the certificates stored in
file ~/.postgresql/postgresql.crt in the user's home
- directory. The certificate must be signed by one of the certificate
- authorities (CA) trusted by the server. A matching
+ directory. The certificates must chain to the root certificate trusted
+ by the server. A matching
private key file ~/.postgresql/postgresql.key must also
be present. The private
key file must not allow any access to world or group; achieve this by the
@@ -7660,23 +7681,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
- In some cases, the client certificate might be signed by an
- intermediate
certificate authority, rather than one that is
- directly trusted by the server. To use such a certificate, append the
- certificate of the signing authority to the postgresql.crt
- file, then its parent authority's certificate, and so on up to a certificate
- authority, root
or intermediate
, that is trusted by
- the server, i.e. signed by a certificate in the server's root CA file
- ().
+ The first certificate in postgresql.crt must be the
+ client's certificate because it must match the client's private key.
+ Intermediate
certificates can be optionally appended
+ to the file — doing so avoids requiring storage of intermediate
+ certificates on the server ().
- Note that the client's ~/.postgresql/root.crt lists the top-level CAs
- that are considered trusted for signing server certificates. In principle it need
- not list the CA that signed the client's certificate, though in most cases
- that CA would also be trusted for server certificates.
+ For instructions on creating certificates, see .
-
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index a2ebd3e21ca..d162acb2e84 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2247,40 +2247,46 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
- In some cases, the server certificate might be signed by an
- intermediate
certificate authority, rather than one that is
- directly trusted by clients. To use such a certificate, append the
- certificate of the signing authority to the server.crt file,
- then its parent authority's certificate, and so on up to a certificate
- authority, root
or intermediate
, that is trusted by
- clients, i.e. signed by a certificate in the clients'
- root.crt files.
+ The first certificate in 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 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.
Using Client Certificates
- To require the client to supply a trusted certificate, place
- certificates of the certificate authorities (CAs)
- you trust in a file named root.crt in the data
+ 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 in
- postgresql.conf to root.crt,
- and add the authentication option clientcert=1 to the
- appropriate hostssl line(s) in pg_hba.conf.
- A certificate will then be requested from the client during
- SSL connection startup. (See for a
- description of how to set up certificates on the client.) The server will
+ postgresql.conf to the new file name, and add the
+ authentication option clientcert=1 to the appropriate
+ hostssl line(s) in pg_hba.conf.
+ A certificate will then be requested from the client during SSL
+ connection startup. (See for a description
+ of how to set up certificates on the client.) The server will
verify that the client's certificate is signed by one of the trusted
certificate authorities.
- If intermediate CAs appear in
- root.crt, the file must also contain certificate
- chains to their root CAs. Certificate Revocation List
- (CRL) entries
- are also checked if the parameter is set.
+ Intermediate certificates that chain up to existing root certificates
+ can also appear in the file if
+ you wish to avoid storing them on clients (assuming the root and
+ intermediate certificates were created with v3_ca
+ extensions). Certificate Revocation List (CRL) entries are also
+ checked if the parameter is set.
(See
@@ -2296,14 +2302,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
it will not insist that a client certificate be presented.
-
- Note that the server's root.crt lists the top-level
- CAs that are considered trusted for signing client certificates.
- In principle it need
- not list the CA that signed the server's certificate, though in most cases
- that CA would also be trusted for client certificates.
-
-
If you are setting up client certificates, you may wish to use
the cert authentication method, so that the certificates
@@ -2385,15 +2383,16 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
- Creating a Self-signed Certificate
+ Creating Certificates
- To create a quick self-signed certificate for the server, valid for 365
+ To create a simple self-signed certificate for the server, valid for 365
days, use the following OpenSSL command,
- replacing yourdomain.com with the server's host name:
+ replacing dbhost.yourdomain.com with the
+ server's host name:
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
- -keyout server.key -subj "/CN=yourdomain.com"
+ -keyout server.key -subj "/CN=dbhost.yourdomain.com"
Then do:
@@ -2406,14 +2405,86 @@ chmod og-rwx server.key
- A self-signed certificate can be used for testing, but a certificate
- signed by a certificate authority (CA) (either one of the
- global CAs or a local one) should be used in production
- so that clients can verify the server's identity. If all the clients
- are local to the organization, using a local CA is
- recommended.
+ While a self-signed certificate can be used for testing, a certificate
+ signed by a certificate authority (CA) (usually an
+ enterprise-wide root CA) should be used in production.
+
+ To create a server certificate whose identity can be validated
+ by clients, first create a certificate signing request
+ (CSR) and a public/private key file:
+
+openssl req -new -nodes -text -out root.csr \
+ -keyout root.key -subj "/CN=root.yourdomain.com"
+chmod og-rwx root.key
+
+ Then, sign the request with the key to create a root certificate
+ authority (using the default OpenSSL
+ configuration file location on Linux):
+
+openssl x509 -req -in root.csr -text -days 3650 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -signkey root.key -out root.crt
+
+ Finally, create a server certificate signed by the new root certificate
+ authority:
+
+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
+
+ server.crt and server.key
+ should be stored on the server, and root.crt should
+ be stored on the client so the client can verify that the server's leaf
+ certificate was signed by its trusted root certificate.
+ root.key should be stored offline for use in
+ creating future certificates.
+
+
+
+ It is also possible to create a chain of trust that includes
+ intermediate certificates:
+
+# 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
+
+ server.crt and
+ intermediate.crt should be concatenated
+ into a certificate file bundle and stored on the server.
+ server.key should also be stored on the server.
+ root.crt should be stored on the client so
+ the client can verify that the server's leaf certificate was signed
+ by a chain of certificates linked to its trusted root certificate.
+ root.key and intermediate.key
+ should be stored offline for use in creating future certificates.
+