diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index fe09b7bdfd..dfaea3b865 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -1353,6 +1353,37 @@ SSLRenegBufferSize 262144 + +SSLStrictSNIVHostCheck +Whether to allow non SNI clients to access a name based virtual +host. + +SSLStrictSNIVHostCheck on|off +SSLStrictSNIVHostCheck off +server config +virtual host + + +

+This directive sets whether a non SNI client is allowed to access a name based +virtual host. If set to on in the non default name based virtual +host, non SNI clients are not allowed to access this particular virtual host. +If set to on in the default name based virtual host, non SNI +clients are not allowed to access any name based virtual host belonging to +this IP / port combination. +

+ +

+This option is only available if httpd was compiled against an SNI capable +version of OpenSSL. +

+ +Example +SSLStrictSNIVHostCheck on + +
+
+ SSLProxyMachineCertificatePath Directory of PEM-encoded client certificates and keys to be used by the proxy diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 98dfd4d545..fb5ded244f 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -129,6 +129,10 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(LogLevelDebugDump, TAKE1, "Include I/O Dump when LogLevel is set to Debug " "([ None (default) | IO (not bytes) | Bytes ])") +#ifndef OPENSSL_NO_TLSEXT + SSL_CMD_SRV(StrictSNIVHostCheck, FLAG, + "Strict SNI virtual host checking") +#endif /* * Proxy configuration for remote SSL connections diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index 41118c5da9..70bbf758cf 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -175,6 +175,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) sc->ssl_log_level = SSL_LOG_UNSET; sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET; sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET; +#ifndef OPENSSL_NO_TLSEXT + sc->strict_sni_vhost_check = SSL_ENABLED_UNSET; +#endif modssl_ctx_init_proxy(sc, p); @@ -270,6 +273,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) cfgMerge(ssl_log_level, SSL_LOG_UNSET); cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET); cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET); +#ifndef OPENSSL_NO_TLSEXT + cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET); +#endif modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); @@ -1440,6 +1446,17 @@ const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag) return NULL; } +#ifndef OPENSSL_NO_TLSEXT +const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + + sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; + + return NULL; +} +#endif + void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) { if (!ap_exists_config_define("DUMP_CERTS")) { diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index e2ab5ff936..b12850034e 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -186,10 +186,16 @@ int ssl_hook_ReadReq(request_rec *r) return HTTP_BAD_REQUEST; } } - else if (r->connection->vhost_lookup_data) { + else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE) + || (mySrvConfig(sslconn->server))->strict_sni_vhost_check + == SSL_ENABLED_TRUE) + && r->connection->vhost_lookup_data) { /* * We are using a name based configuration here, but no hostname was - * provided via SNI. Don't allow that. + * provided via SNI. Don't allow that if are requested to do strict + * checking. Check wether this strict checking was setup either in the + * server config we used for handshaking or in our current server. + * This should avoid insecure configuration by accident. */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "No hostname was provided via SNI for a name based" diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index f9f82b82d1..840230a3fc 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -479,6 +479,9 @@ struct SSLSrvConfigRec { ssl_log_level_e ssl_log_level; ssl_enabled_t proxy_ssl_check_peer_expire; ssl_enabled_t proxy_ssl_check_peer_cn; +#ifndef OPENSSL_NO_TLSEXT + ssl_enabled_t strict_sni_vhost_check; +#endif }; /** @@ -544,6 +547,9 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLLogLevelDebugDump(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); +#ifndef OPENSSL_NO_TLSEXT +const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); +#endif const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);