Skip to content

Commit f840557

Browse files
committed
doc: update intermediate certificate instructions
Document how to properly create root and intermediate certificates using v3_ca extensions and where to place intermediate certificates so they are properly transferred to the remote side with the leaf certificate to link to the remote root certificate. This corrects docs that used to say that intermediate certificates must be stored with the root certificate. Also add instructions on how to create root, intermediate, and leaf certificates. Discussion: https://postgr.es/m/20180116002238.GC12724@momjian.us Reviewed-by: Michael Paquier Backpatch-through: 9.3
1 parent 1284d18 commit f840557

File tree

2 files changed

+164
-89
lines changed

2 files changed

+164
-89
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7093,17 +7093,37 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
70937093
the server certificate. This means that it is possible to spoof the server
70947094
identity (for example by modifying a DNS record or by taking over the server
70957095
IP address) without the client knowing. In order to prevent spoofing,
7096-
<acronym>SSL</> certificate verification must be used.
7096+
the client must be able to verify the server's identity via a chain of
7097+
trust. A chain of trust is established by placing a root (self-signed)
7098+
certificate authority (<acronym>CA</>) certificate on one
7099+
computer and a leaf certificate <emphasis>signed</> by the
7100+
root certificate on another computer. It is also possible to use an
7101+
<quote>intermediate</> certificate which is signed by the root
7102+
certificate and signs leaf certificates.
70977103
</para>
70987104

70997105
<para>
7106+
To allow the client to verify the identity of the server, place a root
7107+
certificate on the client and a leaf certificate signed by the root
7108+
certificate on the server. To allow the server to verify the identity
7109+
of the client, place a root certificate on the server and a leaf and
7110+
optional intermediate certificates signed by the root certificate on
7111+
the client. Intermediate certificates (usually stored with the leaf
7112+
certificate) can also be used to link the leaf certificate to the
7113+
root certificate.
7114+
</para>
7115+
7116+
<para>
7117+
Once a chain of trust has been established, there are two ways for
7118+
the client to validate the leaf certificate sent by the server.
71007119
If the parameter <literal>sslmode</> is set to <literal>verify-ca</>,
71017120
libpq will verify that the server is trustworthy by checking the
7102-
certificate chain up to a trusted certificate authority
7103-
(<acronym>CA</>). If <literal>sslmode</> is set to <literal>verify-full</>,
7104-
libpq will <emphasis>also</> verify that the server host name matches its
7105-
certificate. The SSL connection will fail if the server certificate cannot
7106-
be verified. <literal>verify-full</> is recommended in most
7121+
certificate chain up to the root certificate stored on the client.
7122+
If <literal>sslmode</> is set to <literal>verify-full</>,
7123+
libpq will <emphasis>also</> verify that the server host
7124+
name matches the name stored in the server certificate. The
7125+
SSL connection will fail if the server certificate cannot be
7126+
verified. <literal>verify-full</> is recommended in most
71077127
security-sensitive environments.
71087128
</para>
71097129

@@ -7118,13 +7138,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71187138
</para>
71197139

71207140
<para>
7121-
To allow server certificate verification, the certificate(s) of one or more
7122-
trusted <acronym>CA</>s must be
7123-
placed in the file <filename>~/.postgresql/root.crt</> in the user's home
7124-
directory. If intermediate <acronym>CA</>s appear in
7125-
<filename>root.crt</filename>, the file must also contain certificate
7126-
chains to their root <acronym>CA</>s. (On Microsoft Windows the file is named
7127-
<filename>%APPDATA%\postgresql\root.crt</filename>.)
7141+
To allow server certificate verification, one or more root certificates
7142+
must be placed in the file <filename>~/.postgresql/root.crt</>
7143+
in the user's home directory. (On Microsoft Windows the file is named
7144+
<filename>%APPDATA%\postgresql\root.crt</>.) Intermediate
7145+
certificates should also be added to the file if they are needed to link
7146+
the certificate chain sent by the server to the root certificates
7147+
stored on the client.
71287148
</para>
71297149

