Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
501 views
in Technique[技术] by (71.8m points)

python - I continuously receive `Invalid HTTP_HOST header` error email after I upgrade my django site from http to https

Recently, I upgrade one of my django sites from http to https. However, after that, I continuously receive Invalid HTTP_HOST header error email while before I never received such type of emails.

Here are some log messages:

[Django] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: '123.56.221.107'. You may need to add '123.56.221.107' to ALLOWED_HOSTS.


[Django] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: 'www.sgsrec.com'. You may need to add 'www.sgsrec.com' to ALLOWED_HOSTS.


[Django] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: 'sgsrec.com'. You may need to add 'sgsrec.com' to ALLOWED_HOSTS.

Report at /apple-app-site-association Invalid HTTP_HOST header: ‘sgsrec.com’. You may need to add ‘sgsrec.com’ to ALLOWED_HOSTS.


Invalid HTTP_HOST header: ‘www.pythonzh.cn’. You may need to add ‘www.pythonzh.cn’ to ALLOWED_HOSTS.

Report at / Invalid HTTP_HOST header: ‘www.pythonzh.cn’. You may need to add ‘www.pythonzh.cn’ to ALLOWED_HOSTS.

Request Method: GET Request URL: http://www.pythonzh.cn/ Django Version: 1.10.6


[Django] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: 'pythonzh.cn'. You may need to add 'pythonzh.cn' to ALLOWED_HOSTS.

What the strange thing is that I only change my blog site www.zmrenwu.com nginx configuration, but seems all of my sites which hosted on 123.56.221.107 are effected.

Of cause, I set ALLOWED_HOSTS correctly:

ALLOWED_HOSTS = ['.zmrenwu.com']
ALLOWED_HOSTS = ['.sgsrec.com']
ALLOWED_HOSTS = ['.pythonzh.cn']

Nginx configuration of my blog site www.zmrenwu.com:

server {
    charset utf-8;
    server_name zmrenwu.com www.zmrenwu.com;
    listen 80;
    return 301 https://www.zmrenwu.com$request_uri;
}

server {
    charset utf-8;
    server_name zmrenwu.com;
    listen 443;

    ssl on;
    ssl_certificate /etc/ssl/1_www.zmrenwu.com_bundle.crt;
    ssl_certificate_key /etc/ssl/2_www.zmrenwu.com.key;

    return 301 https://www.zmrenwu.com$request_uri;
}

server {
    charset utf-8;
    listen 443;
    server_name www.zmrenwu.com;

    ssl on;
    ssl_certificate /etc/ssl/1_www.zmrenwu.com_bundle.crt;
    ssl_certificate_key /etc/ssl/2_www.zmrenwu.com.key;

    location /static  {
        alias /home/yangxg/sites/zmrenwu.com/blogproject/static;
    }

    location /media {
        alias /home/yangxg/sites/zmrenwu.com/blogproject/media;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://unix:/tmp/zmrenwu.com.socket;

Why that happened? And How could I solve this issue?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Disabling DisallowedHost host warnings as suggested in the other answer is not the correct solution in my opinion. There is a reason why Django gives you those warnings - and it is better for you to block those requests before they reach Django.

You created a new server block in your nginx configuration. Because it is the only HTTPS server you have defined, it becomes the default server for that port. From the documentation:

The default_server parameter, if present, will cause the server to become the default server for the specified address:port pair. If none of the directives have the default_server parameter then the first server with the address:port pair will be the default server for this pair.

This explains why you are suddenly seeing all these invalid host errors. Any bot that now tries to connect to your server over HTTPS will end up using this default server. Because many bots will be using fake host names or just your server IP (neither of which are in ALLOWED_HOSTS) this causes the warnings in Django.

So what is the solution? You can create a separate server block that handles all such invalid requests:

server {
    listen 443 ssl default_server;
    server_name _;
    return 444;
}

444 is a special response status used by nginx to disconnect invalid requests.

Once you add this block, it will be used for all requests that don't match the host headers that you want to respond to, and anything trying to connect with an invalid host will not be able to connect.

Django meanwhile will stop seeing requests for invalid hosts.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...