A customer asked about including Server Name Indication (SNI) into the
SSL connection from the client, so they can use an SSL-aware proxy to
route connections. There was a thread a few years ago where this was
briefly discussed but no patch appeared.[0] I whipped up a quick patch
and it did seem to do the job, so I figured I'd share it here.
The question I had was whether this should be an optional behavior, or
conversely a behavior that can be turned off, or whether it should just
be turned on all the time.
Technically, it seems pretty harmless. It adds another field to the TLS
handshake, and if the server is not interested in it, it just gets ignored.
The Wikipedia page[1] discusses some privacy concerns in the context of
web browsing, but it seems there is no principled solution to those.
The relevant RFC[2] "recommends" that SNI is used for all applicable TLS
connections.
[0]:
https://www.postgresql.org/message-id/flat/CAPPwrB_tsOw8MtVaA_DFyOFRY2ohNdvMnLoA_JRr3yB67Rggmg%40mail.gmail.com
[1]: https://en.wikipedia.org/wiki/Server_Name_Indication
[2]: https://tools.ietf.org/html/rfc6066#section-3
From 3e4aae8b01a05fe78017659bb3be1942a7f1ccf5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Mon, 15 Feb 2021 14:11:27 +0100
Subject: [PATCH] Set SNI for SSL connections from the client
This allows an SNI-aware proxy to route connections.
---
src/interfaces/libpq/fe-secure-openssl.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/src/interfaces/libpq/fe-secure-openssl.c
b/src/interfaces/libpq/fe-secure-openssl.c
index 5b4a4157d5..6e439679e5 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1066,6 +1066,25 @@ initialize_SSL(PGconn *conn)
SSL_CTX_free(SSL_context);
SSL_context = NULL;
+ /*
+ * Set Server Name Indication (SNI), but not if it's a literal IP
address.
+ * (RFC 6066)
+ */
+ if (!((conn->pghost[0] >= '0' && conn->pghost[0] <= '9') ||
strchr(conn->pghost, ':')))
+ {
+ if (SSL_set_tlsext_host_name(conn->ssl, conn->pghost) != 1)
+ {
+ char *err = SSLerrmessage(ERR_get_error());
+
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("could
not set SSL Server Name Indication (SNI): %s\n"),
+ err);
+ SSLerrfree(err);
+ SSL_CTX_free(SSL_context);
+ return -1;
+ }
+ }
+
/*
* Read the SSL key. If a key is specified, treat it as an engine:key
* combination if there is colon present - we don't support files with
--
2.30.0