You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2014/05/09 10:03:16 UTC

[Bug 56508] New: Requiring SNI - SSLStrictSNIVHostCheck semantics

https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

            Bug ID: 56508
           Summary: Requiring SNI - SSLStrictSNIVHostCheck semantics
           Product: Apache httpd-2
           Version: 2.5-HEAD
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_ssl
          Assignee: bugs@httpd.apache.org
          Reporter: mnot@mnot.net

I've set up my sites (https://www.mnot.net/ and https://redbot.org/) to require
TLS SNI to be presented by clients; if they do not, I hard-fail.

I believe this is the most secure configuration for a site that uses SNI to
serve multiple origins, since it's the only way to assure that a client doesn't
get content for one origin when they think it's for another.

However, SSLStrictSNIVHostCheck is less than ideal for the task at hand.

1) When a client doesn't present SNI, the response status code is 403
Forbidden. A more appropriate status code would be 400 Bad Request (as it's
similar to a missing Host header), or perhaps a new status code (happy to help
there).

2) It doesn't appear possible to configure Apache to send back more than a
simple string in the body of the 403 response due to missing SNI. I've
configured like this:

    SSLStrictSNIVHostCheck on
    ErrorDocument 403 "TLS SNI Required."

    Listen 443

    <VirtualHost *:443>
        ...
        SSLStrictSNIVHostCheck on

      <Directory ...>
        ErrorDocument 403 default
        SSLRequireSSL
        SSLOptions +StrictRequire
      </Directory>
    </VirtualHost>

Note the re-defaulting of 403's ErrorDocument here. Configuring ErrorDocument
403 with a local file doesn't appear possible; if it is possible, the
configuration is pretty convoluted (I tried a number of approaches).

Much more ops-friendly would be to have a separate SSLStrictSNIErrorDocument
directive to allow people to present a page explaining to the end user that SNI
is required to access this site.

3) When multiple TLS hosts are served from the same IP:Port, SNI should be
required by default; not requiring it is a security risk, as explained above.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #3 from Mark Nottingham <mn...@mnot.net> ---
(In reply to Jeff Trawick from comment #2)
> There's nothing at all wrong with the request from a back-level client, so
> 400 is not appropriate.  The request is rejected because of policy, so 403
> seems appropriate.  If you have a response code in mind which you believe is
> more appropriate, bring it up on the dev@httpd list.

Yeah, I was looking at this again yesterday and had much the same thought. 

If I were to spec a new 4xx status code would Apache use it?

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #6 from Jeff Trawick <tr...@apache.org> ---
>RewriteCond %{SSL:SSL_TLS_SNI} =""
>RewriteRule ^ /no_sni_error_page.html

Nice trick (thanks!) though error prone...  No more "SSLStrictSNIVHostCheck
On", rules have to be active in every SSL-enabled vhost (since non-SNI client
will likely still get to the right vhost even though they handshaked with the
default vhost), rules have to be in proper order relative to existing rules for
the vhost, error page still has to be active everywhere, potentially under the
document root for each vhost.  (A global Alias directive didn't handle that for
me; dunno if it is the ordering between mod_alias and mod_rewrite or some error
that I need to debug.)

IMO it is simply wrong to pick a vhost from the Host header if SNI clients
aren't supposed to be supported (that leads to issues like needing to duplicate
 directives related to no-SNI error handling in all the SSL-enabled vhosts). 
But that has a migration impact in stable releases for those admins that
already got this to work.

A directive like SSLStrictSNIErrorDocument + SSLStrictSNIVHostCheck=On set in
global scope is a nice pragmatic solution.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #1 from Jeff Trawick <tr...@apache.org> ---
>Much more ops-friendly would be to have a separate SSLStrictSNIErrorDocument >directive to allow people to present a page explaining to the end user that SNI >is required to access this site.

Or have an optional parameter to SSLStrictSNIErrorDocument which has the same
sort of string as ErrorDocument.

I think that the ErrorDocument situation is worse than you mention, in that
overriding the 403 (or whatever) document to handle SNI is more widely
applicable than just lack of SNI since it can't be localized to a default vhost
which is used just to catch lack of SNI.  Why not?  Suppose you have a default
vhost to catch this error and a user with a backlevel client tries to visit
your site.  Initially the default vhost is used, then the desired vhost is
selected from the Host header, then mod_ssl fails the request due to
SSLStrictSNIVHostCheck.  When the 403 response is generated, the vhost used for
ErrorDocument is not the default vhost but instead the desired one.  So the
ErrorDocument configuration in the default vhost is not consulted.

My current hack to work around this:

Index: modules/ssl/ssl_engine_kernel.c
===================================================================
--- modules/ssl/ssl_engine_kernel.c    (revision 1608262)
+++ modules/ssl/ssl_engine_kernel.c    (working copy)
@@ -213,6 +213,11 @@
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02033)
                          "No hostname was provided via SNI for a name based"
                          " virtual host");
+            ap_custom_response(r, HTTP_FORBIDDEN,
+                               "<html><head><meta name=\"viewport\"
content=\"width=device-width, initial-scale=1\" />"
+                               "</head><body><h1>Secure communication
error</h1><p>Your browser does not support "
+                               "secure communication with this web site. 
Please use a modern browser such as "
+                               "Chrome or Firefox.</p></body>");
             return HTTP_FORBIDDEN;
         }
     }

When you tried

  ErrorDocument 403 /some/path

did you check where it was looking with strace or similar?  That path should be
taken relative to DocumentRoot OF THE VHOST SELECTED VIA HOST HEADER.

IMO the best bet here is to not select a vhost from the host header if SNI was
required and missing or mismatching, but I don't know if that is practical.

BTW, there are too many separate issues here (getting an error document
defined, concern about the use of 403, concern about security).  I'd at least
raise the security concern on dev@httpd after looking at past discussions
related to SSLStrictSNIVHostCheck.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #5 from Jeff Trawick <tr...@apache.org> ---
>If I were to spec a new 4xx status code would Apache use it?

IMO no need/not appropriate to have a new 4xx status code.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #4 from Kaspar Brand <as...@velox.ch> ---
Sounds like we would end up with an overengineered solution... mod_rewrite can
already do much of this:

  RewriteCond %{SSL:SSL_TLS_SNI} =""
  RewriteRule ^ /no_sni_error_page.html

(and instead of a static page, you could also handle this with a script,
setting whatever HTTP status you prefer)

