nginx 非80端口的同端口http跳转https
最近在家中搭建了一个 All-in-one 的 NAS 服务器,也申请了 SSL 证书,打算正式进入 HTTPS 时代。
但在这个时候遇到问题,就是 HTTP 到 HTTPS 的跳转问题。以往是通过 nginx 在 80 端口监听流量,并使用 30x 的 http code 将 url 重定向至 https 的网址。但是家用公网的特点就是 80 和 443 端口是不可用的,所以这种方式不再可行。
好在 nginx 实际上在发现 http 请求被发送到 https 的监听端口时,实际上会产生内部错误代码 497,因此我们可以通过对这个内部错误代码设置 error handler,将用户的 http 请求重新定向到 https 的网址。
nginx 的 error_page
选项
先看看 nginx 的 error_page
选项的定义(官方文档):
Syntax: error_page code … [=[response]] uri;
Default: —
Context: http, server, location, if in location
简述:简单来说,code
为 nginx 遇到的错误代码,并指定遇到此错误代码时候的跳转地址。此外,还可以在跳转的时候,指定 response
作为新的返回代码。注意此选项可以运用在 http
、server
和 location
等块中,因此方便起见,我将此选项至于 http
块中作为全局设置。
示例:
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
error_page 404 =200 /empty.gif;
error_page 404 = /404.php;
HTTP 全局跳转 HTTPS 的设置
在 http
块中,修改为:
http {
... ...
##
# HTTP redirect
##
error_page 497 =307 https://$host:$server_port$request_uri;
... ...
}
这里解释一下:代码 497 前面说过,是 nginx 在遇到 HTTP 请求发到 HTTPS 时会产生的内部错误代码,因此我们将返回一个 307 的回复(307 Temporary Redirect是HTTP协议中的一个状态码(Status Code)。可以理解为一个临时的重定向。但该响应代码与302重定向有所区别的地方在于,收到307响应码后,客户端应保持请求方法不变向新的地址发出请求,详情见维基百科 - HTTP 307)。
之后,我们使用 nginx 中内置的变量,将 HTTP 请求重定向到 HTTPS 即可。