LNMP环境下正确配置HTTP强制跳转HTTPS的方法

17次阅读
没有评论

概述

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites

1
2
3
4
5
6
# 不好的方法:
rewrite ^/(.*)$ http://example.com/$1 permanent;
# 好的方法:
rewrite ^ http://example.com$request_uri? permanent;
# 更好的方法:
return 301 http://example.com$request_uri;

因此,对于 HTTP 强制跳转 HTTPS 的语句,应当写成:

1
return 301 https://$server_name$request_uri;

默认配置

对于自己手动编译安装的 Nginx,其默认配置文件nginx.conf 将 80 端口和 443 端口(默认被注释)的监听分别写进了两个 server 段中,这是一种非常符合生产环境的标准做法。因此,只需要将上述语句直接复制到 80 端口对应的 server 段中,同时将该段中的 location 配置全部复制到 443 端口对应的 server 段中即可。类似如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# https 部分
server {
listen 443 ssl;
server_name yourname.com;

ssl_certificate /dir/xx.crt;
ssl_certificate_key /dir/xx.key;
ssl_dhparam /dir/dhparam.pem;

ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+EXP;

location / {
root /your/wwwroot/;
index index.html index.htm index.jsp index.do;
}
}
# http 部分
server {
listen 80;
server_name yourname.com;
return 301 https://$server_name$request_uri;
location / {
root /your/wwwroot/;
index index.html index.htm index.jsp index.do;
}
# http 部分的 location 字段可保留可删除
}

LNMP 环境配置

如果你的 LNMP 环境使用的是流行的一键安装包,那么问题就来了。这个脚本生成的 nginx.conf 中没有 443 端口的 server 字段,因此在配置 SSL 证书的时候,有些人为了省事,可能会直接将 443 端口的监听一起写到 server 字段中,类似这种:

1
2
3
4
5
6
7
8
9
10
11
12
13
server
{
listen 80;
listen 443 ssl;
ssl_certificate /dir/xx.crt;
ssl_certificate_key /dir/xx.key;
ssl_dhparam /dir/dhparam.pem;
#listen [::]:80 default_server ipv6only=on;
server_name www.yourname.com yourname.com;

index index.html index.htm index.php;
root /your/wwwroot/;
}

那么如果你直接使用 return 301 https://$server_name$request_uri; 由于 443 端口和 80 端口在同一个 server 段监听,就会产生内部无限循环。当用户访问时,就会出现“重定向次数过多(ERR_TOO_MANY_REDIRECTS)”的错误。

正确的方法,使用 IF 判定,只对 HTTP 连接进行重定向:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server
{
listen 80;
listen 443 ssl;
ssl_certificate /dir/xx.crt;
ssl_certificate_key /dir/xx.key;
ssl_dhparam /dir/dhparam.pem;
#listen [::]:80 default_server ipv6only=on;
server_name www.yourname.com yourname.com;

if ($scheme = http ){
return 301 https://$server_name$request_uri;
}

index index.html index.htm index.php;
root /your/wwwroot/;
}

但 Nginx 官方并不推荐过多的 IF 判定(可参考:https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/)。

因此最好还是像 Nginx 默认配置文件那样,将 80 端口和 443 端口的监听区分开,同时采用第一种跳转方法,这也是更符合生产环境的一种做法。

正文完
 0
liveob
版权声明:本站原创文章,由 liveob 于2024-09-15发表,共计2136字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码