Skip to content

Commit 0253f80

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 9a215fb commit 0253f80

File tree

2 files changed

+164
-83
lines changed

2 files changed

+164
-83
lines changed

doc/src/sgml/libpq.sgml

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

71057111
<para>
7112+
To allow the client to verify the identity of the server, place a root
7113+
certificate on the client and a leaf certificate signed by the root
7114+
certificate on the server. To allow the server to verify the identity
7115+
of the client, place a root certificate on the server and a leaf and
7116+
optional intermediate certificates signed by the root certificate on
7117+
the client. Intermediate certificates (usually stored with the leaf
7118+
certificate) can also be used to link the leaf certificate to the
7119+
root certificate.
7120+
</para>
7121+
7122+
<para>
7123+
Once a chain of trust has been established, there are two ways for
7124+
the client to validate the leaf certificate sent by the server.
71067125
If the parameter <literal>sslmode</> is set to <literal>verify-ca</>,
71077126
libpq will verify that the server is trustworthy by checking the
7108-
certificate chain up to a trusted certificate authority
7109-
(<acronym>CA</>). If <literal>sslmode</> is set to <literal>verify-full</>,
7110-
libpq will <emphasis>also</> verify that the server host name matches its
7111-
certificate. The SSL connection will fail if the server certificate cannot
7112-
be verified. <literal>verify-full</> is recommended in most
7127+
certificate chain up to the root certificate stored on the client.
7128+
If <literal>sslmode</> is set to <literal>verify-full</>,
7129+
libpq will <emphasis>also</> verify that the server host
7130+
name matches the name stored in the server certificate. The
7131+
SSL connection will fail if the server certificate cannot be
7132+
verified. <literal>verify-full</> is recommended in most
71137133
security-sensitive environments.
71147134
</para>
71157135

@@ -7124,11 +7144,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71247144
</para>
71257145

71267146
<para>
7127-
To allow server certificate verification, the certificate(s) of one or more
7128-
trusted <acronym>CA</>s must be
7129-
placed in the file <filename>~/.postgresql/root.crt</> in the user's home
7130-
directory. (On Microsoft Windows the file is named
7131-
<filename>%APPDATA%\postgresql\root.crt</filename>.)
7147+
To allow server certificate verification, one or more root certificates
7148+
must be placed in the file <filename>~/.postgresql/root.crt</>
7149+
in the user's home directory. (On Microsoft Windows the file is named
7150+
<filename>%APPDATA%\postgresql\root.crt</>.) Intermediate
7151+
certificates should also be added to the file if they are needed to link
7152+
the certificate chain sent by the server to the root certificates
7153+
stored on the client.
71327154
</para>
71337155

71347156
<para>
@@ -7162,11 +7184,12 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71627184
<title>Client Certificates</title>
71637185

71647186
<para>
7165-
If the server requests a trusted client certificate,
7166-
<application>libpq</application> will send the certificate stored in
7187+
If the server attempts to verify the identity of the
7188+
client by requesting the client's leaf certificate,
7189+
<application>libpq</> will send the certificates stored in
71677190
file <filename>~/.postgresql/postgresql.crt</> in the user's home
7168-
directory. The certificate must be signed by one of the certificate
7169-
authorities (<acronym>CA</acronym>) trusted by the server. A matching
7191+
directory. The certificates must chain to the root certificate trusted
7192+
by the server. A matching
71707193
private key file <filename>~/.postgresql/postgresql.key</> must also
71717194
be present. The private
71727195
key file must not allow any access to world or group; achieve this by the
@@ -7181,23 +7204,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
71817204
</para>
71827205

71837206
<para>
7184-
In some cases, the client certificate might be signed by an
7185-
<quote>intermediate</> certificate authority, rather than one that is
7186-
directly trusted by the server. To use such a certificate, append the
7187-
certificate of the signing authority to the <filename>postgresql.crt</>
7188-
file, then its parent authority's certificate, and so on up to a
7189-
<quote>root</> authority that is trusted by the server. The root
7190-
certificate should be included in every case where
7191-
<filename>postgresql.crt</> contains more than one certificate.
7207+
The first certificate in <filename>postgresql.crt</> must be the
7208+
client's certificate because it must match the client's private key.
7209+
<quote>Intermediate</> certificates can be optionally appended
7210+
to the file &mdash; doing so avoids requiring storage of intermediate
7211+
certificates on the server's <filename>root.crt</filename> file.
71927212
</para>
71937213

71947214
<para>
7195-
Note that <filename>root.crt</filename> lists the top-level CAs that are
7196-
considered trusted for signing server certificates. In principle it need
7197-
not list the CA that signed the client's certificate, though in most cases
7198-
that CA would also be trusted for server certificates.
7215+
For instructions on creating certificates, see <xref
7216+
linkend="ssl-certificate-creation">.
71997217
</para>
7200-
72017218
</sect2>
72027219

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

doc/src/sgml/runtime.sgml

Lines changed: 119 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,34 +2110,46 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
21102110
</para>
21112111

21122112
<para>
2113-
In some cases, the server certificate might be signed by an
2114-
<quote>intermediate</> certificate authority, rather than one that is
2115-
directly trusted by clients. To use such a certificate, append the
2116-
certificate of the signing authority to the <filename>server.crt</> file,
2117-
then its parent authority's certificate, and so on up to a <quote>root</>
2118-
authority that is trusted by the clients. The root certificate should
2119-
be included in every case where <filename>server.crt</> contains more than
2120-
one certificate.
2113+
The first certificate in <filename>server.crt</> must be the
2114+
server's certificate because it must match the server's private key.
2115+
The certificates of <quote>intermediate</> certificate authorities
2116+
can also be appended to the file. Doing this avoids the necessity of
2117+
storing intermediate certificates on clients, assuming the root and
2118+
intermediate certificates were created with <literal>v3_ca</>
2119+
extensions. This allows easier expiration of intermediate certificates.
2120+
</para>
2121+
2122+
<para>
2123+
It is not necessary to add the root certificate to
2124+
<filename>server.crt</>. Instead, clients must have the root
2125+
certificate of the server's certificate chain.
21212126
</para>
21222127

21232128
<sect2 id="ssl-client-certificates">
21242129
<title>Using Client Certificates</title>
21252130

