8000 doc: update intermediate certificate instructions · MSPawanRanjith/postgres@d516aea · GitHub
[go: up one dir, main page]

Skip to content

Commit d516aea

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 8a71ee6 commit d516aea

File tree

2 files changed

+159
-87
lines changed

2 files changed

+159
-87
lines changed

doc/src/sgml/libpq.sgml

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

73397345
<para>
7346+
To allow the client to verify the identity of the server, place a root
7347+
certificate on the client and a leaf certificate signed by the root
7348+
certificate on the server. To allow the server to verify the identity
7349+
of the client, place a root certificate on the server and a leaf and
7350+
optional intermediate certificates signed by the root certificate on
7351+
the client. Intermediate certificates (usually stored with the leaf
7352+
certificate) can also be used to link the leaf certificate to the
7353+
root certificate.
7354+
</para>
7355+
7356+
<para>
7357+
Once a chain of trust has been established, there are two ways for
7358+
the client to validate the leaf certificate sent by the server.
73407359
If the parameter <literal>sslmode</> is set to <literal>verify-ca</>,
73417360
libpq will verify that the server is trustworthy by checking the
7342-
certificate chain up to a trusted certificate authority
7343-
(<acronym>CA</>). If <literal>sslmode</> is set to <literal>verify-full</>,
7344-
libpq will <emphasis>also</> verify that the server host name matches its
7345-
certificate. The SSL connection will fail if the server certificate cannot
7346-
be verified. <literal>verify-full</> is recommended in most
7361+
certificate chain up to the root certificate stored on the client.
7362+
If <literal>sslmode</> is set to <literal>verify-full</>,
7363+
libpq will <emphasis>also</> verify that the server host
7364+
name matches the name stored in the server certificate. The
7365+
SSL connection will fail if the server certificate cannot be
7366+
verified. <literal>verify-full</> is recommended in most
73477367
security-sensitive environments.
73487368
</para>
73497369

@@ -7360,13 +7380,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
73607380
</para>
73617381

73627382
<para>
7363-
To allow server certificate verification, the certificate(s) of one or more
7364-
trusted <acronym>CA</>s must be
7365-
placed in the file <filename>~/.postgresql/root.crt</> in the user's home
7366-
directory. If intermediate <acronym>CA</>s appear in
7367-
<filename>root.crt</filename>, the file must also contain certificate
7368-
chains to their root <acronym>CA</>s. (On Microsoft Windows the file is named
7369-
<filename>%APPDATA%\postgresql\root.crt</filename>.)
7383+
To allow server certificate verification, one or more root certificates
7384+
must be placed in the file <filename>~/.postgresql/root.crt</>
7385+
in the user's home directory. (On Microsoft Windows the file is named
7386+
<filename>%APPDATA%\postgresql\root.crt</>.) Intermediate
7387+
certificates should also be added to the file if they are needed to link
7388+
the certificate chain sent by the server to the root certificates
7389+
stored on the client.
73707390
</para>
73717391

73727392
<para>
@@ -7400,11 +7420,12 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
74007420
<title>Client Certificates</title>
74017421

74027422
<para>
7403-
If the server requests a trusted client certificate,
7404-
<application>libpq</application> will send the certificate stored in
7423+
If the server attempts to verify the identity of the
7424+
client by requesting the client's leaf certificate,
7425+
<application>libpq</> will send the certificates stored in
74057426
file <filename>~/.postgresql/postgresql.crt</> in the user's home
7406-
directory. The certificate must be signed by one of the certificate
7407-
authorities (<acronym>CA</acronym>) trusted by the server. A matching
7427+
directory. The certificates must chain to the root certificate trusted
7428+
by the server. A matching
74087429
private key file <filename>~/.postgresql/postgresql.key</> must also
74097430
be present. The private
74107431
key file must not allow any access to world or group; achieve this by the
@@ -7419,23 +7440,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
74197440
</para>
74207441

74217442
<para>
7422-
In some cases, the client certificate might be signed by an
7423-
<quote>intermediate</> certificate authority, rather than one that is
7424-
directly trusted by the server. To use such a certificate, append the
7425-
certificate of the signing authority to the <filename>postgresql.crt</>
7426-
file, then its parent authority's certificate, and so on up to a certificate
7427-
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
7428-
the server, i.e. signed by a certificate in the server's
7429-
<filename>root.crt</filename> file.
7443+
The first certificate in <filename>postgresql.crt</> must be the
7444+
client's certificate because it must match the client's private key.
7445+
<quote>Intermediate</> certificates can be optionally appended
7446+
to the file &mdash; doing so avoids requiring storage of intermediate
7447+
certificates on the server's <filename>root.crt</filename> file.
74307448
</para>
74317449

74327450
<para>
7433-
Note that the client's <filename>~/.postgresql/root.crt</> lists the top-level CAs
7434-
that are considered trusted for signing server certificates. In principle it need
7435-
not list the CA that signed the client's certificate, though in most cases
7436-
that CA would also be trusted for server certificates.
7451+
For instructions on creating certificates, see <xref
7452+
linkend="ssl-certificate-creation">.
74377453
</para>
7438-
74397454
</sect2>
74407455

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

doc/src/sgml/runtime.sgml

Lines changed: 114 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,40 +2276,46 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
22762276
</para>
22772277

22782278
<para>
2279-
In some cases, the server certificate might be signed by an
2280-
<quote>intermediate</> certificate authority, rather than one that is
2281-
directly trusted by clients. To use such a certificate, append the
2282-
certificate of the signing authority to the <filename>server.crt</> file,
2283-
then its parent authority's certificate, and so on up to a certificate
2284-
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
2285-
clients, i.e. signed by a certificate in the clients'
2286-
<filename>root.crt</filename> files.
2279+
The first certificate in <filename>server.crt</> must be the
2280+
server's certificate because it must match the server's private key.
2281+
The certificates of <quote>intermediate</> certificate authorities
2282+
can also be appended to the file. Doing this avoids the necessity of
2283+
storing intermediate certificates on clients, assuming the root and
2284+
intermediate certificates were created with <literal>v3_ca</>
2285+
extensions. This allows easier expiration of intermediate certificates.
2286+
</para>
2287+
2288+
<para>
2289+
It is not necessary to add the root certificate to
2290+
<filename>server.crt</>. Instead, clients must have the root
2291+
certificate of the server's certificate chain.
22872292
</para>
22882293

22892294
<sect2 id="ssl-client-certificates">
22902295
<title>Using Client Certificates</title>
22912296

22922297
<para>
2293-
To require the client to supply a trusted certificate, place
2294-
certificates of the certificate authorities (<acronym>CA</acronym>s)
2295-
you trust in the file <filename>root.crt</filename> in the data
2298+
To require the client to supply a trusted certificate,
2299+
place certificates of the root certificate authorities
2300+
(<acronym>CA</>s) you trust in a file in the data
22962301
directory, set the parameter <xref linkend="guc-ssl-ca-file"> in
2297-
<filename>postgresql.conf</filename> to <literal>root.crt</literal>,
2298-
and add the authentication option <literal>clientcert=1</literal> to the
2299-
appropriate <literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
2300-
A certificate will then be requested from the client during
2301-
SSL connection startup. (See <xref linkend="libpq-ssl"> for a
2302-
description of how to set up certificates on the client.) The server will
2302+
<filename>postgresql.conf</> to the new file name, and add the
2303+
authentication option <literal>clientcert=1</> to the appropriate
2304+
<literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
2305+
A certificate will then be requested from the client during SSL
2306+
connection startup. (See <xref linkend="libpq-ssl"> for a description
2307+
of how to set up certificates on the client.) The server will
23032308
verify that the client's certificate is signed by one of the trusted
23042309
certificate authorities.
23052310
</para>
23062311

