在申请成功https的泛域名证书账号,接下来就是为主域名以及二级域名配置添加证书文件,以让“小绿锁” 显示出来。
显示小绿锁却提示404NotFound 上篇文章末尾,我为二级域名 gogit.itfanr.cc
的Nginx配置中指定了证书目录,网站也正常应用上了https:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 server { listen 443 ssl; server_name gogit.itfanr.cc; ssl_certificate /etc/acme.sh/itfanr.cc/fullchain.cer; ssl_certificate_key /etc/acme.sh/itfanr.cc/itfanr.cc.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; location / { proxy_pass http://127.0.0.1:3000/; } } server { listen 80; server_name gogit.itfanr.cc; return 301 https://$server_name$request_uri; }
但当我按照上面的配置为主域名 www.itfanr.cc
也指定https证书后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 server { listen 443 ssl; server_name www.itfanr.cc; ssl_certificate /etc/acme.sh/itfanr.cc/fullchain.cer; ssl_certificate_key /etc/acme.sh/itfanr.cc/itfanr.cc.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; location / { proxy_pass http://localhost:8080/; } } server { listen 80; server_name www.itfanr.cc; return 301 https://$server_name$request_uri; }
结果,页面却显示了 404 Not Found
的错误。
解决多域名下设置证书 通过相关问题的搜索,结果却没有找到什么有效的解决方法。另外由于我对Nginx的配置也不是特别精通,所以一下子陷入了迷茫中。
后来,在一篇相关文章 Let’s Encrypt 泛域名证书申请及配置 中找到了一种方法。
第一步 在Nginx的 snippets
目录下,创建一个配置文件,我这里命名为 ssl-itfanr.conf
,内容用来设置SSL相关的配置:
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 # /etc/nginx/snippets/ssl-itfanr.conf server_tokens off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 60m; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s; ssl_prefer_server_ciphers on; # 证书路径 绝对地址 ssl_certificate /etc/acme.sh/itfanr.cc/fullchain.cer; ssl_certificate_key /etc/acme.sh/itfanr.cc/itfanr.cc.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload"; add_header X-Frame-Options deny; add_header X-Content-Type-Options nosniff; add_header x-xss-protection "1; mode=block"; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src https:";
第二步 然后在 Nginx
主配置文件中开启 SSL
支持:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # /etc/nginx/nginx.conf http { ... ... ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ... ... }
我的配置文件中 SSL配置
这里默认是启用状态,所以保持默认即可。
第三步 修改域名的配置文件。
比如,修改我的网站主域名 itfanr.cc
配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # /etc/nginx/conf.d/itfanr.conf server { listen 80; listen [::]:80; server_name itfanr.cc www.itfanr.cc; return 301 https://$server_name$request_uri; } server { listen 443 default_server; listen [::]:443 default_server; server_name itfanr.cc www.itfanr.cc; include snippets/ssl-itfanr.conf; location / { proxy_pass http://localhost:8080/; } }
同时,修改二级域名 gogit.itfanr.cc
的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # /etc/nginx/conf.d/gogit.conf server { listen 80; server_name gogit.itfanr.cc; return 301 https://$server_name$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name gogit.itfanr.cc; include snippets/ssl-itfanr.conf; location / { proxy_pass http://127.0.0.1:3000/; } }
其中,关键的一点就是在配置文件中包含SSL的配置文件:
1 include snippets/ssl-itfanr.conf;
第四步 如果还有其他的二级域名,同样依照上面的方法进行配置,然后重新载入Nginx配置文件。
在重载之前,可以先验证一下刚刚修改的配置文件是否有误:
1 2 3 $ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
无误后,再执行重载操作:
此时,再次访问两个域名地址,可以发现都能够正常访问且都是https安全连接了。
itfanr.cc:
gogit.itfanr.cc:
设置默认站点 因为我的域名设置了支持泛域名,所以支持的二级域名都会跳转到我的服务器的IP地址。
那么,对于一些我们没有添加到二级域名在没有进行定义时,会返回什么呢?这就需要设置 默认站点
了。
也就是通过参数 default_server
来指定。
我们可以查看一下 /etc/nginx/sites-available/default
文件:
1 2 3 4 5 6 7 server { listen 80 default_server; listen [::]:80 default_server; ... ... root /var/www/html; }
上面的设置说明,当访问域名是没有匹配到我们添加的域名,那么就会返回默认的地址。也就是这里的 Nginx默认的页面。
比如,我访问 http://abc.itfanr.cc
时:
而该文件中并没有配置当使用 https
方式访问时,要返回什么默认页面。所以我在上面的 itfanr.conf
配置中添加了一项:
1 2 3 4 5 ... listen 443 default_server; listen [::]:443 default_server; server_name itfanr.cc www.itfanr.cc; ...
默认返回我的博客地址。比如访问 https://abc.itfanr.cc
时:
另外,要注意的是:只能设置一个网址为默认地址,当设置了多个时会提示错误:
1 2 3 $ sudo nginx -t nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/default:17 nginx: configuration file /etc/nginx/nginx.conf test failed
解决网站中的 data
类型字体图片无法载入问题 配置好Nginx的 https
配置后,再次请求网址 https://gogit.itfanr.cc
,发现浏览器地址栏中已经显示了安全的 “小绿锁” 标志。但是一打开Chrome浏览器的F12调试工具,发现有一些请求是报错的。
可以发现,报错的基本都是前缀为 data:application
类型的字体图片文件。
通过查询,在 Content-Security-Policy
段中应该包含以下内容:
所以只需要在 font-src
和 https
之间添加 :'self' data:
即可。注意前后之间要用空格分隔。
原:
1 2 3 # /etc/nginx/snippets/ssl-itfanr.conf add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src https:";
修改后:
1 2 3 # /etc/nginx/snippets/ssl-itfanr.conf add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src 'self' data: https:";
修改完成后,重新载入Nginx配置,再次刷新网站,发现已经没有 data:application
红色的错误请求链接了:
解决七牛云图片外链http无法载入的问题 访问我的博客网址 https://www.itfanr.cc
,发现有些文章中的七牛云外链图片都不显示了。查看F12调试工具:
发现所有的七牛云 http
外链图片均不加载。
然后我又去七牛云的网站中查看了一下配置,发现如果按照官方的方法切换成 https
的链接,是需要收费的,此时心里是一万头草泥马狂奔的景象…
无奈只能找寻其他的解决方法了。
查看F12的Console中的错误信息:
1 Refused to load the image 'http://ouej55gp9.bkt.clouddn.com/blog/20180917193602.png' because it violates the following Content Security Policy directive: "img-src 'self' data: https: blob:".
搜索到 Content-Security-Policy
介绍页面:Content Security Policy CSP Reference & Examples
参照里面的介绍,尝试把七牛云图片的域名加到 img-src
中,更改如下:
1 2 3 4 5 img-src 'self' data: https: blob:; # 更改为: img-src 'self' ouej55gp9.bkt.clouddn.com data: https: blob:;
再次刷新页面后,发现如果页面中没有引用到七牛云的图片链接,地址栏中是显示“小绿锁”的,比如首页;而到了文章详情页中,引用了七牛云的图片链接后,地址栏中就会显示“叹号”的不安全标志。
访问首页,提示“安全连接”:
访问带有http外链图片的文章详情,提示“连接并非完全安全”:
根据上面的验证发现,必须得整站的链接都是 https
的情况下,才会是一直处于“小绿锁”的安全模式下。那么接下来就是解决整站https
的问题了。目前来看,也就是解决七牛云图片链接如何从 http
到 https
的问题。
遗留的问题 虽然通过独立出SSL配置,然后在需要启用 https
的域名配置文件 server{}
中 include
的方式能够正常运行,但我心里一直还是有个疑问的:为什么分别指定证书文件地址时配置却不生效?
由于目前还未找到原因,这个问题暂留,以待后续解答。