On ons, 2012-02-08 at 09:16 +0100, Magnus Hagander wrote:
> > My best idea at the moment is that we should set these parameters to
> > empty by default, and make users point them to existing files if they
> > want to use that functionality. Comments?
> >
>
> +1. Anybody who actually cares about setting up security is likely not
> going to rely on defaults anyway - and is certainly going to review
> whatever they are. So there should be no big problem there.
Updated patch to reflect this.
*** i/doc/src/sgml/config.sgml
--- w/doc/src/sgml/config.sgml
***************
*** 668,673 **** SET ENABLE_SEQSCAN TO OFF;
--- 668,737 ----
</listitem>
</varlistentry>
+ <varlistentry id="guc-ssl-ca-file" xreflabel="ssl_ca_file">
+ <term><varname>ssl_ca_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_ca_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate
+ authority (CA). The default is empty, meaning no CA file is loaded,
+ and client certificate verification is not performed. (In previous
+ releases of PostgreSQL, the name of this file was hard-coded
+ as <filename>root.crt</filename>.) Relative paths are relative to the
+ data directory. This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-cert-file" xreflabel="ssl_cert_file">
+ <term><varname>ssl_cert_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_cert_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate.
+ The default is <filename>server.crt</filename>. Relative paths are
+ relative to the data directory. This parameter can only be set at
+ server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+ <term><varname>ssl_crl_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_crl_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate
+ revocation list (CRL). The default is empty, meaning no CRL file is
+ loaded. (In previous releases of PostgreSQL, the name of this file was
+ hard-coded as <filename>root.crl</filename>.) Relative paths are
+ relative to the data directory. This parameter can only be set at
+ server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-key-file" xreflabel="ssl_key_file">
+ <term><varname>ssl_key_file</varname> (<type>string</type>)</term>
+ <indexterm>
+ <primary><varname>ssl_key_file</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server private key.
+ The default is <filename>server.key</filename>. Relative paths are
+ relative to the data directory. This parameter can only be set at
+ server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-ssl-renegotiation-limit" xreflabel="ssl_renegotiation_limit">
<term><varname>ssl_renegotiation_limit</varname> (<type>integer</type>)</term>
<indexterm>
*** i/doc/src/sgml/runtime.sgml
--- w/doc/src/sgml/runtime.sgml
***************
*** 1831,1840 **** pg_dumpall -p 5432 | psql -d postgres -p 5433
SSL certificates and make sure that clients check the server's certificate.
To do that, the server
must be configured to accept only <literal>hostssl</> connections (<xref
! linkend="auth-pg-hba-conf">) and have SSL
! <filename>server.key</filename> (key) and
! <filename>server.crt</filename> (certificate) files (<xref
! linkend="ssl-tcp">). The TCP client must connect using
<literal>sslmode=verify-ca</> or
<literal>verify-full</> and have the appropriate root certificate
file installed (<xref linkend="libpq-connect">).
--- 1831,1838 ----
SSL certificates and make sure that clients check the server's certificate.
To do that, the server
must be configured to accept only <literal>hostssl</> connections (<xref
! linkend="auth-pg-hba-conf">) and have SSL key and certificate files
! (<xref linkend="ssl-tcp">). The TCP client must connect using
<literal>sslmode=verify-ca</> or
<literal>verify-full</> and have the appropriate root certificate
file installed (<xref linkend="libpq-connect">).
***************
*** 2053,2062 **** pg_dumpall -p 5432 | psql -d postgres -p 5433
</note>
<para>
! To start in <acronym>SSL</> mode, the files <filename>server.crt</>
! and <filename>server.key</> must exist in the server's data directory.
! These files should contain the server certificate and private key,
! respectively.
On Unix systems, the permissions on <filename>server.key</filename> must
disallow any access to world or group; achieve this by the command
<command>chmod 0600 server.key</command>.
--- 2051,2062 ----
</note>
<para>
! To start in <acronym>SSL</> mode, files containing the server certificate
! and private key must exist. By default, these files are expected to be
! named <filename>server.crt</> and <filename>server.key</>, respectively, in
! the server's data directory, but other names and locations can be specified
! using the configuration parameters <xref linkend="guc-ssl-cert-file">
! and <xref linkend="guc-ssl-key-file">.
On Unix systems, the permissions on <filename>server.key</filename> must
disallow any access to world or group; achieve this by the command
<command>chmod 0600 server.key</command>.
***************
*** 2144,2170 **** pg_dumpall -p 5432 | psql -d postgres -p 5433
<tbody>
<row>
! <entry><filename>$PGDATA/server.crt</></entry>
<entry>server certificate</entry>
<entry>sent to client to indicate server's identity</entry>
</row>
<row>
! <entry><filename>$PGDATA/server.key</></entry>
<entry>server private key</entry>
<entry>proves server certificate was sent by the owner; does not indicate
certificate owner is trustworthy</entry>
</row>
<row>
! <entry><filename>$PGDATA/root.crt</></entry>
<entry>trusted certificate authorities</entry>
<entry>checks that client certificate is
signed by a trusted certificate authority</entry>
</row>
<row>
! <entry><filename>$PGDATA/root.crl</></entry>
<entry>certificates revoked by certificate authorities</entry>
<entry>client certificate must not be on this list</entry>
</row>
--- 2144,2170 ----
<tbody>
<row>
! <entry><xref linkend="guc-ssl-cert-file"> (<filename>$PGDATA/server.crt</>)</entry>
<entry>server certificate</entry>
<entry>sent to client to indicate server's identity</entry>
</row>
<row>
! <entry><xref linkend="guc-ssl-key-file"> (<filename>$PGDATA/server.key</>)</entry>
<entry>server private key</entry>
<entry>proves server certificate was sent by the owner; does not indicate
certificate owner is trustworthy</entry>
</row>
<row>
! <entry><xref linkend="guc-ssl-ca-file"> (<filename>$PGDATA/root.crt</>)</entry>
<entry>trusted certificate authorities</entry>
<entry>checks that client certificate is
signed by a trusted certificate authority</entry>
</row>
<row>
! <entry><xref linkend="guc-ssl-crl-file"> (<filename>$PGDATA/root.crl</>)</entry>
<entry>certificates revoked by certificate authorities</entry>
<entry>client certificate must not be on this list</entry>
</row>
***************
*** 2176,2181 **** pg_dumpall -p 5432 | psql -d postgres -p 5433
--- 2176,2182 ----
<para>
The files <filename>server.key</>, <filename>server.crt</>,
<filename>root.crt</filename>, and <filename>root.crl</filename>
+ (or their configured alternative names)
are only examined during server start; so you must restart
the server for changes in them to take effect.
</para>
*** i/src/backend/libpq/be-secure.c
--- w/src/backend/libpq/be-secure.c
***************
*** 77,86 ****
#ifdef USE_SSL
! #define ROOT_CERT_FILE "root.crt"
! #define ROOT_CRL_FILE "root.crl"
! #define SERVER_CERT_FILE "server.crt"
! #define SERVER_PRIVATE_KEY_FILE "server.key"
static DH *load_dh_file(int keylength);
static DH *load_dh_buffer(const char *, size_t);
--- 77,86 ----
#ifdef USE_SSL
! char *ssl_cert_file;
! char *ssl_key_file;
! char *ssl_ca_file;
! char *ssl_crl_file;
static DH *load_dh_file(int keylength);
static DH *load_dh_buffer(const char *, size_t);
***************
*** 746,762 **** initialize_SSL(void)
* Load and verify server's certificate and private key
*/
if (SSL_CTX_use_certificate_chain_file(SSL_context,
! SERVER_CERT_FILE) != 1)
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not load server certificate file \"%s\": %s",
! SERVER_CERT_FILE, SSLerrmessage())));
! if (stat(SERVER_PRIVATE_KEY_FILE, &buf) != 0)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not access private key file \"%s\": %m",
! SERVER_PRIVATE_KEY_FILE)));
/*
* Require no public access to key file.
--- 746,762 ----
* Load and verify server's certificate and private key
*/
if (SSL_CTX_use_certificate_chain_file(SSL_context,
! ssl_cert_file) != 1)
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not load server certificate file \"%s\": %s",
! ssl_cert_file, SSLerrmessage())));
! if (stat(ssl_key_file, &buf) != 0)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not access private key file \"%s\": %m",
! ssl_key_file)));
/*
* Require no public access to key file.
***************
*** 771,786 **** initialize_SSL(void)
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("private key file \"%s\" has group or world access",
! SERVER_PRIVATE_KEY_FILE),
errdetail("Permissions should be u=rw (0600) or less.")));
#endif
if (SSL_CTX_use_PrivateKey_file(SSL_context,
! SERVER_PRIVATE_KEY_FILE,
SSL_FILETYPE_PEM) != 1)
ereport(FATAL,
(errmsg("could not load private key file \"%s\": %s",
! SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
if (SSL_CTX_check_private_key(SSL_context) != 1)
ereport(FATAL,
--- 771,786 ----
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("private key file \"%s\" has group or world access",
! ssl_key_file),
errdetail("Permissions should be u=rw (0600) or less.")));
#endif
if (SSL_CTX_use_PrivateKey_file(SSL_context,
! ssl_key_file,
SSL_FILETYPE_PEM) != 1)
ereport(FATAL,
(errmsg("could not load private key file \"%s\": %s",
! ssl_key_file, SSLerrmessage())));
if (SSL_CTX_check_private_key(SSL_context) != 1)
ereport(FATAL,
***************
*** 797,844 **** initialize_SSL(void)
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
/*
! * Attempt to load CA store, so we can verify client certificates if
! * needed.
*/
! ssl_loaded_verify_locations = false;
!
! if (access(ROOT_CERT_FILE, R_OK) != 0)
{
! /*
! * If root certificate file simply not found, don't log an error here,
! * because it's quite likely the user isn't planning on using client
! * certificates. If we can't access it for other reasons, it is an
! * error.
! */
! if (errno != ENOENT)
ereport(FATAL,
! (errmsg("could not access root certificate file \"%s\": %m",
! ROOT_CERT_FILE)));
}
! else if (SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL) != 1 ||
! (root_cert_list = SSL_load_client_CA_file(ROOT_CERT_FILE)) == NULL)
! {
! /*
! * File was there, but we could not load it. This means the file is
! * somehow broken, and we cannot do verification at all - so fail.
! */
! ereport(FATAL,
! (errmsg("could not load root certificate file \"%s\": %s",
! ROOT_CERT_FILE, SSLerrmessage())));
! }
! else
{
- /*----------
- * Load the Certificate Revocation List (CRL) if file exists.
- * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
- *----------
- */
X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
if (cvstore)
{
/* Set the flags to check against the complete CRL chain */
! if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) == 1)
{
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
#ifdef X509_V_FLAG_CRL_CHECK
--- 797,826 ----
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
/*
! * Load CA store, so we can verify client certificates if needed.
*/
! if (ssl_ca_file[0])
{
! if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
! (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
ereport(FATAL,
! (errmsg("could not load root certificate file \"%s\": %s",
! ssl_ca_file, SSLerrmessage())));
}
!
! /*----------
! * Load the Certificate Revocation List (CRL).
! * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
! *----------
! */
! if (ssl_crl_file[0])
{
X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
if (cvstore)
{
/* Set the flags to check against the complete CRL chain */
! if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
{
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
#ifdef X509_V_FLAG_CRL_CHECK
***************
*** 847,878 **** initialize_SSL(void)
#else
ereport(LOG,
(errmsg("SSL certificate revocation list file \"%s\" ignored",
! ROOT_CRL_FILE),
errdetail("SSL library does not support certificate revocation lists.")));
#endif
}
else
! {
! /* Not fatal - we do not require CRL */
! ereport(LOG,
! (errmsg("SSL certificate revocation list file \"%s\" not found, skipping: %s",
! ROOT_CRL_FILE, SSLerrmessage()),
! errdetail("Certificates will not be checked against revocation list.")));
! }
! /*
! * Always ask for SSL client cert, but don't fail if it's not
! * presented. We might fail such connections later, depending on
! * what we find in pg_hba.conf.
! */
! SSL_CTX_set_verify(SSL_context,
! (SSL_VERIFY_PEER |
! SSL_VERIFY_CLIENT_ONCE),
! verify_cb);
! /* Set flag to remember CA store is successfully loaded */
! ssl_loaded_verify_locations = true;
! }
/*
* Tell OpenSSL to send the list of root certs we trust to clients in
--- 829,859 ----
#else
ereport(LOG,
(errmsg("SSL certificate revocation list file \"%s\" ignored",
! ssl_crl_file),
errdetail("SSL library does not support certificate revocation lists.")));
#endif
}
else
! ereport(FATAL,
! (errmsg("could not load SSL certificate revocation list file \"%s\": %s",
! ssl_crl_file, SSLerrmessage())));
! }
! }
! if (ssl_ca_file[0])
! {
! /*
! * Always ask for SSL client cert, but don't fail if it's not
! * presented. We might fail such connections later, depending on
! * what we find in pg_hba.conf.
! */
! SSL_CTX_set_verify(SSL_context,
! (SSL_VERIFY_PEER |
! SSL_VERIFY_CLIENT_ONCE),
! verify_cb);
! /* Set flag to remember CA store is successfully loaded */
! ssl_loaded_verify_locations = true;
/*
* Tell OpenSSL to send the list of root certs we trust to clients in
*** i/src/backend/utils/misc/guc.c
--- w/src/backend/utils/misc/guc.c
***************
*** 39,44 ****
--- 39,45 ----
#include "funcapi.h"
#include "libpq/auth.h"
#include "libpq/be-fsstubs.h"
+ #include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
***************
*** 2961,2966 **** static struct config_string ConfigureNamesString[] =
--- 2962,3007 ----
},
{
+ {"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL server certificate file."),
+ NULL
+ },
+ &ssl_cert_file,
+ "server.crt",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL server private key file."),
+ NULL
+ },
+ &ssl_key_file,
+ "server.key",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL certificate authority file."),
+ NULL
+ },
+ &ssl_ca_file,
+ "",
+ NULL, NULL, NULL
+ },
+
+ {
+ {"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Location of the SSL certificate revocation list file."),
+ NULL
+ },
+ &ssl_crl_file,
+ "",
+ NULL, NULL, NULL
+ },
+
+ {
{"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR,
gettext_noop("Writes temporary statistics files to the specified directory."),
NULL,
*** i/src/backend/utils/misc/postgresql.conf.sample
--- w/src/backend/utils/misc/postgresql.conf.sample
***************
*** 81,86 ****
--- 81,90 ----
#ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
# (change requires restart)
#ssl_renegotiation_limit = 512MB # amount of data between renegotiations
+ #ssl_cert_file = 'server.crt' # (change requires restart)
+ #ssl_key_file = 'server.key' # (change requires restart)
+ #ssl_ca_file = '' # (change requires restart)
+ #ssl_crl_file = '' # (change requires restart)
#password_encryption = on
#db_user_namespace = off
*** i/src/include/libpq/libpq.h
--- w/src/include/libpq/libpq.h
***************
*** 70,75 **** extern void pq_endcopyout(bool errorAbort);
--- 70,80 ----
/*
* prototypes for functions in be-secure.c
*/
+ extern char *ssl_cert_file;
+ extern char *ssl_key_file;
+ extern char *ssl_ca_file;
+ extern char *ssl_crl_file;
+
extern int secure_initialize(void);
extern bool secure_loaded_verify_locations(void);
extern void secure_destroy(void);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers