为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务

昨天测试开发微信小程序,才发现微信也要求用HTTPS加密数据,想来是因为以前苹果的ATS审核政策的缘故吧,微信想在苹果上开放小程序必然也只能要求开发者必须使用HTTPS了,因而在服务器上测试安装Nginx+HTTPS服务。html

安装 HTTPS 最麻烦的问题应该就是获取证书了,证书感受种类也挺复杂的,有好几种,单域、泛域、多域。。。还有个种标准乱七八糟的感受,并且收费很高,仍是每一年买的。python

如今各个云服务商也都有提供各类基础功能的免费证书,但彷佛不少只对单域免费,这里的单域是指每一个二级域名都算是一个域名,每一个二级域名都须要单独配置证书。nginx

我使用的是免费的 Let's encrypt 证书,支持苹果ATS标准。web

https://letsencrypt.org/
Let's Encrypt 项目旨在让每一个网站都能使用 HTTPS 加密,该项目得到了 Mozilla、思科、Akamai、IdenTrust 和 EFF 等组织的支持, 由 Linux 基金会托管小程序

我用的是阿里云的服务器,操做系统版本:CentOS7.0微信小程序

提醒:在一切开始前,须要先注意看看服务器剩余内存,我一开始用的是最低配的测试服务器,剩余可用内存只有70MB左右,结果服务器直接挂了,因此最好先腾出个300MB内存再来。浏览器

另外,就是服务器必须绑定域名且是外网能够直接访问的才行,如果内网或虚拟机上是不行的,由于证书安装时须要经过域名访问数据的,不然不能生成证书。缓存


SSL labs 最终配置测试结果,
为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务安全

好了,下面上配置流程:服务器


1、升级系统 OpenSSL 版本

我第一次安装时使用的 OpenSSL 仍是系统默认安装版本 1.0.1e,安装完后在 SSL labs 测试安全性竟然是个 F 等级,因而升级到1.1.0c 以后变成了A,不事后来看了不少文章后,发现你们推荐使用的是 1.0.2j 版本,听说是由于 1.1 官方支持是到 2018年,并且不少软件还不能兼容,1.0.2 是支持到2019年的。至于实际用哪一个看你的其余需求了。。。

为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务

wget https://www.openssl.org/source/openssl-1.1.0c.tar.gz
tar -zxvf openssl-1.1.0c.tar.gz 
cd openssl-1.1.0c/
./config --prefix=/usr shared zlib
make 
make install

2、修改Nginx配置以支持 .well-known 目录的访问

证书安装时会在网站根目录下自动生成 .well-known 目录,必须让外网可以访问该目录下的文件才行,不然会认证失败。

对于 Nginx 的版本,我测试时使用过的最低版本是 nginx1.8.1,建议使用当前最新的稳定版 nginx1.10.2

若是以前 nginx.conf 中存在相似下面的规则

location ~ /\. {
        deny all;
    }

须要增长下面配置:注意,由于后面证书还须要自动续期,因此这个配置后面仍是须要用到的,不能删除。

location ~ /.well-known {
        allow all;
    }

3、安装 certbot-auto

1, 须要先安装 epel
yum install epel-release

