SSL: Add configuration option to prefer server cipher order

By default, OpenSSL (and SSL/TLS in general) lets the client cipher
order take priority.  This is OK for browsers where the ciphers were
tuned, but few PostgreSQL client libraries make the cipher order
configurable.  So it makes sense to have the cipher order in
postgresql.conf take priority over client defaults.

This patch adds the setting "ssl_prefer_server_ciphers" that can be
turned on so that server cipher order is preferred.  Per discussion,
this now defaults to on.

From: Marko Kreen <markokr@gmail.com>
Reviewed-by: Adrian Klaver <adrian.klaver@gmail.com>
This commit is contained in:
Peter Eisentraut 2013-12-07 08:04:27 -05:00
parent 8fe3d90d34
commit ef3267523d
4 changed files with 39 additions and 0 deletions

View File

@ -886,6 +886,27 @@ include 'filename'
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-ssl-prefer-server-ciphers" xreflabel="ssl_prefer_server_ciphers">
<term><varname>ssl_prefer_server_ciphers</varname> (<type>bool</type>)</term>
<indexterm>
<primary><varname>ssl_prefer_server_ciphers</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies whether to use the server's SSL cipher preferences, rather
than the client's. The default is true.
</para>
<para>
Older PostgreSQL versions do not have this setting and always use the
client's preferences. This setting is mainly for backward
compatibility with those versions. Using the server's preferences is
usually better because it is more likely that the server is appropriately
configured.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-password-encryption" xreflabel="password_encryption"> <varlistentry id="guc-password-encryption" xreflabel="password_encryption">
<term><varname>password_encryption</varname> (<type>boolean</type>)</term> <term><varname>password_encryption</varname> (<type>boolean</type>)</term>
<indexterm> <indexterm>

View File

@ -112,6 +112,9 @@ static bool ssl_loaded_verify_locations = false;
/* GUC variable controlling SSL cipher list */ /* GUC variable controlling SSL cipher list */
char *SSLCipherSuites = NULL; char *SSLCipherSuites = NULL;
/* GUC variable: if false, prefer client ciphers */
bool SSLPreferServerCiphers;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* Hardcoded values */ /* Hardcoded values */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -854,6 +857,10 @@ initialize_SSL(void)
if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1) if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
elog(FATAL, "could not set the cipher list (no valid ciphers available)"); elog(FATAL, "could not set the cipher list (no valid ciphers available)");
/* Let server choose order */
if (SSLPreferServerCiphers)
SSL_CTX_set_options(SSL_context, SSL_OP_CIPHER_SERVER_PREFERENCE);
/* /*
* Load CA store, so we can verify client certificates if needed. * Load CA store, so we can verify client certificates if needed.
*/ */

View File

@ -127,6 +127,7 @@ extern char *temp_tablespaces;
extern bool ignore_checksum_failure; extern bool ignore_checksum_failure;
extern bool synchronize_seqscans; extern bool synchronize_seqscans;
extern char *SSLCipherSuites; extern char *SSLCipherSuites;
extern bool SSLPreferServerCiphers;
#ifdef TRACE_SORT #ifdef TRACE_SORT
extern bool trace_sort; extern bool trace_sort;
@ -800,6 +801,15 @@ static struct config_bool ConfigureNamesBool[] =
false, false,
check_ssl, NULL, NULL check_ssl, NULL, NULL
}, },
{
{"ssl_prefer_server_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
gettext_noop("Give priority to server ciphersuite order."),
NULL
},
&SSLPreferServerCiphers,
true,
NULL, NULL, NULL
},
{ {
{"fsync", PGC_SIGHUP, WAL_SETTINGS, {"fsync", PGC_SIGHUP, WAL_SETTINGS,
gettext_noop("Forces synchronization of updates to disk."), gettext_noop("Forces synchronization of updates to disk."),

View File

@ -81,6 +81,7 @@
#ssl = off # (change requires restart) #ssl = off # (change requires restart)
#ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers #ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
# (change requires restart) # (change requires restart)
#ssl_prefer_server_ciphers = on # (change requires restart)
#ssl_renegotiation_limit = 512MB # amount of data between renegotiations #ssl_renegotiation_limit = 512MB # amount of data between renegotiations
#ssl_cert_file = 'server.crt' # (change requires restart) #ssl_cert_file = 'server.crt' # (change requires restart)
#ssl_key_file = 'server.key' # (change requires restart) #ssl_key_file = 'server.key' # (change requires restart)