23072312
<para>
2308-
If intermediate <acronym>CA</>s appear in
2309-
<filename>root.crt</filename>, the file must also contain certificate
2310-
chains to their root <acronym>CA</>s. Certificate Revocation List
2311-
(CRL) entries
2312-
are also checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
2313+
Intermediate certificates that chain up to existing root certificates
2314+
can also appear in the file <filename>root.crt</filename> if
2315+
you wish to avoid storing them on clients (assuming the root and
2316+
intermediate certificates were created with <literal>v3_ca</>
2317+
extensions). Certificate Revocation List (CRL) entries are also
2318+
checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
23132319
<!-- If this URL changes replace it with a URL to www.archive.org. -->
23142320
(See <ulink
23152321
url="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html"></>
@@ -2325,14 +2331,6 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
23252331
it will not insist that a client certificate be presented.
23262332
</para>
23272333

2328-
<para>
2329-
Note that the server's <filename>root.crt</filename> lists the top-level
2330-
CAs that are considered trusted for signing client certificates.
2331-
In principle it need
2332-
not list the CA that signed the server's certificate, though in most cases
2333-
that CA would also be trusted for client certificates.
2334-
</para>
2335-
23362334
<para>
23372335
If you are setting up client certificates, you may wish to use
23382336
the <literal>cert</> authentication method, so that the certificates
@@ -2405,31 +2403,18 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
24052403
</sect2>
24062404

24072405
<sect2 id="ssl-certificate-creation">
2408-
<title>Creating a Self-signed Certificate</title>
2406+
<title>Creating Certificates</title>
24092407

24102408
<para>
2411-
To create a quick self-signed certificate for the server, use the
2412-
following <productname>OpenSSL</productname> command:
2413-
<programlisting>
2414-
openssl req -new -text -out server.req
2415-
</programlisting>
2416-
Fill out the information that <application>openssl</> asks for. Make sure
2417-
you enter the local host name as <quote>Common Name</>; the challenge
2418-
password can be left blank. The program will generate a key that is
2419-
passphrase protected; it will not accept a passphrase that is less
2420-
than four characters long. To remove the passphrase (as you must if
2421-
you want automatic start-up of the server), run the commands:
2422-
<programlisting>
2423-
openssl rsa -in privkey.pem -out server.key
2424-
rm privkey.pem
2425-
</programlisting>
2426-
Enter the old passphrase to unlock the existing key. Now do:
2409+
To create a simple self-signed certificate for the server, valid for 365
2410+
days, use the following <productname>OpenSSL</productname> command,
2411+
replacing <replaceable>dbhost.yourdomain.com</> with the
2412+
server's host name:
24272413
<programlisting>
2428-
openssl req -x509 -in server.req -text -key server.key -out server.crt
2414+
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
2415+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
24292416
</programlisting>
2430-
to turn the certificate into a self-signed certificate and to copy
2431-
the key and certificate to where the server will look for them.
2432-
Finally do:
2417+
Then do:
24332418
<programlisting>
24342419
chmod og-rwx server.key
24352420
</programlisting>
@@ -2440,14 +2425,86 @@ chmod og-rwx server.key
24402425
</para>
24412426

24422427
<para>
2443-
A self-signed certificate can be used for testing, but a certificate
2444-
signed by a certificate authority (<acronym>CA</>) (either one of the
2445-
global <acronym>CAs</> or a local one) should be used in production
2446-
so that clients can verify the server's identity. If all the clients
2447-
are local to the organization, using a local <acronym>CA</> is
2448-
recommended.
2428+
While a self-signed certificate can be used for testing, a certificate
2429+
signed by a certificate authority (<acronym>CA</>) (usually an
2430+
enterprise-wide root <acronym>CA</>) should be used in production.
24492431
</para>
24502432

2433+
<para>
2434+
To create a server certificate whose identity can be validated
2435+
by clients, first create a certificate signing request
2436+
(<acronym>CSR</>) and a public/private key file:
2437+
<programlisting>
2438+
openssl req -new -nodes -text -out root.csr \
2439+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2440+
chmod og-rwx root.key
2441+
</programlisting>
2442+
Then, sign the request with the key to create a root certificate
2443+
authority (using the default <productname>OpenSSL</>
2444+
configuration file location on <productname>Linux</>):
2445+
<programlisting>
2446+
openssl x509 -req -in root.csr -text -days 3650 \
2447+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2448+
-signkey root.key -out root.crt
2449+
</programlisting>
2450+
Finally, create a server certificate signed by the new root certificate
2451+
authority:
2452+
<programlisting>
2453+
openssl req -new -nodes -text -out server.csr \
2454+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2455+
chmod og-rwx server.key
2456+
2457+
openssl x509 -req -in server.csr -text -days 365 \
2458+
-CA root.crt -CAkey root.key -CAcreateserial \
2459+
-out server.crt
2460+
</programlisting>
2461+
<filename>server.crt</> and <filename>server.key</>
2462+
should be stored on the server, and <filename>root.crt</> should
2463+
be stored on the client so the client can verify that the server's leaf
2464+
certificate was signed by its trusted root certificate.
2465+
<filename>root.key</> should be stored offline for use in
2466+
creating future certificates.
2467+
</para>
2468+
2469+
<para>
2470+
It is also possible to create a chain of trust that includes
2471+
intermediate certificates:
2472+
<programlisting>
2473+
# root
2474+
openssl req -new -nodes -text -out root.csr \
2475+
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
2476+
chmod og-rwx root.key
2477+
openssl x509 -req -in root.csr -text -days 3650 \
2478+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2479+
-signkey root.key -out root.crt
2480+
2481+
# intermediate
2482+
openssl req -new -nodes -text -out intermediate.csr \
2483+
-keyout intermediate.key -subj "/CN=<replaceable>intermediate.yourdomain.c CEEF om</>"
2484+
chmod og-rwx intermediate.key
2485+
openssl x509 -req -in intermediate.csr -text -days 1825 \
2486+
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
2487+
-CA root.crt -CAkey root.key -CAcreateserial \
2488+
-out intermediate.crt
2489+
2490+
# leaf
2491+
openssl req -new -nodes -text -out server.csr \
2492+
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
2493+
chmod og-rwx server.key
2494+
openssl x509 -req -in server.csr -text -days 365 \
2495+
-CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
2496+
-out server.crt
2497+
</programlisting>
2498+
<filename>server.crt</> and
2499+
<filename>intermediate.crt</> should be concatenated
2500+
into a certificate file bundle and stored on the server.
2501+
<filename>server.key</> should also be stored on the server.
2502+
<filename>root.crt</> should be stored on the client so
2503+
the client can verify that the server's leaf certificate was signed
2504+
by a chain of certificates linked to its trusted root certificate.
2505+
<filename>root.key</> and <filename>intermediate.key</>
2506+
should be stored offline for use in creating future certificates.
2507+
</para>
24512508
</sect2>
24522509

24532510
</sect1>

0 commit comments

Comments
 (0)
0