71307150
<para>
@@ -7158,11 +7178,12 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71587178
<title>Client Certificates</title>
71597179

71607180
<para>
7161-
If the server requests a trusted client certificate,
7162-
<application>libpq</application> will send the certificate stored in
7181+
If the server attempts to verify the identity of the
7182+
client by requesting the client's leaf certificate,
7183+
<application>libpq</> will send the certificates stored in
71637184
file <filename>~/.postgresql/postgresql.crt</> in the user's home
7164-
directory. The certificate must be signed by one of the certificate
7165-
authorities (<acronym>CA</acronym>) trusted by the server. A matching
7185+
directory. The certificates must chain to the root certificate trusted
7186+
by the server. A matching
71667187
private key file <filename>~/.postgresql/postgresql.key</> must also
71677188
be present. The private
71687189
key file must not allow any access to world or group; achieve this by the
@@ -7177,23 +7198,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71777198
</para>
71787199

71797200
<para>
7180-
In some cases, the client certificate might be signed by an
7181-
<quote>intermediate</> certificate authority, rather than one that is
7182-
directly trusted by the server. To use such a certificate, append the
7183-
certificate of the signing authority to the <filename>postgresql.crt</>
7184-
file, then its parent authority's certificate, and so on up to a certificate
7185-
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
7186-
the server, i.e. signed by a certificate in the server's
7187-
<filename>root.crt</filename> file.
7201+
The first certificate in <filename>postgresql.crt</> must be the
7202+
client's certificate because it must match the client's private key.
7203+
<quote>Intermediate</> certificates can be optionally appended
7204+
to the file &mdash; doing so avoids requiring storage of intermediate
7205+
certificates on the server's <filename>root.crt</filename> file.
71887206
</para>
71897207

71907208
<para>
7191-
Note that the client's <filename>~/.postgresql/root.crt</> lists the top-level CAs
7192-
that are considered trusted for signing server certificates. In principle it need
7193-
not list the CA that signed the client's certificate, though in most cases
7194-
that CA would also be trusted for server certificates.
7209+
For instructions on creating certificates, see <xref
7210+
linkend="ssl-certificate-creation">.
71957211
</para>
7196-
71977212
</sect2>
71987213

71997214
<sect2 id="libpq-ssl-protection">

doc/src/sgml/runtime.sgml

Lines changed: 119 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,37 +2203,46 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
22032203
</para>
22042204

22052205
<para>
2206-
In some cases, the server certificate might be signed by an
2207-
<quote>intermediate</> certificate authority, rather than one that is
2208-
directly trusted by clients. To use such a certificate, append the
2209-
certificate of the signing authority to the <filename>server.crt</> file,
2210-
then its parent authority's certificate, and so on up to a certificate
2211-
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
2212-
clients, i.e. signed by a certificate in the clients'
2213-
<filename>root.crt</filename> files.
2206+
The first certificate in <filename>server.crt</> must be the
2207+
server's certificate because it must match the server's private key.
2208+
The certificates of <quote>intermediate</> certificate authorities
2209+
can also be appended to the file. Doing this avoids the necessity of
2210+
storing intermediate certificates on clients, assuming the root and
2211+
intermediate certificates were created with <literal>v3_ca</>
2212+
extensions. This allows easier expiration of intermediate certificates.
2213+
</para>
2214+
2215+
<para>
2216+
It is not necessary to add the root certificate to
2217+
<filename>server.crt</>. Instead, clients must have the root
2218+
certificate of the server's certificate chain.
22142219
</para>
22152220

22162221
<sect2 id="ssl-client-certificates">
22172222
<title>Using Client Certificates</title>
22182223