(In reply to Mark Nottingham from comment #0)
> it's the only way to assure that a client
> doesn't get content for one origin when they think it's for another.

Well, the client has to verify the certificate in the first place, so you can
configure some kind of dummy ("snakeoil") certificate for the first vhost.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #7 from Kaspar Brand <as...@velox.ch> ---
(In reply to Jeff Trawick from comment #6)
> No more "SSLStrictSNIVHostCheck On",

Yes, since I always considered this to be an unnecessary/misdesigned directive
(see e.g.
https://mail-archives.apache.org/mod_mbox/httpd-dev/200903.mbox/%3C49D0EFF7.8030902@velox.ch%3E).
The primary purpose of SNI is allowing to present the proper certificate, not
enforcing access control, IMO.

> rules have to be active in every SSL-enabled vhost (since non-SNI
> client will likely still get to the right vhost even though they handshaked
> with the default vhost), rules have to be in proper order relative to
> existing rules for the vhost,

Relatively easy to achieve with "RewriteOptions InheritBefore" (or even
"RewriteOptions InheritdownBefore" with 2.4.8 and later), I would say.

> IMO it is simply wrong to pick a vhost from the Host header if SNI clients
> aren't supposed to be supported

Did you mean *non-*SNI clients? I can't follow you here otherwise.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #9 from Jeff Trawick <tr...@apache.org> ---
>>The primary purpose of SNI is allowing to present the proper certificate, not >>enforcing access control, IMO.

>I think that's a perverse way of describe the desire to lock out non-SNI clients >when relying on SNI to select the proper certificate.

I just realized that I didn't understand the big picture from your perspective,
which I think is:

Because there is no security-based reason to reject clients that don't support
SNI even if you are relying on name (SNI)-based SSL virtual hosts, then having
mod_ssl return FORBIDDEN (or any HTTP error) for this situation makes no sense,
and any solution should be outside of mod_ssl to the extent possible.

Is that correct?

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #8 from Jeff Trawick <tr...@apache.org> ---
>The primary purpose of SNI is allowing to present the proper certificate, not >enforcing access control, IMO.

I think that's a perverse way of describe the desire to lock out non-SNI
clients when relying on SNI to select the proper certificate.  (I mention only
the certificate selection issue as I will trust for the moment all previous
refutation of the security concerns about the satisfaction of all other
security/access-related SSL configuration in the vhost when the client gets to
the right vhost after first being handled by the wrong certificate/vhost.)

As an admin, I want clients for whom the proper certificate can't be selected
to use a different browser, not to continue to use my site with a negative
visual warning in the address bar.  Those users or unattended clients that do
proceed after a certificate error should get a message indicating how to fix
the problem, not proceed to use the site.

>Relatively easy to achieve with "RewriteOptions InheritBefore" (or even >"RewriteOptions InheritdownBefore" with 2.4.8 and later), I would say.

Thanks!

Aside from general concerns about the mod_rewrite requirements (mod_rewrite is
definitely error prone in general, has unexpected behavior between
configuration scopes, and many people are wise to avoid it), I still had
problems with the earlier recipe and avoiding having to put the error page
under DocumentRoot of every vhost.  I'll have to play with this further to sort
out any errors on my part vs. real limitations.

>Did you mean *non-*SNI clients? I can't follow you here otherwise.

Yes, of course :)

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #2 from Jeff Trawick <tr...@apache.org> ---
I had a thought on the response code issue you raised (403 vs. something else).

There's nothing at all wrong with the request from a back-level client, so 400
is not appropriate.  The request is rejected because of policy, so 403 seems
appropriate.  If you have a response code in mind which you believe is more
appropriate, bring it up on the dev@httpd list.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


[Bug 56508] Requiring SNI - SSLStrictSNIVHostCheck semantics

Posted by bu...@apache.org.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56508

--- Comment #10 from Kaspar Brand <as...@velox.ch> ---
(In reply to Jeff Trawick from comment #9)
> I just realized that I didn't understand the big picture from your
> perspective, which I think is:
> 
> Because there is no security-based reason to reject clients that don't
> support SNI even if you are relying on name (SNI)-based SSL virtual hosts,
> then having mod_ssl return FORBIDDEN (or any HTTP error) for this situation
> makes no sense,

Not necessarily, but I think (only) relying on the presence of a suitable SNI
extension in a ClientHello for deciding whether a client is allowed to "reach"
a certain vhost is too coarse.

The assumption that configuring a more restrictive setting like SSLCipherSuite
or SSLProtocol for a non-default vhost is automatically enforced when SNI is in
place isn't really true, unfortunately. In
ssl_callback_ServerNameIndication()/ssl_find_vhost(), we try to "fix" some
things, but essentially, OpenSSL's SSL_set_SSL_CTX() implementation is too
slim, IMO - see
https://rt.openssl.org/Ticket/Display.html?user=guest&pass=guest&id=3183 (and
https://issues.apache.org/bugzilla/show_bug.cgi?id=55707 for its implications
on mod_ssl).

> and any solution should be outside of mod_ssl to the extent possible.

I think it's much more safe if SSL-related access restrictions are spelled out
explicitly in the config, by means of "Require" directives (or "SSLRequire" in
earlier httpd versions). E.g.:

<RequireAll>
  Require expr -n %{SSL_TLS_SNI}
  Require expr %{SSL_PROTOCOL} in { "TLSv1.1", "TLSv1.2" }
  Require expr %{SSL_CIPHER_USEKEYSIZE} ge 128
</RequireAll>

... rather than having a single "SSLStrictSNIVHostCheck" flag. Returning 403 is
fine in this case, as is an appropriate ErrorDocument. But adding a per-module
and per-feature error handling directive ("SSLStrictSNIErrorDocument") feels
like the wrong approach to me.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org