diff --git a/src/backend/distributed/sql/citus--7.0-1.sql b/src/backend/distributed/sql/citus--7.0-1.sql index a0cdae839..0af4a046a 100644 --- a/src/backend/distributed/sql/citus--7.0-1.sql +++ b/src/backend/distributed/sql/citus--7.0-1.sql @@ -5,10 +5,21 @@ CREATE SCHEMA citus; --- Enable SSL to encrypt all trafic by default +-- Enable SSL to encrypt all traffic by default --- create temporary UDF that has the power to change settings within postgres and drop it --- after ssl has been setup. +-- create temporary UDF that has the power to change settings within postgres +-- and drop it after ssl has been setup. + +-- This was placed here in version 8.1.0. This means that this code has not +-- been executed for clusters created before 8.1.0. This is a somewhat hacky +-- way to detect that we can safely set sslmode=require for citus.node_conninfo +-- in the upgrade script to 8.1.0. We will do so only if ssl is enabled before +-- running that upgrade script. For upgrades where this is not the case this is +-- not safe, since that probably means not all nodes have SSL setup yet. In +-- that case we would get connection errors with "sslmode=require" during the +-- cluster upgrade. We will later setup SSL anyway in the upgrade script for +-- Citus 9.2.3, but by that time citus.node_conninfo will contain +-- "sslmode=prefer", so upgrades are safe. CREATE FUNCTION citus_setup_ssl() RETURNS void LANGUAGE C STRICT diff --git a/src/backend/distributed/sql/citus--9.2-2--9.2-3.sql b/src/backend/distributed/sql/citus--9.2-2--9.2-3.sql new file mode 100644 index 000000000..addc434fb --- /dev/null +++ b/src/backend/distributed/sql/citus--9.2-2--9.2-3.sql @@ -0,0 +1,37 @@ +-- Enable SSL to encrypt all traffic by default + +-- create temporary UDF that has the power to change settings within postgres and drop it +-- after ssl has been setup. + +-- This exact same function has already been run for clusters that were +-- originally created with Citus 8.1.0 or later. However, this is not the case +-- for clusters originally created with a version before 8.1.0. +-- That's why we run it again here. If SSL is already set up this is a no-op, +-- else this sets up self signed certificates and enables SSL. + +-- There will still be a difference between clusters from before 8.1.0 and +-- clusters after 8.1.0. This difference is that for old clusters +-- citus.node_conninfo will be "sslmode=prefer", and for new clusters it will +-- be "sslmode=require". +-- The reason for this difference is that using "sslmode=require" does not +-- allow connections to nodes without SSL at all. So this does not work with +-- clusters where some nodes don't have SSL enabled. A situation like that will +-- happen during rolling upgrades, where part of the cluster has Citus version +-- lower than 8.1.0 and part of it has a higher version. In that case there +-- will be unwanted downtime of the cluster until all nodes have been upgraded. +CREATE FUNCTION citus_setup_ssl() + RETURNS void + LANGUAGE C STRICT + AS 'MODULE_PATHNAME', $$citus_setup_ssl$$; + +DO LANGUAGE plpgsql +$$ +BEGIN + -- setup ssl when postgres is OpenSSL-enabled + IF current_setting('ssl_ciphers') != 'none' THEN + PERFORM citus_setup_ssl(); + END IF; +END; +$$; + +DROP FUNCTION citus_setup_ssl(); diff --git a/src/backend/distributed/sql/citus--9.2-2--9.3-1.sql b/src/backend/distributed/sql/citus--9.2-3--9.3-1.sql similarity index 100% rename from src/backend/distributed/sql/citus--9.2-2--9.3-1.sql rename to src/backend/distributed/sql/citus--9.2-3--9.3-1.sql diff --git a/src/backend/distributed/utils/enable_ssl.c b/src/backend/distributed/utils/enable_ssl.c index f21857004..955340c68 100644 --- a/src/backend/distributed/utils/enable_ssl.c +++ b/src/backend/distributed/utils/enable_ssl.c @@ -49,7 +49,6 @@ static void GloballyReloadConfig(void); #ifdef USE_SSL /* forward declaration of functions used when compiled with ssl */ -static bool ShouldUseAutoSSL(void); static bool CreateCertificatesWhenNeeded(void); static EVP_PKEY * GeneratePrivateKey(void); static X509 * CreateCertificate(EVP_PKEY *privateKey); @@ -73,10 +72,12 @@ citus_setup_ssl(PG_FUNCTION_ARGS) ereport(WARNING, (errmsg("can not setup ssl on postgres that is not compiled with " "ssl support"))); #else /* USE_SSL */ - if (!EnableSSL && ShouldUseAutoSSL()) + if (!EnableSSL) { + /* Only enable it when it's not already on */ + ereport(LOG, (errmsg("citus extension created on postgres without ssl enabled, " - "turning it on during creation of the extension"))); + "turning it on now"))); /* execute the alter system statement to enable ssl on within postgres */ Node *enableSSLParseTree = ParseTreeNode(ENABLE_SSL_QUERY); @@ -85,19 +86,20 @@ citus_setup_ssl(PG_FUNCTION_ARGS) if (strcmp(SSLCipherSuites, POSTGRES_DEFAULT_SSL_CIPHERS) == 0) { /* - * postgres default cipher suite is configured, these allow TSL 1 and TLS 1.1, - * citus will upgrade to TLS1.2+HIGH and above. + * postgres default cipher suite is configured, these allow TSL 1 + * and TLS 1.1, citus will upgrade to TLS1.2+HIGH and above. */ Node *citusSSLCiphersParseTree = ParseTreeNode(SET_CITUS_SSL_CIPHERS_QUERY); AlterSystemSetConfigFile((AlterSystemStmt *) citusSSLCiphersParseTree); } /* - * ssl=on requires that a key and certificate are present, since we have - * enabled ssl mode here chances are the user didn't install credentials already. + * ssl=on requires that a server private key and server certificate are + * present. Since we have enabled ssl mode here, chances are the user + * didn't install credentials already. * - * This function will check if they are available and if not it will generate a - * self singed certificate. + * This function will check if they are available and if not it will + * generate a private key and a matching self signed certificate. */ CreateCertificatesWhenNeeded(); @@ -179,27 +181,6 @@ GloballyReloadConfig() #ifdef USE_SSL -/* - * ShouldUseAutoSSL checks if citus should enable ssl based on the connection settings it - * uses for outward connections. When the outward connection is configured to require ssl - * it assumes the other nodes in the network have the same setting and therefor it will - * automatically enable ssl during installation. - */ -static bool -ShouldUseAutoSSL(void) -{ - const char *sslmode = NULL; - sslmode = GetConnParam("sslmode"); - - if (sslmode != NULL && strcmp(sslmode, "require") == 0) - { - return true; - } - - return false; -} - - /* * CreateCertificatesWhenNeeded checks if the certificates exists. When they don't exist * they will be created. The return value tells whether or not new certificates have been