I have a site set up this way: nginx as a proxy server, proxying requests tu a gunicorn instance serving a Django site through a UNIX socket.
This is my nginx configuration:
server {
listen 80;
server_name api.mysite.com;
location /static/ {
alias /webapps/mysite/static/;
autoindex off;
}
location / {
include proxy_params;
proxy_pass http://unix:/webapps/mysite/mysite.sock;
}
}
Is my understanding that nginx, when receiving a request, matches the Host
header against the server_name parameter of the server block and, if it matches, it serves it. However, nginx seems to be trying to serve (passing the request to my Django server) request with a Host
header different than api.mysite.com. Django has a setting named ALLOWED_HOSTS
(in my case set to ['api.mysite.com']
) that performs further checking of the Host
header and raises an error if the request Host
header doesn't match, which shouldn't happen because nginx is supposedly already filtering this. The thing is that I'm seeing errors raised by Django which look like this:
- Invalid HTTP_HOST header: '/webapps/mysite/mysite.sock:'. The domain name provided is not valid according to RFC 1034/1035.
- Invalid HTTP_HOST header: 'testp1.piwo.pila.pl'. You may need to add 'testp1.piwo.pila.pl' to ALLOWED_HOSTS.
- Invalid HTTP_HOST header: 'xxx.xxx.xxx.xxx' (The real IP of my server). You may need to add 'xxx.xxx.xxx.xxx' to ALLOWED_HOSTS.
A couple of things:
- I know that the requests are coming through nginx because they show up in nginx logs and it would be impossible anyway to hit directly the gunicorn server because I'm proxying through a UNIX socket and not through HTTP.
- I know that these requests are coming from a bot looking for free proxies to use, but I don't really care much about that. What I'm really intrigued by is the request with the
Host
header set to the path on the local filesystem of my gunicorn/nignx UNIX socket.
Any clue?
Turns out that if nginx doesn't encounter a matching server block, it will send the request to the first server block. So the solution was to set up a default server block that drops every request like this: