Host header and SSL

Hi,

in my setup Nginx is a load balancer to many different services, some
of them are using SSL (so Nginx is also SSL terminator in this case).
I have many different IPs and for every IP it happen to be more than
one domain (of course only in non-SSL situation).

So I am using virtual hosts heavily with http and since my backends
rely on Host header from user (it has to be correct) I have catch-all
section for not matching server_names. Something like this

… (many different server sections with different server_names) …

server {
listen IP1:80 default_server;
listen IP2:80 default_server;
serrver_name _;
return 444;
}

But this technique simply does not work for SSL. As far I understand
correctly there are two techniques to cope with my problem (to prevent
https request with non-matching Host header to be served):

  1. using if

server {
listen IP3:443 ssl default_server;
server_name some_host.com;

ssl_certificate…

if ($host != “some_host.com”) {
return 444;
}

location / {

proxy_set_header Host $host; // safe
}
}

  1. using catch-all but slightly more complicated and weird:

server {
listen IP3:443 ssl;
server_name some_host.com;

(no ssl_certificate section - it is in catch-all block)

location / {

proxy_set_header Host $host; // safe because of catch-all below
}
}

server {
listen IP3:443 ssl default_server;
server_name _;

ssl_certificate…

return 444;
}

What do you think? Are both solutions equivalent? Which one is
preffered (more efficient, elegant)? Will it work?

Thanks for your help!


Kamil

On Fri, Feb 17, 2012 at 6:18 AM, Kamil G. [email protected] wrote:

https request with non-matching Host header to be served):

It should work (at least passes nginx -t in my test).


return 444;
}

Nothing weird or complicated in this one. It’s the preferred method
but you need to specify ssl_certificate parameters on each server
blocks. I’m not sure how it behaves on non-SNI environment though.

Alternatively you can force passing some_host.com as the Host header
to your proxy:

proxy_set_header Host some_host.com


O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

On Fri, Feb 17, 2012 at 1:06 AM, Edho A. [email protected] wrote:

correctly there are two techniques to cope with my problem (to prevent
https request with non-matching Host header to be served):

It should work (at least passes nginx -t in my test).

You mean soultion no. 1 (the one with if in server block, which you -
maybe accidentally - cut off)?


return 444;
}

Nothing weird or complicated in this one. It’s the preferred method
but you need to specify ssl_certificate parameters on each server
blocks. I’m not sure how it behaves on non-SNI environment though.

By writing ‘weird’ I meant that ssl configuration is not in one place
(in the server_name with corresponding server_name) but instead in
some weird ‘server_name _’ block which maybe confusing for some
non-experienced Nginx config writers :stuck_out_tongue:

Performance wisely - is 1 and 3 imperceptible?

Alternatively you can force passing some_host.com as the Host header
to your proxy:

proxy_set_header Host some_host.com

No, this is not exactly what I want because:
a) it does not work when I have server_name like *.some_host.com (of
course in combination with some wildcard certificate)
b) it tells backend that user came with some_host.com which is not true

Thanks for your help.

Cheers,


Kamil