mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
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
This commit is contained in:
parent
8a71ee6288
commit
d516aea659
@ -7333,17 +7333,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
|
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
|
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,
|
IP address) without the client knowing. In order to prevent spoofing,
|
||||||
<acronym>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 (<acronym>CA</>) certificate on one
|
||||||
|
computer and a leaf certificate <emphasis>signed</> by the
|
||||||
|
root certificate on another computer. It is also possible to use an
|
||||||
|
<quote>intermediate</> certificate which is signed by the root
|
||||||
|
certificate and signs leaf certificates.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
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.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
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 <literal>sslmode</> is set to <literal>verify-ca</>,
|
If the parameter <literal>sslmode</> is set to <literal>verify-ca</>,
|
||||||
libpq will verify that the server is trustworthy by checking the
|
libpq will verify that the server is trustworthy by checking the
|
||||||
certificate chain up to a trusted certificate authority
|
certificate chain up to the root certificate stored on the client.
|
||||||
(<acronym>CA</>). If <literal>sslmode</> is set to <literal>verify-full</>,
|
If <literal>sslmode</> is set to <literal>verify-full</>,
|
||||||
libpq will <emphasis>also</> verify that the server host name matches its
|
libpq will <emphasis>also</> verify that the server host
|
||||||
certificate. The SSL connection will fail if the server certificate cannot
|
name matches the name stored in the server certificate. The
|
||||||
be verified. <literal>verify-full</> is recommended in most
|
SSL connection will fail if the server certificate cannot be
|
||||||
|
verified. <literal>verify-full</> is recommended in most
|
||||||
security-sensitive environments.
|
security-sensitive environments.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -7360,13 +7380,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To allow server certificate verification, the certificate(s) of one or more
|
To allow server certificate verification, one or more root certificates
|
||||||
trusted <acronym>CA</>s must be
|
must be placed in the file <filename>~/.postgresql/root.crt</>
|
||||||
placed in the file <filename>~/.postgresql/root.crt</> in the user's home
|
in the user's home directory. (On Microsoft Windows the file is named
|
||||||
directory. If intermediate <acronym>CA</>s appear in
|
<filename>%APPDATA%\postgresql\root.crt</>.) Intermediate
|
||||||
<filename>root.crt</filename>, the file must also contain certificate
|
certificates should also be added to the file if they are needed to link
|
||||||
chains to their root <acronym>CA</>s. (On Microsoft Windows the file is named
|
the certificate chain sent by the server to the root certificates
|
||||||
<filename>%APPDATA%\postgresql\root.crt</filename>.)
|
stored on the client.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -7400,11 +7420,12 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
|
|||||||
<title>Client Certificates</title>
|
<title>Client Certificates</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If the server requests a trusted client certificate,
|
If the server attempts to verify the identity of the
|
||||||
<application>libpq</application> will send the certificate stored in
|
client by requesting the client's leaf certificate,
|
||||||
|
<application>libpq</> will send the certificates stored in
|
||||||
file <filename>~/.postgresql/postgresql.crt</> in the user's home
|
file <filename>~/.postgresql/postgresql.crt</> in the user's home
|
||||||
directory. The certificate must be signed by one of the certificate
|
directory. The certificates must chain to the root certificate trusted
|
||||||
authorities (<acronym>CA</acronym>) trusted by the server. A matching
|
by the server. A matching
|
||||||
private key file <filename>~/.postgresql/postgresql.key</> must also
|
private key file <filename>~/.postgresql/postgresql.key</> must also
|
||||||
be present. The private
|
be present. The private
|
||||||
key file must not allow any access to world or group; achieve this by the
|
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=*)
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In some cases, the client certificate might be signed by an
|
The first certificate in <filename>postgresql.crt</> must be the
|
||||||
<quote>intermediate</> certificate authority, rather than one that is
|
client's certificate because it must match the client's private key.
|
||||||
directly trusted by the server. To use such a certificate, append the
|
<quote>Intermediate</> certificates can be optionally appended
|
||||||
certificate of the signing authority to the <filename>postgresql.crt</>
|
to the file — doing so avoids requiring storage of intermediate
|
||||||
file, then its parent authority's certificate, and so on up to a certificate
|
certificates on the server's <filename>root.crt</filename> file.
|
||||||
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
|
|
||||||
the server, i.e. signed by a certificate in the server's
|
|
||||||
<filename>root.crt</filename> file.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Note that the client's <filename>~/.postgresql/root.crt</> lists the top-level CAs
|
For instructions on creating certificates, see <xref
|
||||||
that are considered trusted for signing server certificates. In principle it need
|
linkend="ssl-certificate-creation">.
|
||||||
not list the CA that signed the client's certificate, though in most cases
|
|
||||||
that CA would also be trusted for server certificates.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="libpq-ssl-protection">
|
<sect2 id="libpq-ssl-protection">
|
||||||
|
@ -2276,40 +2276,46 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In some cases, the server certificate might be signed by an
|
The first certificate in <filename>server.crt</> must be the
|
||||||
<quote>intermediate</> certificate authority, rather than one that is
|
server's certificate because it must match the server's private key.
|
||||||
directly trusted by clients. To use such a certificate, append the
|
The certificates of <quote>intermediate</> certificate authorities
|
||||||
certificate of the signing authority to the <filename>server.crt</> file,
|
can also be appended to the file. Doing this avoids the necessity of
|
||||||
then its parent authority's certificate, and so on up to a certificate
|
storing intermediate certificates on clients, assuming the root and
|
||||||
authority, <quote>root</> or <quote>intermediate</>, that is trusted by
|
intermediate certificates were created with <literal>v3_ca</>
|
||||||
clients, i.e. signed by a certificate in the clients'
|
extensions. This allows easier expiration of intermediate certificates.
|
||||||
<filename>root.crt</filename> files.
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is not necessary to add the root certificate to
|
||||||
|
<filename>server.crt</>. Instead, clients must have the root
|
||||||
|
certificate of the server's certificate chain.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2 id="ssl-client-certificates">
|
<sect2 id="ssl-client-certificates">
|
||||||
<title>Using Client Certificates</title>
|
<title>Using Client Certificates</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To require the client to supply a trusted certificate, place
|
To require the client to supply a trusted certificate,
|
||||||
certificates of the certificate authorities (<acronym>CA</acronym>s)
|
place certificates of the root certificate authorities
|
||||||
you trust in the file <filename>root.crt</filename> in the data
|
(<acronym>CA</>s) you trust in a file in the data
|
||||||
directory, set the parameter <xref linkend="guc-ssl-ca-file"> in
|
directory, set the parameter <xref linkend="guc-ssl-ca-file"> in
|
||||||
<filename>postgresql.conf</filename> to <literal>root.crt</literal>,
|
<filename>postgresql.conf</> to the new file name, and add the
|
||||||
and add the authentication option <literal>clientcert=1</literal> to the
|
authentication option <literal>clientcert=1</> to the appropriate
|
||||||
appropriate <literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
|
<literal>hostssl</> line(s) in <filename>pg_hba.conf</>.
|
||||||
A certificate will then be requested from the client during
|
A certificate will then be requested from the client during SSL
|
||||||
SSL connection startup. (See <xref linkend="libpq-ssl"> for a
|
connection startup. (See <xref linkend="libpq-ssl"> for a description
|
||||||
description of how to set up certificates on the client.) The server will
|
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
|
verify that the client's certificate is signed by one of the trusted
|
||||||
certificate authorities.
|
certificate authorities.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If intermediate <acronym>CA</>s appear in
|
Intermediate certificates that chain up to existing root certificates
|
||||||
<filename>root.crt</filename>, the file must also contain certificate
|
can also appear in the file <filename>root.crt</filename> if
|
||||||
chains to their root <acronym>CA</>s. Certificate Revocation List
|
you wish to avoid storing them on clients (assuming the root and
|
||||||
(CRL) entries
|
intermediate certificates were created with <literal>v3_ca</>
|
||||||
are also checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
|
extensions). Certificate Revocation List (CRL) entries are also
|
||||||
|
checked if the parameter <xref linkend="guc-ssl-crl-file"> is set.
|
||||||
<!-- If this URL changes replace it with a URL to www.archive.org. -->
|
<!-- If this URL changes replace it with a URL to www.archive.org. -->
|
||||||
(See <ulink
|
(See <ulink
|
||||||
url="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html"></>
|
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
|
|||||||
it will not insist that a client certificate be presented.
|
it will not insist that a client certificate be presented.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Note that the server's <filename>root.crt</filename> 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.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
If you are setting up client certificates, you may wish to use
|
If you are setting up client certificates, you may wish to use
|
||||||
the <literal>cert</> authentication method, so that the certificates
|
the <literal>cert</> authentication method, so that the certificates
|
||||||
@ -2405,31 +2403,18 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
|
|||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="ssl-certificate-creation">
|
<sect2 id="ssl-certificate-creation">
|
||||||
<title>Creating a Self-signed Certificate</title>
|
<title>Creating Certificates</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To create a quick self-signed certificate for the server, use the
|
To create a simple self-signed certificate for the server, valid for 365
|
||||||
following <productname>OpenSSL</productname> command:
|
days, use the following <productname>OpenSSL</productname> command,
|
||||||
|
replacing <replaceable>dbhost.yourdomain.com</> with the
|
||||||
|
server's host name:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
openssl req -new -text -out server.req
|
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
|
||||||
|
-keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</>"
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Fill out the information that <application>openssl</> asks for. Make sure
|
Then do:
|
||||||
you enter the local host name as <quote>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:
|
|
||||||
<programlisting>
|
|
||||||
openssl rsa -in privkey.pem -out server.key
|
|
||||||
rm privkey.pem
|
|
||||||
</programlisting>
|
|
||||||
Enter the old passphrase to unlock the existing key. Now do:
|
|
||||||
<programlisting>
|
|
||||||
openssl req -x509 -in server.req -text -key server.key -out server.crt
|
|
||||||
</programlisting>
|
|
||||||
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:
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
chmod og-rwx server.key
|
chmod og-rwx server.key
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@ -2440,14 +2425,86 @@ chmod og-rwx server.key
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A self-signed certificate can be used for testing, but a certificate
|
While a self-signed certificate can be used for testing, a certificate
|
||||||
signed by a certificate authority (<acronym>CA</>) (either one of the
|
signed by a certificate authority (<acronym>CA</>) (usually an
|
||||||
global <acronym>CAs</> or a local one) should be used in production
|
enterprise-wide root <acronym>CA</>) 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 <acronym>CA</> is
|
|
||||||
recommended.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To create a server certificate whose identity can be validated
|
||||||
|
by clients, first create a certificate signing request
|
||||||
|
(<acronym>CSR</>) and a public/private key file:
|
||||||
|
<programlisting>
|
||||||
|
openssl req -new -nodes -text -out root.csr \
|
||||||
|
-keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</>"
|
||||||
|
chmod og-rwx root.key
|
||||||
|
</programlisting>
|
||||||
|
Then, sign the request with the key to create a root certificate
|
||||||
|
authority (using the default <productname>OpenSSL</>
|
||||||
|
configuration file location on <productname>Linux</>):
|
||||||
|
<programlisting>
|
||||||
|
openssl x509 -req -in root.csr -text -days 3650 \
|
||||||
|
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
|
||||||
|
-signkey root.key -out root.crt
|
||||||
|
</programlisting>
|
||||||
|
Finally, create a server certificate signed by the new root certificate
|
||||||
|
authority:
|
||||||
|
<programlisting>
|
||||||
|
openssl req -new -nodes -text -out server.csr \
|
||||||
|
-keyout server.key -subj "/CN=<replaceable>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
|
||||||
|
</programlisting>
|
||||||
|
<filename>server.crt</> and <filename>server.key</>
|
||||||
|
should be stored on the server, and <filename>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.
|
||||||
|
<filename>root.key</> should be stored offline for use in
|
||||||
|
creating future certificates.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is also possible to create a chain of trust that includes
|
||||||
|
intermediate certificates:
|
||||||
|
<programlisting>
|
||||||
|
# root
|
||||||
|
openssl req -new -nodes -text -out root.csr \
|
||||||
|
-keyout root.key -subj "/CN=<replaceable>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=<replaceable>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=<replaceable>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
|
||||||
|
</programlisting>
|
||||||
|
<filename>server.crt</> and
|
||||||
|
<filename>intermediate.crt</> should be concatenated
|
||||||
|
into a certificate file bundle and stored on the server.
|
||||||
|
<filename>server.key</> should also be stored on the server.
|
||||||
|
<filename>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.
|
||||||
|
<filename>root.key</> and <filename>intermediate.key</>
|
||||||
|
should be stored offline for use in creating future certificates.
|
||||||
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user