]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add Server Name Indication (SNI) to outbound RadSec connections
authorAlan T. DeKok <aland@freeradius.org>
Sun, 25 Jul 2021 13:31:57 +0000 (09:31 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 25 Jul 2021 13:31:57 +0000 (09:31 -0400)
to simplify TLS load balancing

raddb/sites-available/tls
src/include/tls-h
src/main/tls.c
src/main/tls_listen.c

index 8c8e06ac4bfff70790b2ff829891cdea37500e60..12bf503ce3f87f17b19a53328c1de59f3250d380 100644 (file)
@@ -475,6 +475,23 @@ home_server tls {
        status_check = none
 
        tls {
+               #
+               #  Similarly to HTTP, the client can use Server Name
+               #  Indication to inform the RadSec server of which
+               #  domain it is requesting.  This selection allows
+               #  multiple sites to exist at the same IP address.
+               #
+               #  For example, and identity provider could host
+               #  multiple sites, but present itself with one public
+               #  IP address.
+               #
+               #  SNI also permits the use of a load balancer such as
+               #  haproxy.  That load balancer can terminate the TLS
+               #  connection, and then use SNI to route the
+               #  underlying RADIUS TCP traffic to a particular host.
+               #
+       #       hostname = "example.com"
+
                private_key_password = whatever
                private_key_file = ${certdir}/client.pem
 
index c0d3ff00360aa7d54a0b1c3a912a4b3d2cbd8c93..2a6683d471f2e6d4f425003a8487ec447c5a305e 100644 (file)
@@ -434,6 +434,8 @@ struct fr_tls_server_conf_t {
 
        char const      *realm_dir;
        fr_hash_table_t *realms;
+
+       char const      *client_hostname;
 };
 
 #ifdef __cplusplus
index 2ce164264588bf8a8c0f421ec99cfe285c1fcf09..8926fe75ed942183515db8bf512ec64468495459 100644 (file)
@@ -1638,6 +1638,8 @@ static CONF_PARSER tls_client_config[] = {
 #endif
        },
 
+       { "hostname", FR_CONF_OFFSET(PW_TYPE_STRING, fr_tls_server_conf_t, client_hostname), NULL },
+
        CONF_PARSER_TERMINATOR
 };
 
index 0c3a4cfcb3c346a6d670096802ac6697610b23cd..cad1353cd3964f8b1fd0c4379f819af4ebfd1bcd 100644 (file)
@@ -177,6 +177,18 @@ static int tls_socket_recv(rad_listen_t *listener)
                SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_TALLOC, sock);
                sock->ssn->quick_session_tickets = true; /* we don't have inner-tunnel authentication */
 
+               /*
+                *      Set SNI, if configured.
+                *
+                *      The OpenSSL API says the filename is "char
+                *      const *", but some versions have it as "void
+                *      *", without the "const".  So we un-const it
+                *      here through various C magic.
+                */
+               if (listener->tls->client_hostname) {
+                       (void) SSL_set_tlsext_host_name(sock->ssn->ssl, (void *) (uintptr_t) listener->tls->client_hostname);
+               }
+
                doing_init = true;
        }