diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 932ee17b09..1946bb083d 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -886,6 +886,27 @@ include 'filename'
+
+ ssl_prefer_server_ciphers (bool)
+
+ ssl_prefer_server_ciphers> configuration parameter
+
+
+
+ Specifies whether to use the server's SSL cipher preferences, rather
+ than the client's. The default is true.
+
+
+
+ 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.
+
+
+
+
password_encryption (boolean)
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 573ad3e731..51f3b12bb9 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -112,6 +112,9 @@ static bool ssl_loaded_verify_locations = false;
/* GUC variable controlling SSL cipher list */
char *SSLCipherSuites = NULL;
+/* GUC variable: if false, prefer client ciphers */
+bool SSLPreferServerCiphers;
+
/* ------------------------------------------------------------ */
/* Hardcoded values */
/* ------------------------------------------------------------ */
@@ -854,6 +857,10 @@ initialize_SSL(void)
if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
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.
*/
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index cbf3186789..5c39de5a52 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -127,6 +127,7 @@ extern char *temp_tablespaces;
extern bool ignore_checksum_failure;
extern bool synchronize_seqscans;
extern char *SSLCipherSuites;
+extern bool SSLPreferServerCiphers;
#ifdef TRACE_SORT
extern bool trace_sort;
@@ -800,6 +801,15 @@ static struct config_bool ConfigureNamesBool[] =
false,
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,
gettext_noop("Forces synchronization of updates to disk."),
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 7a18e72750..a0f564bb9c 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -81,6 +81,7 @@
#ssl = off # (change requires restart)
#ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
# (change requires restart)
+#ssl_prefer_server_ciphers = on # (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)