Blocking unknown hostnames for SSL/TLS connections

Valentin V. Bartenev vbart at
Thu Dec 3 21:44:02 UTC 2015

On Thursday 03 December 2015 11:41:51 Patrick O'Brien wrote:
> Hello,
> We're currently using nginx for SSL/TLS termination, which then
> proxies the request to a pair of internal pair of load balancers.
> Since the TLS handshake is performed before nginx is able to figure
> out what hostname is being requested, except in cases where SNI is
> used, it will accept any request for any hostname and pass it along
> to our internal load balancers. This puts us in a situation where
> internal resources are allowed to be exposed externally, although in
> a roundabout way.
> For example, our internal load balancers have a pool called "news",
> which is accessible via news, or and is intended
> to be internally accessible only. If you were to add our external IP
> address mapped to and told curl to ignore the
> invalid cert, nginx will proxy this request along to our internal
> load balancers and the internal service will happily respond. Here's
> a curl example of this hitting the internal healthcheck endpoint:
> ```
> curl -k
> alive
> ```
> Ideally this would be blocked at our ingress point, which is nginx.
> The only way around this that I've found so far is to inspect the
> $host variable in the server definition for the 443 blocks. The
> example below shows the check for the server block which is intended
> to respond to and only:
> ```
>   # if the request coming in doesn't match any of the hosts we know
>   # about, throw a 301 and rewrite to the default server.
>    if ($host !~ (^$|^$)) {
>      return 301;
>    }
> ```
> In our production environment we have a wildcard cert that covers as
> many as 6 externally available resources, so I am concerned with the
> performance hit of doing a check on every host.
> Is there a preferred method of dealing with an issue like this? I've
> read through the config pitfalls page on the[0] page,
> and the If Is Evil page[1], so I am pretty positive the solution
> above is very inefficient. The pitfalls page even talks about the
> preferred alternative to an if statement for hostname matching[2],
> but this does not appear to cover TLS connections. Is there any other
> documentation that talks about this or could be useful?

It's as simple as:


  server {
      listen 443 ssl default_server;
      return 301;

  server {
      listen 443 ssl;
      server_name ...;

      location / {
          proxy_pass ...;

wbr, Valentin V. Bartenev

More information about the nginx mailing list