2, 先修改成使用国内的 pip 源
```mkdir ~/.pip
cat > ~/.pip/pip.conf <<EOF
[global]
index-url = https://pypi.doubanio.com/simple/

[install]
trusted-host=pypi.doubanio.com
EOF

3, 安装 certbot 依赖包

mkdir /usr/local/certbot
cd /usr/local/certbot
wget https://dl.eff.org/certbot-auto --no-check-certificate
chmod +x ./certbot-auto
./certbot-auto -n

安装时错误:

Delta RPMs disabled because /usr/bin/applydeltarpm not installed

![为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务](http://img.blog.csdn.net/20170122140144795?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXptZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
解决方法:

yum provides '*/applydeltarpm'
yum install deltarpm

安装依赖的时候会下载大量包可能看着没动静,注意top看看是否有python的进程在跑

我安装完后,出现下面信息,能够直接忽略的,没有问题的

> Saving debug log to /var/log/letsencrypt/letsencrypt.log
Missing command line flags. For non-interactive execution, you will need to specify a plugin on the command line.  Run with '--help plugins' to see a list of options, and see https://eff.org/letsencrypt-plugins for more detail on what the plugins do and how to use them.

####4、生成证书

> 生成证书,有多种方式,选择你须要的一种
admin@mail.com 为管理员的邮箱,请先替换为您的邮箱地址

1. 网站一个域名的证书

./certbot-auto certonly --email admin@mail.com --agree-tos --webroot -w /home/wwwroot/yourwebsite -d www.yourdomain.com

2. 一个网站多个域名只生成一个证书

./certbot-auto certonly --email admin@mail.com --agree-tos --webroot -w /home/wwwroot/yourwebsite -d www.yourdomain.com -d m.yourdomain.com

3. 多个网站多个域名生成多个证书

./certbot-auto certonly --email admin@mail.com --agree-tos --webroot -w /home/wwwroot/yourwebsite -d www.yourdomain.com -d m.yourdomain.com -w /home/wwwroot/myanotherwebsite -d www.aotherdomain.com -d www.aotherdomain.com

出现下面信息就安装好了

> IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.youqumob.com/fullchain.pem. Your cert
   will expire on 2017-04-19. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:
>
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le


查看生成的证书,检查是否存在对应域名的密钥文件

ll /etc/letsencrypt/live/

> 咱们须要给Nginx配置用的文件为:
fullchain.pem - 证书文件
privkey.pem - 私钥文件


####5、给Nginx添加SSL证书



> HTTP 默认端口是 80,因此使用 http 时咱们无须输入端口号,HTTPS 默认的端口是 443,因此如今使用 https 不输入端口号,其实是使用的 443 端口了
修改你的网站配置文件,下面以 nginx.conf 为例

vi nginx.conf

> 若是你原来的网站还容许 http 访问,那就先复制一份再来修改,若是直接所有使用https 则直接修改
下面展现须要修改的主要配置代码

server {
listen 443 ssl;
# 若是你的服务器支持ipv6,可开启下面这一行
# listen [::]:443 ssl http2;
server_name www.yourdomain.com;

# SSL 验证配置
ssl_certificate "/etc/letsencrypt/live/www.yourdomain.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/www.yourdomain.com/privkey.pem";
# 默认值
ssl_ciphers HIGH:!aNULL:!MD5;
# 听说这个兼容 ie6 xp , 但实际测试发现根本打不开网页啊
#ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256: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";
#ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
#ssl_ciphers "EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
#ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

# 下面仍是你原来的其余配置...

}

> 对于 ssl_ciphers 这个参数的配置实在是没搞明白,网上找了半天也没有找到能说清楚具体怎么配置的,上面的几种都是网上看到的比较多的几种写法,也感受不出来有什么区别,最后我仍是使用的默认配置了。

修改保存后记得先测试下配置是否正确

nginx -t
nginx -s reload

####6、开启防火墙443端口容许外部访问

vi /etc/sysconfig/iptables

添加一行

-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT

重启防火墙

如今打开网站测试下访问是否正常。

> 注意,若是你在浏览器上网址左边没看到一个绿色的锁,表示网页上应该还有非 https 的请求,须要将页面上的 http 请求所有改形成 https 以后就是绿色的锁喽。


####7、定时任务自动更新证书续期

> 由于听说证书的有效期是 90天,但能够无限续期,因此最后还要增长个证书的自动续期定时任务功能,
注意更新证书的频率是有限制的哦,不要太频繁了,能够看看说明页面 https://letsencrypt.org/docs/rate-limits/
英文一大堆有些看不懂,大概意思吧说的是各类新增更新之类的状况每周 5~20次的限制

crontab -e

增长任务,每个月1号凌晨5点30分更新一次证书,并自动重载 nginx 配置

30 05 01 * * /usr/local/certbot/certbot-auto renew --renew-hook "/etc/init.d/nginx reload"

####8、测试是否符合苹果的ATS要求
在苹果操做系统的终端中经过nscurl命令来诊断检查

nscurl --verbose --ats-diagnostics https://www.yourdomain.com

我在苹果上测试了下 TLSv1 TLSv1.1 TLSv1.2 所有 PASS 经过了的
![为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务](http://img.blog.csdn.net/20170122140627250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXptZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

不事后来发现还能够线上测试:
腾讯云上面有个在线苹果ATS检测的功能能够试试
https://www.qcloud.com/product/ssl

![为苹果ATS和微信小程序搭建 Nginx + HTTPS 服务](http://img.blog.csdn.net/20170122140844724?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhvdXptZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

测试也所有经过

####9、其余问题

1, 检测服务器 HTTPS 配置安全性
https://www.ssllabs.com/ssltest/analyze.html
出现下面提示,安全等级竟然为 F 无语。。

> This server is vulnerable to the OpenSSL Padding Oracle vulnerability (CVE-2016-2107) and insecure

一番搜索后,发现是服务器的 openssl 版本过低的缘由,须要升级 openssl 了,能够查看第一步更新下再从新编译Nginx

2, 重定向的问题

> 若是只想使用 HTTPS ,之前的 HTTP 方式通常是须要 301 或 302 重定向到 HTTPS 请求上的,但这样会致使多一次请求,并且一样存在可能被劫持的风险,
此时可使用 HSTS ,能够将当前的 HTTP 请求重置为 HTTPS 方式而不用跳转,max-age的时间根据你的需求自定义
加上这个后,你的服务器在 SSLLAB 上的等级就是 A+ 啦

在 server 部分添加 add_header

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";

注意:

> 若要取消时不能直接删除该配置,必须先将 max-age=0; 设置为 0 一段时间后再去掉,不然可能致使部分用户浏览器未更新配置。
也就是说这个功能只能是当用户 经过 https 协议访问过网站一次后浏览器缓存住跳转信息,下次继续用 http 请求的时候浏览器才会自动跳了而再也不是请求了服务器后来跳转
建议若是不是全站都转移到 https ,仅用 https 访问网站的话仍是别用,仍是服务器来控制跳转好些

3, SSL labs 出现提示:

> This server supports weak Diffie-Hellman (DH) key exchange parameters. Grade capped to B. 

解决方法(下面的密钥保存目录可自定义):

mkdir -p /usr/local/nginx/conf/vhost/ssl
openssl dhparam -out /usr/local/nginx/conf/vhost/ssl/dhparams.pem 2048

添加 nginx ssl 配置:

vi nginx.conf
ssl_dhparam /usr/local/nginx/conf/vhost/ssl/dhparams.pem;
```

好了,整个服务端配置完成。

相关文章
相关标签/搜索