server {
listen 80;
listen [::]:80;
server_name iyaozhen.com www.iyaozhen.com;
return 301 https://iyaozhen.com$request_uri;
}
一个IP地址正常情况是只支持一个 https vhost,所以你访问 demo 访问到了 iyaozhen.com。这个 demo 有红叉是因为访问的域名和ssl证书认证的域名不一致。访问是demo.iyaozhen.com,证书是 www.iyaozhen.com 以及 iyaozhen.com。
如果要一个IP支持多个 https vhost,请开启 nginx 的 SNI 支持。但是,不建议这样做。因为可能访问https 都会出现红叉。
嗯,这个我知道。我是单域名证书。我不是要 https://demo.iyaozhen.com/ 能访问到我的主域博客。而是 https://demo.iyaozhen.com/ 不能访问,http://demo.iyaozhen.com/ 能正常访问其本来的站点。
要http正常的话只要正确填写server_name即可
https的怎么都不会正常
只要你想让443 能通过https访问,必须要配置证书
即使是只做跳转
看来是这样。跳转这个是个小问题。但 https://demo.iyaozhen.com/ (或者其它有设置 DNS 解析,但没在 Nginx 里面设置 server 的域名)能访问到 iyaozhen.com 的内容(https 那里有红x)。这个怎么解决。
这个因为是共享ip没法解决,除非你给 demo.iyaozhen.com 也配置上ssl
https连接建立是在判断server_name之前的,所以所有的https连接都会指向 iyaozhen.com 。
可以加一行判断host的:
if ($host !~* ^iyaozhen.com$ ) {
return 404;
}
不知道有没有更好的方案。
明白了,我没有许可的证书(泛域名证书)再设置 443 端口的 default_server。单域名证书,有点略坑呀。
嗯,谢谢。明白了。
没人用 HSTS 做 http 跳转 https 的么?
有啊,配置里面不是写了嘛。不过 IE9 等不支持 HSTS,还是要再加个 server 做跳转。
lz自己把自己坑了,申请证书的时候加上不要用裸域名而是带www的,否则有些直接给你签发的证书就只有裸域名了
配一个 80 端口的 server:
server_name iyaozhen.com www.iyaozhen.com;
if ($host ~ ^(www\.)?iyaozhen\.com) {
rewrite ^(.*) https://iyaozhen.com$1 permanent;
}
只配一个 443 端口的 server:
server_name iyaozhen.com www.iyaozhen.com;
if ($host ~ ^www\.iyaozhen\.com) {
rewrite ^(.*) https://iyaozhen.com$1 permanent;
}
if ($host !~ ^(www\.)?iyaozhen\.com) {
rewrite ^(.*) http://$host$1 permanent;
}
(未经测试)
HSTS 在 http 下并没卵用,已经试过了
server {
listen 80;
server_name pupboss.com;
return 301 https://$server_name$request_uri;
}
server {
listen 80;
listen 443 ssl;
server_name www.pupboss.com;
rewrite ^/(.*)$ https://pupboss.com/$1 permanent;
}
谢谢,你这种方式应该也可以。目前我是这样解决的:
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name www.iyaozhen.com;
return 301 https://iyaozhen.com$request_uri;
}
按理说 www.iyaozhen.com 是没有配置证书的,只监听 443 端口,不过实际测试发现 https://www.iyaozhen.com 能跳转到 https://iyaozhen.com。
顺带请教个问题 !~ 是 !=,~ 是 = 吗?这是什么语法?
好方法,我就是像你这样配置的。
是的,HSTS 在只访问 http 时是没用的。
HSTS 的作用应该是访问了一次 https 的网站后,浏览器检测到了这个协议,当你以后输入域名时(即使手动输入 http://)会跳转到对应的 https 网站。
应该也是给我签了带 www 的。https://www.ssllabs.com/ssltest/index.html 检测结果:
Common names iyaozhen.com
Alternative names iyaozhen.com www.iyaozhen.com
Prefix handling Both (with and without WWW)
因为你只有一个 ssl 站点,任何域名解析到你的IP地址。都能通过https://test.abc.com 访问到 https://iyaozhen.com 的内容。这个你是关不掉的。
变通的做法是,开启 SNI 支持。然后,新建一个 nginx 的 ssl 站点,root指向一个目录,目录下没有任何东西。不过,这样肯定不好。
如果是用的 Linux ,使用 iptables 做一个域名白名单防火墙,443端口只允许 iyaozhen 域名访问。
白名单设置参考: https://github.com/fifilyu/module-http-whitelist 中的 “代替方案”
嗯,谢谢。目前采用的是更粗暴的方法。
把 iyaozhen.com 的 server 设置为 default_server 然后在里面做判断:
if ($host != iyaozhen.com) {
return 444;
}
233 确实粗暴。
有个小小的疑问。像你那样配置,按理说 www.iyaozhen.com 是没有配置证书的,只监听 443 端口,不过实际测试发现 https://www.iyaozhen.com 能跳转到 https://iyaozhen.com。 这是为什么?
倒是对lz已经成功实现的一个功能提一个建议
lz想把http请求都转换为https请求,个人不建议用301,而是用hsts实现
然后就只要考虑把www请求转发到裸域就行了
我觉得这个类似脚本语言,一行一行运行,上面没错误就不报错,如果上面写了证书信息,而且是错误的,我觉得会报错,直接给 rewrite 掉,差不多就相当于程序里面的 return 了,下面再错误都没关系
嗯,我看过说不建议用 301,但我不太明白,可否解释下。我觉得这表示我的资源都是在 https 上,感觉没问题呀。
hsts 有些浏览器不支持。其它原因在18楼有说明。
嗯,好像是的。而且我域名证书带 www 和不带的都可以。或者说是 Nginx 自己智能做了处理。比如说我访问 https://xxx.iyaozhen.com 用的是主域的证书,显示连接(算法)没问题,但域名没有公审记录。
哈哈,公审记录我也不知道是啥,和 Nginx 设置没多大问题,我猜有可能是 EV 证书之类的,绿色地址框,因为 Github,cat.net ,是 EV 证书,没有 '但域名没有公审记录'
额,我说错了,是不受信任。没有公审记录是你说的那样,另外一回事了。
不信任一般是证书链不对,浏览器肯定信任根的,中间的链你要手动添加到你域名证书后面
~ 是正则匹配的意思,!~ 就是不匹配后面的正则。上面有位V友的回复提到 !~*,其中*的意思是不区分大小写。
如果 http 协议通过 301 跳转到 https,那么浏览器会记住这个选择,以后再访问 http://iyaozhen.com 时,就会直接访问 https://iyaozhen.com 而不再经过服务器跳转,这里并没有任何问题。
问题在于,如果初次通过 https 访问,但是没有设置HSTS;然后再访问 http 链接,浏览器就会正常执行一次 http 请求,顺带把之前从 https 中获取的 cookie 发出去了,这时就可能会被嗅探到。
所以 HSTS 要比单纯的 301 要好。
以上是个人理解。
没有做配置的情况下, www.iyaozhen.com 跳转到 iyaozhen.com,可能是因为 WordPress 的默认功能。
原来 Nginx 正则语法是这样的。谢谢
“顺带把之前从 https 中获取的 cookie 发出去了,这时就可能会被嗅探到。”——这个倒是没有考虑到。不过我 301 和 HSTS 都配置了。
为什么要把 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_prefer_server_ciphers on; />ssl_buffer_size 1400; 1400 bytes to fit in one MTU
spdy_headers_comp 6; X-Frame-Options SAMEORIGIN; />add_header Strict-Transport-Security "max-age=8640000; includeSubDomains"; />add_header X-Content-Type-Options: nosniff; ($ssl_protocol = "") { return 301 https://$server_name$request_uri; }
if ($host != 'cao.la' ) { return 301 https://cao.la$request_uri; }
}
嗯,你这样也是好办法,在 server 配置内部做判断,然后跳转。