爲蘋果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;
```

好了,整個服務端配置完成。

相關文章
相關標籤/搜索