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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers