Nginx 配置安装 SSL 证书与配置在线代理

最近闲来无事想折腾一下 https 。顺便学习猫神做一做在线代理。于是就去https://buy.wosign.com/FreeSSL.html 申请了一个免费的 SSL 证书。申请证书的过程需要验证域名所有权,然后会经过人工审核,实际上申请的过程没有任何难度。成功后会获得一个 crt 和一个 key。有些是获得四个文件,需要自己把几个文件连起来生成 crt。

(注:免费的 SSL 证书也可以来自 http://www.startssl.com,关于 startssl 的申请步骤可以参见http://ichon.me/post/955.html

我的测试服务器环境是 Ubuntu 14.04+nginx 1.4.6+php5 with fpm。

至于 wosign 的 SSL,参考官方文档https://support.wosign.com/index.php?/Knowledgebase/Article/View/41/0/sslnginx

注意 https 的站点较难被百度收录,但似乎并不是完全不收,关于这个问题 V2EX 上有讨论。

1,使用 scp 或者 ftp 把证书上传到服务器

(本次使用的是 WoSign 提供的 SSL 证书,是加密的 zip ,内有 crt 和 key)。

2,解压证书

unzip p.lidadi.me.zip 
Archive:  p.lidadi.me.zip
[p.lidadi.me.zip] for IIS.zip password: 
replace for IIS.zip? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
  inflating: for IIS.zip             
  inflating: for Tomcat.zip          
  inflating: for Apache.zip          
  inflating: for Nginx.zip           
  inflating: for Other Server.zip
unzip for\ Nginx.zip 
Archive:  for Nginx.zip
  inflating: 2_p.lidadi.me.key       
  inflating: 1_p.lidadi.me_bundle.crt

3,将证书放置到妥善的位置。

需要注意的一点,不同认证机构提供的证书形式可能不一样,比如沃通直接提供了签署好的证书,但是诸如 AlphaSSL 等认证机构需要自己生成证书。

顺序是:服务器证书 > 中间机构证书 > 根证书 ,中间机构有几个粘几段注意顺序,最后组合成一个 *.crt 文件。

如果服务器证书和认证方证书链合并时顺序弄错了,nginx就不能正常启动,而且会显示下面的错误信息:

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

因为nginx首先需要用私钥去解密服务器证书,而遇到的却是认证方的证书。

浏览器通常会将那些被受信的认证机构认证的中间认证机构保存下来,那么这些浏览器以后在遇到使用这些中间认证机构但不包含证书链的情况时,因为已经保存了这些中间认证机构的信息,所以不会报错。


UPDATE 2016.08.01

最近配 Let’s encrypt 发现屈老师的示例里没有把 root CA 串进证书链,而只串进了 OCSP 的 cert 文件,当中间 CA 已经是广泛被信任的 CA 时实际上是不需要把 root CA 也串进证书链里的。实际上 SSLLAB 测试的时候也对这个串了四级的证书报了不正确的 CA 配置。

有些浏览器不接受那些众所周知的证书认证机构签署的证书,而另外一些浏览器却接受它们。这是由于证书签发使用了一些中间认证机构,这些中间机构被众所周知的证书认证机构授权代为签发证书,但是它们自己却不被广泛认知,所以有些客户端不予识别。针对这种情况,证书认证机构提供一个证书链的包裹,用来声明众所周知的认证机构和自己的关系,需要将这个证书链包裹与服务器证书合并成一个文件。——来自 tengine.org


 

4,配置 nginx 的vhost Server:

server {
        listen 80;
        server_name p.lidadi.me;
        rewrite ^(.*) https://$server_name$1 permanent;
}

设置重写规则,强制所有80端口的访问跳转到443(不然 https 也就没有意义了对吧)

server {
	listen 443;
	server_name XXXX;

	root XXXX;
	index index.html index.php index.htm;

	ssl on;
	ssl_certificate XXXX;
	ssl_certificate_key XXXX;
	ssl_session_timeout 5m;
	ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
	ssl_prefer_server_ciphers on;

	location / {
		try_files $uri $uri/ =404;
	}
        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
		fastcgi_param HTTPS on;
        }
}

这里使用的是 PHP5-FPM 方式,若是使用 fastcgi 配置会略有不同但是和服务在80端口的时候是一样的。

另外请务必十分注意加上

fastcgi_param HTTPS on;

缺少这一句的话 PHP 是不会在 https 下生效的。

5,部署在线代理工具

可以使用glype 这个在线代理工具。其主站受某绿坝娘的姐妹 blocked.com的防护似乎限制访问,但是可以直接在浏览器里输入https://glype.com/download.php下载需要的文件。

然后还是 scp 或者 FTP 到服务器,放置到网站目录下解压。

这个代理需要 curl 库支持,Debian 系可直接 apt 解决。

apt-get install php5-curl

最后,在浏览器里输入 http://域名/admin.php 进行安装(不输入 https 可以检测重写是否生效)。

值得一提的是,一般情况下是不支持同一个 IP 配置多 https 站点的。

SSL协议层位于HTTP协议层之下,HTTP协议是被封装在SSL协议中的,所以SSL会话必须在HTTP会话之前建立。因为在建立SSL会话的最初握手阶段,服务器无法知道HTTP请求头的Host字段的内容,也就无法确定究竟使用哪个虚拟主机的配置(例如允许使用哪些加密算法、服务器证书是哪个等等),于是Apache就会使用匹配这个IP地址端口对的第一个主机的SSL配置。

如果需要开启这功能需要 Web Server 支持 TLS SNI support,之后配反代的时候应该会详细解决这个问题,Apache 的解决方案可以参见猫神的博客

 


本文链接:https://www.starduster.me/2014/11/16/nginx-install-ssl/
本站基于 Creactive Commons BY-NC-SA 4.0 License 允许并欢迎您在注明来源和非商业使用前提下自由地对本文进行复制、分享或基于本文进行创作。
请注意:受限于笔者水平,本站内容可能存在主观臆断或事实错误,文中信息也可能因时间推移而不再准确,在此提醒读者结合自身判断谨慎地采纳。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据