From: Alan T. DeKok Date: Sun, 25 Jul 2021 13:31:57 +0000 (-0400) Subject: add Server Name Indication (SNI) to outbound RadSec connections X-Git-Tag: release_3_0_24~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27e699f4a6cf149c6cf4f88f3d2c9da61f7f573c;p=thirdparty%2Ffreeradius-server.git add Server Name Indication (SNI) to outbound RadSec connections to simplify TLS load balancing --- diff --git a/raddb/sites-available/tls b/raddb/sites-available/tls index 8c8e06ac4bf..12bf503ce3f 100644 --- a/raddb/sites-available/tls +++ b/raddb/sites-available/tls @@ -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 diff --git a/src/include/tls-h b/src/include/tls-h index c0d3ff00360..2a6683d471f 100644 --- a/src/include/tls-h +++ b/src/include/tls-h @@ -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 diff --git a/src/main/tls.c b/src/main/tls.c index 2ce16426458..8926fe75ed9 100644 --- a/src/main/tls.c +++ b/src/main/tls.c @@ -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 }; diff --git a/src/main/tls_listen.c b/src/main/tls_listen.c index 0c3a4cfcb3c..cad1353cd39 100644 --- a/src/main/tls_listen.c +++ b/src/main/tls_listen.c @@ -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; }