2219-
<para>
2220-
To require the client to supply a trusted certificate, place
2221-
certificates of the certificate authorities (<acronym>CA</acronym>s)
2222-
you trust in the file <filename>root.crt</filename> in the data
2224+
<para>
2225+
To require the client to supply a trusted certificate,
2226+
place certificates of the root certificate authorities
2227+
(<acronym>CA</>s) you trust in a file in the data
22232228
directory, set the parameter <xref linkend="guc-ssl-ca-file"> in
2224-
<filename>postgresql.conf</filename> to <literal>root.crt</literal>,
2225-
and set the <literal>clientcert</literal> parameter
2226-
to 1 on the appropriate <literal>hostssl</> line(s) in
2227-
<filename>pg_hba.conf</>.
2228-
A certificate will then be requested from the client during
2229-
SSL connection startup. (See <xref linkend="libpq-ssl"> for a
2230-
description of how to set up certificates on the client.) The server will
2229+
<filename>postgresql.conf</> to the new file name, and add the
2230+
authentication option <literal>clientcert=1</> to the appropriate
2231+
<literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
2232+
A certificate will then be requested from the client during SSL
2233+
connection startup. (See <xref linkend="libpq-ssl"> for a description
2234+
of how to set up certificates on the client.) The server will
22312235
verify that the client's certificate is signed by one of the trusted
2232-
certificate authorities. If intermediate <acronym>CA</>s appear in
2233-
<filename>root.crt</filename>, the file must also contain certificate
2234-
chains to their root <acronym>CA</>s. Certificate Revocation List
2235-
(CRL) entries
2236-
are also checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
2236+
certificate authorities.
2237+
</para>
2238+
2239+
<para>
2240+
Intermediate certificates that chain up to existing root certificates
2241+
can also appear in the file <filename>root.crt</filename> if
2242+
you wish to avoid storing them on clients (assuming the root and
2243+
intermediate certificates were created with <literal>v3_ca</>
2244+
extensions). Certificate Revocation List (CRL) entries are also
2245+
checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
22372246
<!-- If this URL changes replace it with a URL to www.archive.org. -->
22382247
(See <ulink
22392248
url="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html"></>
@@ -2249,14 +2258,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
22492258
&mdash; but it will not insist that a client certificate be presented.
22502259
</para>
22512260

2252-
<para>
2253-
Note that the server's <filename>root.crt</filename> lists the top-level
2254-
CAs that are considered trusted for signing client certificates.
2255-
In principle it need
2256-
not list the CA that signed the server's certificate, though in most cases
2257-
that CA would also be trusted for client certificates.
2258-
</para>
2259-
22602261
<para>
22612262
If you are setting up client certificates, you may wish to use
22622263
the <literal>cert</> authentication method, so that the certificates
@@ -2327,31 +2328,18 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
23272328
</sect2>
23282329

23292330
<sect2 id="ssl-certificate-creation">
2330-
<title>Creating a Self-signed Certificate</title>
2331+
<title>Creating Certificates</title>
23312332

23322333
<para>
2333-
To create a quick self-signed certificate for the server, use the
2334-
following <productname>OpenSSL</productname> command:
2335-
<programlisting>
2336-
openssl req -new -text -out server.req
2337-
</programlisting>
2338-
Fill out the information that <application>openssl</> asks for. Make sure
2339-
you enter the local host name as <quote>Common Name</>; the challenge
2340-
password can be left blank. The program will generate a key that is
2341-
passphrase protected; it will not accept a passphrase that is less
2342-
than four characters long. To remove the passphrase (as you must if
2343-
you want automatic start-up of the server), run the commands:
2344-
<programlisting>
2345-
openssl rsa -in privkey.pem -out server.key
2346-
rm privkey.pem
2347-
</programlisting>
2348-
Enter the old passphrase to unlock the existing key. Now do:
2334+
To create a simple self-signed certificate for the server, valid for 365
2335+
days, use the following <productname>OpenSSL</productname> command,
2336+
replacing <replaceable>dbhost.yourdomain.com</> with the
2337+
server's host name:
23492338
<programlisting>
2350-
openssl req -x509 -in server.req -text -key server.key -out server.crt
2339+
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
2340+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
23512341
</programlisting>
2352-
to turn the certificate into a self-signed certificate and to copy
2353-
the key and certificate to where the server will look for them.
2354-
Finally do:
2342+
Then do:
23552343
<programlisting>
23562344
chmod og-rwx server.key
23572345
</programlisting>
@@ -2362,14 +2350,86 @@ chmod og-rwx server.key
23622350
</para>
23632351

23642352
<para>
2365-
A self-signed certificate can be used for testing, but a certificate
2366-
signed by a certificate authority (<acronym>CA</>) (either one of the
2367-
global <acronym>CAs</> or a local one) should be used in production
2368-
so that clients can verify the server's identity. If all the clients
2369-
are local to the organization, using a local <acronym>CA</> is
2370-
recommended.
2353+
While a self-signed certificate can be used for testing, a certificate
2354+
signed by a certificate authority (<acronym>CA</>) (usually an
2355+
enterprise-wide root <acronym>CA</>) should be used in production.
23712356
</para>
23722357

2358+
<para>
2359+
To create a server certificate whose identity can be validated
2360+
by clients, first create a certificate signing request
2361+
(<acronym>CSR</>) and a public/private key file:
2362+
<programlisting>
2363+
openssl req -new -nodes -text -out root.csr \
2364+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2365+
chmod og-rwx root.key
2366+
</programlisting>
2367+
Then, sign the request with the key to create a root certificate
2368+
authority (using the default <productname>OpenSSL</>
2369+
configuration file location on <productname>Linux</>):
2370+
<programlisting>
2371+
openssl x509 -req -in root.csr -text -days 3650 \
2372+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2373+
-signkey root.key -out root.crt
2374+
</programlisting>
2375+
Finally, create a server certificate signed by the new root certificate
2376+
authority:
2377+
<programlisting>
2378+
openssl req -new -nodes -text -out server.csr \
2379+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2380+
chmod og-rwx server.key
2381+
2382+
openssl x509 -req -in server.csr -text -days 365 \
2383+
-CA root.crt -CAkey root.key -CAcreateserial \
2384+
-out server.crt
2385+
</programlisting>
2386+
<filename>server.crt</> and <filename>server.key</>
2387+
should be stored on the server, and <filename>root.crt</> should
2388+
be stored on the client so the client can verify that the server's leaf
2389+
certificate was signed by its trusted root certificate.
2390+
<filename>root.key</> should be stored offline for use in
2391+
creating future certificates.
2392+
</para>
2393+
2394+
<para>
2395+
It is also possible to create a chain of trust that includes
2396+
intermediate certificates:
2397+
<programlisting>
2398+
# root
2399+
openssl req -new -nodes -text -out root.csr \
2400+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2401+
chmod og-rwx root.key
2402+
openssl x509 -req -in root.csr -text -days 3650 \
2403+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2404+
-signkey root.key -out root.crt
2405+
2406+
# intermediate
2407+
openssl req -new -nodes -text -out intermediate.csr \
2408+
-keyout intermediate.key -subj "/CN=<replaceable>intermediate.yourdomain.com</>"
2409+
chmod og-rwx intermediate.key
2410+
openssl x509 -req -in intermediate.csr -text -days 1825 \
2411+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2412+
-CA root.crt -CAkey root.key -CAcreateserial \
2413+
-out intermediate.crt
2414+
2415+
# leaf
2416+
openssl req -new -nodes -text -out server.csr \
2417+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2418+
chmod og-rwx server.key
2419+
openssl x509 -req -in server.csr -text -days 365 \
2420+
-CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
2421+
-out server.crt
2422+
</programlisting>
2423+
<filename>server.crt</> and
2424+
<filename>intermediate.crt</> should be concatenated
2425+
into a certificate file bundle and stored on the server.
2426+
<filename>server.key</> should also be stored on the server.
2427+
<filename>root.crt</> should be stored on the client so
2428+
the client can verify that the server's leaf certificate was signed
2429+
by a chain of certificates linked to its trusted root certificate.
2430+
<filename>root.key</> and <filename>intermediate.key</>
2431+
should be stored offline for use in creating future certificates.
2432+
</para>
23732433
</sect2>
23742434

23752435
</sect1>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy