1

I have already added the following the following to my nginx config to deal with spoofed domains:

    if ($host !~* ^(.*example.org|\d+\.\d+\.\d+\.\d+)$ ) {
            return 444;
    }

Right now it whitelists IP addresses since I need to accept them for certain requests.

This is behind an AWS ELB, so it needs to respond to an IP address as well.

Ideally I'd like it to only accept its own public and its own private IP address. However, I don't want to hard code this into the configuration as these are AWS instances.

So I guess I'm wondering if anyone has come up with a solution for blocking spoofed host headers that specifically limits to the desired IPs.

Best idea I can come up with is a script that generates the config files, adding in the correct IPs at startup, and then copying them over to the nginx config folder. But I feel like there must be a more elegant solution that doesn't require me to write a startup script.

The why

Since someone asked why I want to do this, I have basically two goals:

  • eliminate the Django errors I receive as a result of HOST_HEADER SuspiciousOperation errors
  • prevent bots (which make up 99.9% of these spoof requests) from even reaching my web app layer.
masegaloeh
  • 17,978
  • 9
  • 56
  • 104
Jordan Reiter
  • 1,260
  • 4
  • 17
  • 38
  • My apologies I don't known nginx, but why do you want to block requests with invalid host headers? – Chris S Sep 17 '14 at 14:32
  • I'm with @ChrisS on this one. Why do you want to do this? Invalid hosts are funneled to the "default" site in nginx anyways. If you want to block IPs, filter using the `X-Forwarded-For` header. – Nathan C Sep 17 '14 at 14:36
  • 2
    Honestly, it's to cut down on the `SuspiciousOperation: Invalid HTTP_HOST header` errors that Django generates each time someone spoofs a header. Also 99.9% of these requests involve bots that are actively trying to hack my server, so I'd prefer to shut them down before they get to the web application layer. – Jordan Reiter Sep 17 '14 at 14:39
  • And although Django fortunately takes care of invalid hosts for me, I also run some web apps that don't, and it's conceivable that some of my legacy code might not take host spoofing into account, leading to security issues. – Jordan Reiter Sep 17 '14 at 14:41
  • 1
    You set up a default virtual host. – Michael Hampton Sep 17 '14 at 15:35
  • Wouldn't a default virtual host respond to the private IP address? I still need my site to respond to both the private and public IP. – Jordan Reiter Sep 18 '14 at 16:40
  • @JordanReiter If you are listening on both addresses and send the correct host header, I don't see the issue with default vhost. – Xavier Lucas Sep 19 '14 at 17:06
  • Well, at point this I'm not specifically listing the private or public IPs under server_name since I don't "know" them (these are all ec2 instances). I think right now these IPs are being snagged because this config is being treated as the default server. If I set up another default virtual host, I fear it will snag the IPs that I'm not explicitly listening for. – Jordan Reiter Sep 19 '14 at 20:31
  • @JordanReiter Oh ok, I think you have no choice so, check my answer. – Xavier Lucas Sep 20 '14 at 10:20

1 Answers1

4

Your best option is indeed to generate a config file part and include it because there is no way for nginx to know authorized IPs in Host header without it.

server {

    listen 80;

    server_name mypublicdomain.com anotherdomain.com;
    include conf.d\domain-ips;  

    [ ... ]        

}

With domain-ips file containing :

server_name x.x.x.x; # Public IP
server_name x.x.x.x; # Private IP
Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50