Nginx Https 跳转配置问题

2015-07-09 11:15:07 +08:00
 iyaozhen

我的需求:
http://iyaozhen.com -> https://iyaozhen.com
http://www.iyaozhen.com -> https://iyaozhen.com
这两个已经实现:

server {
        listen 80;
        listen [::]:80;

        server_name iyaozhen.com www.iyaozhen.com;

        return 301 https://iyaozhen.com$request_uri;
}

我还需要 https://www.iyaozhen.com -> https://iyaozhen.com
按理我是需要这样配置:

server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name www.iyaozhen.com;

        return 301 https://iyaozhen.com$request_uri;
}

但我发现这样配置的话所以网站都不能访问了,而且我不配置的话同样能跳转过去(不知道为什么)。
这都是小问题,更大的问题是 https://demo.iyaozhen.com/ (或者其它有设置 DNS 解析,但没在 Nginx 里面设置 server 的域名)能访问到 iyaozhen.com 的内容(https 那里有红x)。

# prevent processing requests with undefined server names
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        return 444;
}

主域 iyaozhen.com 的配置:

server {
        listen 443 ssl spdy;
        listen [::]:443 ssl spdy;

        # SSL configuration
        # don’t use SSLv3 ref: POODLE
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        # 省略其它的设置……
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;
        # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
        add_header Strict-Transport-Security max-age=15768000;

        server_name iyaozhen.com;
}

我发现问题的根源是简单的 listen 443 然后做跳转是不行的,必须要配置证书啥的。这怎么办?

10108 次点击
所在节点    NGINX
36 条回复
iyaozhen
2015-07-09 15:28:55 +08:00
@FifiLyu 嗯,谢谢。目前采用的是更粗暴的方法。

iyaozhen.com 的 server 设置为 default_server 然后在里面做判断:
if ($host != iyaozhen.com) {
return 444;
}
FifiLyu
2015-07-09 15:30:20 +08:00
@iyaozhen 233 确实粗暴。
iyaozhen
2015-07-09 15:37:43 +08:00
@pupboss 有个小小的疑问。像你那样配置,按理说 www.iyaozhen.com 是没有配置证书的,只监听 443 端口,不过实际测试发现 https://www.iyaozhen.com 能跳转到 https://iyaozhen.com。 这是为什么?
alect
2015-07-09 16:52:47 +08:00
倒是对lz已经成功实现的一个功能提一个建议
lz想把http请求都转换为https请求,个人不建议用301,而是用hsts实现
然后就只要考虑把www请求转发到裸域就行了
pupboss
2015-07-09 18:24:35 +08:00
@iyaozhen 我觉得这个类似脚本语言,一行一行运行,上面没错误就不报错,如果上面写了证书信息,而且是错误的,我觉得会报错,直接给 rewrite 掉,差不多就相当于程序里面的 return 了,下面再错误都没关系
iyaozhen
2015-07-09 18:55:12 +08:00
@alect 嗯,我看过说不建议用 301,但我不太明白,可否解释下。我觉得这表示我的资源都是在 https 上,感觉没问题呀。

hsts 有些浏览器不支持。其它原因在18楼有说明。
iyaozhen
2015-07-09 19:02:46 +08:00
@pupboss 嗯,好像是的。而且我域名证书带 www 和不带的都可以。或者说是 Nginx 自己智能做了处理。比如说我访问 https://xxx.iyaozhen.com 用的是主域的证书,显示连接(算法)没问题,但域名没有公审记录。
pupboss
2015-07-09 19:08:09 +08:00
@iyaozhen 哈哈,公审记录我也不知道是啥,和 Nginx 设置没多大问题,我猜有可能是 EV 证书之类的,绿色地址框,因为 Github,cat.net ,是 EV 证书,没有 '但域名没有公审记录'
iyaozhen
2015-07-09 19:18:47 +08:00
@pupboss 额,我说错了,是不受信任。没有公审记录是你说的那样,另外一回事了。
pupboss
2015-07-09 19:40:27 +08:00
@iyaozhen 不信任一般是证书链不对,浏览器肯定信任根的,中间的链你要手动添加到你域名证书后面
dallaslu
2015-07-09 21:36:19 +08:00
@iyaozhen ~ 是正则匹配的意思,!~ 就是不匹配后面的正则。上面有位V友的回复提到 !~*,其中*的意思是不区分大小写。
dallaslu
2015-07-09 21:41:57 +08:00
@iyaozhen 如果 http 协议通过 301 跳转到 https,那么浏览器会记住这个选择,以后再访问 http://iyaozhen.com 时,就会直接访问 https://iyaozhen.com 而不再经过服务器跳转,这里并没有任何问题。

问题在于,如果初次通过 https 访问,但是没有设置HSTS;然后再访问 http 链接,浏览器就会正常执行一次 http 请求,顺带把之前从 https 中获取的 cookie 发出去了,这时就可能会被嗅探到。

所以 HSTS 要比单纯的 301 要好。

以上是个人理解。
dallaslu
2015-07-09 21:47:16 +08:00
@iyaozhen 没有做配置的情况下, www.iyaozhen.com 跳转到 iyaozhen.com,可能是因为 WordPress 的默认功能。
iyaozhen
2015-07-09 22:33:09 +08:00
@dallaslu 原来 Nginx 正则语法是这样的。谢谢

“顺带把之前从 https 中获取的 cookie 发出去了,这时就可能会被嗅探到。”——这个倒是没有考虑到。不过我 301 和 HSTS 都配置了。
caola
2015-07-09 23:21:47 +08:00
为什么要把 80 的 443 端口的分开写两次呢?
下面是我自己的主要配置,并开启了SPDY(www的跳转到根域名)
================================
server {
listen 80;
listen 443 ssl spdy;
server_name cao.la www.cao.la;
index index.php index.html;
root /home/wwwroot/caola;

ssl_certificate cert/cao.la.crt;
ssl_certificate_key cert/cao.la.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #允许的协议
ssl_ciphers AES128:AES256:GCM:!DH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS; #加密算法
ssl_session_timeout 10m; #客户端会话缓存时间
ssl_session_cache builtin:1000 shared:SSL:10m; #SSL会话缓存类型和大小
ssl_prefer_server_ciphers on; #优化SSL,服务器密码优先于客户端
ssl_buffer_size 1400; # 1400 bytes to fit in one MTU
spdy_headers_comp 6; #SPDY报头压缩级别[0-9]

add_header X-Frame-Options SAMEORIGIN; #拒绝被嵌入框架(iframe…)
add_header Strict-Transport-Security "max-age=8640000; includeSubDomains"; #子域没有全部部署https请去掉includeSubDomains
add_header X-Content-Type-Options: nosniff; #禁用浏览器的类型猜测

if ($ssl_protocol = "") { return 301 https://$server_name$request_uri; }
if ($host != 'cao.la' ) { return 301 https://cao.la$request_uri; }

}
iyaozhen
2015-07-09 23:58:57 +08:00
@caola 嗯,你这样也是好办法,在 server 配置内部做判断,然后跳转。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/204420

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX