使用letsencrypt實現https站點

weixin_34087301發表於2016-10-09

原文發表在我的個人部落格 - 使用letsencrypt實現https站點

最近想把我的部落格弄成https安全加密模式,其實不是為了什麼安全,就是為了折騰下https~對於https證照的申請,推薦兩個好用免費的startSSL/letsencrypt。這裡簡單記錄下使用letsencrypt的過程。

letsencrypt的官網上提供了很多申請證照的工具,這裡我選擇了開源的python工具acme-tiny

建立Let's Encrypt賬號私鑰

建立一個RSA私鑰用於Let's Encrypt識別你的身份。

openssl genrsa 4096 > account.key

建立站點的CSR檔案

CSR(Certificate Signing Request)就是證照籤名請求檔案,首先建立一個域名RSA私鑰(不要使用上面的賬號私鑰)。

openssl genrsa 4096 > domain.key

接著就可以生成CSR檔案了,在生成CSR檔案的時候最好把帶www和不帶www兩個域名都新增進去,如果有其他子域名再依次新增。

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:kikoroc.com,DNS:www.kikoroc.com")) > domain.csr

配置站點驗證檔案

這個主要是用於Let's Encrypt來驗證你對域名的所有權的,跟一些搜尋引擎的站點認證原理差不多,在你的伺服器上生成一個隨機檔案,再通過指定的域名訪問,如果訪問得到就說明你對域名有所有權。

首先建立驗證檔案目錄:

mkdir -p /var/www/challenges/

接著修改nginx配置:

server {
    listen 80;
    server_name kikoroc.com www.kikoroc.com;

    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }

    ...the rest of your config
}

獲取網站證照

先獲取acme-tiny.py指令碼。

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

使用acme-tiny生成站點證照。

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt

這個指令碼就會驗證上面生成的驗證檔案,驗證通過就會生成站點的證照檔案signed.crt

在nginx中安裝證照

在nginx中,還需要將Let's Encrypt的中間證照和網站證照合在一起:

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem

配置nginx ssl

server {
    listen 443;
    server_name kikoroc.com, www.kikoroc.com;

    ssl on;
    ssl_certificate /path/to/chained.pem;
    ssl_certificate_key /path/to/domain.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
    ssl_session_cache shared:SSL:50m;
    ssl_dhparam /path/to/server.dhparam;
    ssl_prefer_server_ciphers on;

    ...the rest of your config
}

server {
    listen 80;
    server_name kikoroc.com, www.kikoroc.com;

    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }

    ...the rest of your config
}

自動更新證照指令碼

Let's Encrypt證照每次只有90天的有效期,可以通過指令碼定期更新,so easy~

建立自動更新指令碼renew_cert.sh:

#!/usr/bin/sh
python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem

cat /tmp/signed.crt intermediate.pem > /path/to/chained.pem

service nginx reload

新增crontab定時任務:

0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log

https引起的問題

一切配置好後以為萬事大吉,chrome開啟網站一看,雖然是https協議的,但是並沒有期望中的小綠鎖。開啟chrome開發者工具發現問題所在:

Mixed Content: The page at 'https://kikoroc.com/sadsadsa' was loaded over HTTPS, but requested an insecure script 'http://www.qq.com/404/search_children.js'. This request has been blocked; the content must be served over HTTPS.
Mixed Content: The page at 'https://kikoroc.com/sadsadsa' was loaded over HTTPS, but requested an insecure image 'http://kikoroc.qiniudn.com/double.jpg'. This content should also be served over HTTPS.
GET https://push.zhanzhang.baidu.com/push.js net::ERR_INSECURE_RESPONSE

簡單來說,就是網頁中使用了一些第三方的http資源,這些被認為是有安全隱患的!

這些第三方資源又可以分為可控和不可控兩類,比如第三方的圖片等資源我們可以轉存到自己的cdn服務商,對於不可控的第三方資源先嚐試是否支援https,如果支援的話將引用的地方統一修改成引用地址,比如將http://push.zhanzhang.baidu.com/push.js修改為//push.zhanzhang.baidu.com/push.js;如果第三方不支援https那就暫時沒什麼辦法了,比如騰訊公益404專案暫時就不支援https訪問,只能去掉了。

上面說到轉存到自己的cdn服務商,這裡的前提條件是你的cdn服務支援https協議。本站採用的是qiniu的cdn,https服務現在是要收費的,不過對於我這類部落格網站來說,價格還是能接受的。開通qiniu https域名服務後,將文章中的qiniu http域名替換成https的域名即可。

批量替換https域名:

find . -type f | xargs sed -i '' 's/http:\/\/kikoroc.qiniudn.com/https:\/\/odxth7737.qnssl.com/g'

對於duoshuo的頭像和表情,推薦使用 https://github.com/rainwsy/duoshuo-https 解決。

期望的小綠鎖終於出現了~~~

-EOF-

相關文章