nginx 444

介绍

当没有显式指定default server的时候,Nginx会使用第一个server来作为默认的响应server,即使请求的Host并没有匹配到server_name。
这是为了兼容老旧的一些不带Host的HTTP请求而做的设置。官文描述: How nginx processes a request

此时可能存在一定的风险。如果有非备案的名解析到了你的Public IP上,而你的Web服务对该域名的请求有所响应的话,可能会导致Public IP被运营商封锁。

解决办法:

在nginx中添加一个default server,并在default server中设置return 444;。此时Nginx就不会响应请求,除非请求的Host是配置的。

1
2
3
4
5
server {
listen 80 default_server;
server_name _;
return 444;
}

此时请求服务器,在Chrome中显示的页面如下:

444_no_response.png

和499类似,444不是标准的HTTP status code,而是Nginx自己设立的状态码,参见444 CONNECTION CLOSED WITHOUT RESPONSE
设置了444过后,nginx收到不匹配的Host请求的话,不会有任何响应。比起404之类,另外一个好处就是可以节省一点点的带宽。

Reference

HTTP 307 Temporary Redirect

介绍

随着网络安全越发重要,越来越多的网站都从http迁移到了https。但迁移到https之前分发出去的链接都是http,为了兼容以前的链接,就需要做一个redirect,将http的请求redirect到https中。
最常见的redirect方式就是301 Moved Permanently或者302 Found, 将http重定向到https中。

对于普通的GET请求,这种方式是完全可以的。但当请求是POST的时候,由于一些历史原因,一些浏览器和库收到301或302的时候,会将原本的POST请求转为GET请求发送。此时POST的body会丢失,导致请求出问题。
如果要redirect POST请求,则需要使用307 Temporary Redirect来进行redirect。RFC 7231中对于307的一个描述”Note: This status code is similar to 302 (Found), except that it does not allow changing the request method from POST to GET. “

nginx 例子

一个GET是301, POST是307的nginx配置例子

1
2
3
4
5
6
7
8
server {
listen 80;
server_name www.fake.com;
if ($request_method = POST) {
return 307 https://$host$request_uri;
}
return 301 https://$host$request_uri;
}

国内各大站的处理方式

查看了国内BAT,国外Google,facebook和amazon是如何从http重定向到https的。发现除了腾讯外,其他几个大站,即使请求是GET,也是直接甩307。

如下是几大巨头网站主页http redirect https的截图:

Reference

留言