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

Reply via email to