If you return 301 https://$host$request_uri;
as the default response on port 80, then your server may sooner or later get on a list of open proxies[1] and start being abused to send traffic elsewhere on the Internet. If your logs fill up with messages like this one, then you know it's happened to you:
42.232.104.114 - - [25/Mar/2018:04:50:49 +0000] "GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1" 301 185 "http://www.ioffer.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Hotbar 4.1.8.0; RogueCleaner; Alexa Toolbar)"
The problem is that $host
will echo back whatever the browser sends in the Host
header or even the hostname from HTTP's opening line, like this one:
GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1
Because of that problem, some other answers here recommend using $server_name
instead of $host
. $server_name
always evaluates to what you put in the server_name
declaration. But if you have multiple subdomains there or use a wildcard, that won't work, because $server_name
only uses the first entry after the server_name
declaration, and more importantly will just echo back a wildcard (not expand it).
So how to support multiple domains while maintaining security? On my own systems I've dealt with this dilemma by first listing a default_server
block that doesn't use $host
, and then listing a wildcard block that does:
server {
listen 80 default_server;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
(You could also list more than one domain in the second block.)
With that combination, unmatched domains will get redirected somewhere hardcoded (always example.com
), and domains that match your own will go to the right place. Your server won't be useful as an open proxy, so you won't be attracting trouble.
If you are feeling ornery, I suppose you could also make the default_server
block match none of your legitimate domains and serve something offensive. . . .
[1] Technically "proxy" is the wrong word, because your server isn't going out and fulfilling requests for the clients, just sending a redirect, but I'm not sure what the right word would be. I'm also not sure what the goal is, but it fills up your logs with noise and consumes your CPU and bandwidth, so you might as well put a stop to it.