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.
- To allow server certificate verification, the certificate(s) of one or more
- placed in the file ~/.postgresql/root.crt> in the user's home
- directory. If intermediate
CA>s appear in
- root.crt, the file must also contain certificate
- chains to their root
CA>s. (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.
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
- 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.crt 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's root.crt file.
- 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
+ linkend="ssl-certificate-creation">.
-
- 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 the file root.crt in the data
+ To require the client to supply a trusted certificate,
+ place certificates of the root certificate authorities
+
(CA>s) you trust in a file in the data
directory, set the parameter in
- postgresql.conffilename> 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
CA>s appear in
- root.crt, the file must also contain certificate
- chains to their root
CA>s. 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 root.crt 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
url="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html">>
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
-
Creating a Self-signed Certificate
+
Creating Certificates
- To create a quick self-signed certificate for the server, use the
- following
OpenSSL command:
-openssl req -new -text -out server.req
-
- Fill out the information that
openssl> asks for. Make sure
- you enter the local host name as Common Name>; the challenge
- password can be left blank. The program will generate a key that is
- passphrase protected; it will not accept a passphrase that is less
- than four characters long. To remove the passphrase (as you must if
- you want automatic start-up of the server), run the commands:
-openssl rsa -in privkey.pem -out server.key
-rm privkey.pem
-
- Enter the old passphrase to unlock the existing key. Now do:
+ To create a simple self-signed certificate for the server, valid for 365
+ days, use the following
OpenSSL command,
+ replacing dbhost.yourdomain.com> with the
+ server's host name:
-openssl req -x509 -in server.req -text -key server.key -out server.crt
+openssl req -new -x509 -days 365 -nodes -text -out server.crt \
+ -keyout server.key -subj "/CN=dbhost.yourdomain.com>"
- to turn the certificate into a self-signed certificate and to copy
- the key and certificate to where the server will look for them.
- Finally do:
+ Then do:
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.
+