2126-
<para>
2127-
To require the client to supply a trusted certificate, place
2128-
certificates of the certificate authorities (<acronym>CA</acronym>s)
2129-
you trust in the file <filename>root.crt</filename> in the data
2131+
<para>
2132+
To require the client to supply a trusted certificate,
2133+
place certificates of the root certificate authorities
2134+
(<acronym>CA</>s) you trust in a file in the data
21302135
directory, set the parameter <xref linkend="guc-ssl-ca-file"> in
2131-
<filename>postgresql.conf</filename> to <literal>root.crt</literal>,
2132-
and set the <literal>clientcert</literal> parameter
2133-
to 1 on the appropriate <literal>hostssl</> line(s) in
2134-
<filename>pg_hba.conf</>.
2135-
A certificate will then be requested from the client during
2136-
SSL connection startup. (See <xref linkend="libpq-ssl"> for a
2137-
description of how to set up certificates on the client.) The server will
2136+
<filename>postgresql.conf</> to the new file name, and add the
2137+
authentication option <literal>clientcert=1</> to the appropriate
2138+
<literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
2139+
A certificate will then be requested from the client during SSL
2140+
connection startup. (See <xref linkend="libpq-ssl"> for a description
2141+
of how to set up certificates on the client.) The server will
21382142
verify that the client's certificate is signed by one of the trusted
2139-
certificate authorities. Certificate Revocation List (CRL) entries
2140-
are also checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
2143+
certificate authorities.
2144+
</para>
2145+
2146+
<para>
2147+
Intermediate certificates that chain up to existing root certificates
2148+
can also appear in the file <filename>root.crt</filename> if
2149+
you wish to avoid storing them on clients (assuming the root and
2150+
intermediate certificates were created with <literal>v3_ca</>
2151+
extensions). Certificate Revocation List (CRL) entries are also
2152+
checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
21412153
<!-- If this URL changes replace it with a URL to www.archive.org. -->
21422154
(See <ulink
21432155
url="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html"></>
@@ -2153,13 +2165,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
21532165
&mdash; but it will not insist that a client certificate be presented.
21542166
</para>
21552167

2156-
<para>
2157-
Note that <filename>root.crt</filename> lists the top-level CAs that are
2158-
considered trusted for signing client certificates. In principle it need
2159-
not list the CA that signed the server's certificate, though in most cases
2160-
that CA would also be trusted for client certificates.
2161-
</para>
2162-
21632168
<para>
21642169
If you are setting up client certificates, you may wish to use
21652170
the <literal>cert</> authentication method, so that the certificates
@@ -2230,31 +2235,18 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
22302235
</sect2>
22312236

22322237
<sect2 id="ssl-certificate-creation">
2233-
<title>Creating a Self-signed Certificate</title>
2238+
<title>Creating Certificates</title>
22342239

22352240
<para>
2236-
To create a quick self-signed certificate for the server, use the
2237-
following <productname>OpenSSL</productname> command:
2238-
<programlisting>
2239-
openssl req -new -text -out server.req
2240-
</programlisting>
2241-
Fill out the information that <application>openssl</> asks for. Make sure
2242-
you enter the local host name as <quote>Common Name</>; the challenge
2243-
password can be left blank. The program will generate a key that is
2244-
passphrase protected; it will not accept a passphrase that is less
2245-
than four characters long. To remove the passphrase (as you must if
2246-
you want automatic start-up of the server), run the commands:
2247-
<programlisting>
2248-
openssl rsa -in privkey.pem -out server.key
2249-
rm privkey.pem
2250-
</programlisting>
2251-
Enter the old passphrase to unlock the existing key. Now do:
2241+
To create a simple self-signed certificate for the server, valid for 365
2242+
days, use the following <productname>OpenSSL</productname> command,
2243+
replacing <replaceable>dbhost.yourdomain.com</> with the
2244+
server's host name:
22522245
<programlisting>
2253-
openssl req -x509 -in server.req -text -key server.key -out server.crt
2246+
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
2247+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
22542248
</programlisting>
2255-
to turn the certificate into a self-signed certificate and to copy
2256-
the key and certificate to where the server will look for them.
2257-
Finally do:
2249+
Then do:
22582250
<programlisting>
22592251
chmod og-rwx server.key
22602252
</programlisting>
@@ -2265,14 +2257,86 @@ chmod og-rwx server.key
22652257
</para>
22662258

22672259
<para>
2268-
A self-signed certificate can be used for testing, but a certificate
2269-
signed by a certificate authority (<acronym>CA</>) (either one of the
2270-
global <acronym>CAs</> or a local one) should be used in production
2271-
so that clients can verify the server's identity. If all the clients
2272-
are local to the organization, using a local <acronym>CA</> is
2273-
recommended.
2260+
While a self-signed certificate can be used for testing, a certificate
2261+
signed by a certificate authority (<acronym>CA</>) (usually an
2262+
enterprise-wide root <acronym>CA</>) should be used in production.
22742263
</para>
22752264

2265+
<para>
2266+
To create a server certificate whose identity can be validated
2267+
by clients, first create a certificate signing request
2268+
(<acronym>CSR</>) and a public/private key file:
2269+
<programlisting>
2270+
openssl req -new -nodes -text -out root.csr \
2271+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2272+
chmod og-rwx root.key
2273+
</programlisting>
2274+
Then, sign the request with the key to create a root certificate
2275+
authority (using the default <productname>OpenSSL</>
2276+
configuration file location on <productname>Linux</>):
2277+
<programlisting>
2278+
openssl x509 -req -in root.csr -text -days 3650 \
2279+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2280+
-signkey root.key -out root.crt
2281+
</programlisting>
2282+
Finally, create a server certificate signed by the new root certificate
2283+
authority:
2284+
<programlisting>
2285+
openssl req -new -nodes -text -out server.csr \
2286+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2287+
chmod og-rwx server.key
2288+
2289+
openssl x509 -req -in server.csr -text -days 365 \
2290+
-CA root.crt -CAkey root.key -CAcreateserial \
2291+
-out server.crt
2292+
</programlisting>
2293+
<filename>server.crt</> and <filename>server.key</>
2294+
should be stored on the server, and <filename>root.crt</> should
2295+
be stored on the client so the client can verify that the server's leaf
2296+
certificate was signed by its trusted root certificate.
2297+
<filename>root.key</> should be stored offline for use in
2298+
creating future certificates.
2299+
</para>
2300+
2301+
<para>
2302+
It is also possible to create a chain of trust that includes
2303+
intermediate certificates:
2304+
<programlisting>
2305+
# root
2306+
openssl req -new -nodes -text -out root.csr \
2307+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2308+
chmod og-rwx root.key
2309+
openssl x509 -req -in root.csr -text -days 3650 \
2310+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2311+
-signkey root.key -out root.crt
2312+
2313+
# intermediate
2314+
openssl req -new -nodes -text -out intermediate.csr \
2315+
-keyout intermediate.key -subj "/CN=<replaceable>intermediate.yourdomain.com</>"
2316+
chmod og-rwx intermediate.key
2317+
openssl x509 -req -in intermediate.csr -text -days 1825 \
2318+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2319+
-CA root.crt -CAkey root.key -CAcreateserial \
2320+
-out intermediate.crt
2321+
2322+
# leaf
2323+
openssl req -new -nodes -text -out server.csr \
2324+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2325+
chmod og-rwx server.key
2326+
openssl x509 -req -in server.csr -text -days 365 \
2327+
-CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
2328+
-out server.crt
2329+
</programlisting>
2330+
<filename>server.crt</> and
2331+
<filename>intermediate.crt</> should be concatenated
2332+
into a certificate file bundle and stored on the server.
2333+
<filename>server.key</> should also be stored on the server.
2334+
<filename>root.crt</> should be stored on the client so
2335+
the client can verify that the server's leaf certificate was signed
2336+
by a chain of certificates linked to its trusted root certificate.
2337+
<filename>root.key</> and <filename>intermediate.key</>
2338+
should be stored offline for use in creating future certificates.
2339+
</para>
22762340
</sect2>
22772341

22782342
</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