HTTP"S", "S" means secured

以前要將網站連線升級成HTTPS的話...

Let's Encrypt

Let's Encrypt是一個於2015年三季度推出的數位憑證認證機構,  
旨在以自動化流程消除手動建立和安裝憑證的複雜流程,  
並推廣使全球資訊網伺服器的加密連接無所不在,為安全網站提供免費的SSL/TLS憑證。...

以上取自Let's Encrypt的維基百科頁面

先前準備工作

  1. 本安裝過程假設使用者的OS是CentOS 7,並且已經設定好一個可以用sudo指令取得root權限的使用者。
  2. 必須要有一個自己擁有的網域名稱(就是上一篇文章在教的事情)。
  3. 這個網域名稱已經設定好A指向到你的VPS主機(也是上一篇文章在教的事情)。
  4. 最好按照先前的文章的事情都已經做過了,像是安裝好Nginx。因為我們的HTTPS機制會建構在Nginx上。 如果以上這些條件都滿足的話,那就已經準備好,可以來為VPS主機上的服務來建立HTTPS連線了。

目標:安裝萬用字元憑證

要用什麼工具來做到自動(幾乎)申請憑證,而且還要能自動更新?

確定有設定好Nginx,並且目前是在背景常駐中

再設定一下Nginx的設定檔裡的Server區塊

sudo vim /etc/nginx/conf.d/default.conf

找到server區塊,在server_name屬性裡填入上一篇文章中申請好的Domain,在這裡我們先假設我們申請的domain叫example.com,打上domain本身與前面加上*號的,空白隔開。

 server{

    listen       80;
    server_name  example.com *.example.com;  #增加的部分

   ### .....以下省略
 }

改完後存檔離開。

:x

再用這個指令檢查設定檔是否都正確無誤

sudo nginx -t

再讓Nginx重新讀取設定檔

sudo systemctl reload nginx

安裝acme.sh

curl  https://get.acme.sh | sh

再重新登入一下,讓新安裝的acme.sh生效

logout

到Digital Ocean的管理後台,生成一組api key準備給acme.sh使用

回到VPS的terminal上,執行acme.sh來取得憑證

export DO_API_KEY="....那個APIKey"

這個動作是把一個叫DO_API_KEY的變數曝露到目前的ssh session底下,等等acme.sh在執行的時候,就會抓取並拿去使用,如果是別間DNS廠商的話,這個export的變數名稱就不相同,其他DNS業者的設定方式 可參考acme.sh的文件

acme.sh --issue --dns dns_dgon -d example.com -d *.example.com

注意到第二個-d後面是*.example.com 因為我們要申請的是萬用字元的憑證

[Web May 8 22:36:45 CST 2019] Your cert is in /home/yourusername/.acme.sh/yourdomain.com/yourdomain.com.cer
[Web May 8 22:36:45 CST 2019] Your cert key is in /home/yourusername/.acme.sh/yourdomain.com/yourdomain.com.key
[Web May 8 22:36:45 CST 2019] The intermediate CA cert is in /home/yourusername/.acme.sh/yourdomain.com/ca.cer
[Web May 8 22:36:45 CST 2019] And the full chain certs is there: /home/yourusername/.acme.sh/yourdomain.com/fullchain.cer

acme.sh 告訴你它把申請好的東西放到哪裡了,它在~/底下創了一個.acme.sh資料夾,然後再用你的domain名稱在那底下再創了一個資料夾,放進了這四個檔案,
由上往下依序是

  1. 你的網域的憑證
  2. 你的網域的私鑰
  3. 中繼憑證
  4. fullChain

準備將上面的那些東西跟Nginx結合在一起

首先我們要先用acme.sh--installcert指令

acme.sh  --installcert  -d  <domain>.com   \
        --key-file   /etc/nginx/ssl/<domain>.key \
        --fullchain-file /etc/nginx/ssl/fullchain.cer \
        #--reloadcmd  "service nginx force-reload"

-d, --key-file, --fullchain-file後面要換成自己要放的地方,<domain>請換成自己的domain,上面的指令是放在Nginx預設的安裝目錄底下,
這個動作非常重要,一定要用這個指令來執行,不可以自己複製,因為在執行下去的過程中,acme.sh會建立起之後能夠自動讓它自動幫你更新憑證的機制。

接著打開Nginx的設定檔!

sudo vim /etc/nginx/conf.d/default.conf
 } #  ... 80的server block的結束大括號
server{

    server_name  example.com www.example.com;
    listen 443 ssl http2;                          #http2 可以順便寫上去 
    ssl_certificate /etc/nginx/ssl/fullchain.cer;  #就是上面的  --fullchain-file後面的值
    ssl_certificate_key /etc/nginx/ssl/<domain>.key; #就是上面的  --key-file後面的值  
    # 下面這四行是更加強ssl機制的設定
    ssl_session_cache shared:le_nginx_SSL:1m;
    ssl_session_timeout 1440m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    
    # 可能還會有一些額外的location的設定
}  #這個server區塊的結束大括號
nginx -t

再讓Nginx重新讀取設定

sudo systemctl force-reload nginx

這邊用的是force-reload,因為只用reload有可能會讓Nginx不會重新讀取憑證設定

更新 迪菲-赫爾曼(Diffie-Hellman) 參數

原因就是你的迪菲-赫爾曼(Diffie-Hellman) 參數的強度太弱了。

迪菲-赫爾曼密鑰交換(英語:Diffie–Hellman key exchange,縮寫為D-H) 是一種安全協定。
它可以讓雙方在完全沒有對方任何預先資訊的條件下通過不安全信道建立起一個金鑰。
這個金鑰可以在後續的通訊中作為對稱金鑰來加密通訊內容......

以上內容取自 維基百科 - 迪菲-赫爾曼密鑰交換

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

2048這個數字代表著計算的複雜程度,數字越大強度越強,算出來的時間也要花得越久。

sudo vim /etc/nginx/conf.d/default.conf

你會發現Certbot早就在你的設定檔裡加上了許多東西,找到 server區塊,找到ssl_dhparam這個參數,把值換成我們剛剛用openssl算完的那個檔案:

.....
server{
  ### .....其他部分省略
ssl_dhparam /etc/ssl/certs/dhparam.pem;
}

存檔並離開後,再用這個指令檢查設定檔是否都正確無誤

sudo nginx -t

再讓Nginx重新讀取設定檔

sudo systemctl reload nginx

你的網站現在更安全多了,再透過SSLLabs檢查一次,現在應該至少可以得到A等級。

設定憑證自動更新

Let's Encrypt的證書雖然是免費的,但是只有90天的有效期限,我們再來就是要設定每當證書失效時,我們可以自動重新跟Let's Encrypt申請證書。acme.sh在申請證書的同時,也同時幫我們設定好自動更新證書的排程了。

$ crontab -l
0 0 * * * "/home/ubuntu/.acme.sh"/acme.sh --cron --home "/home/ubuntu/.acme.sh" > /dev/null

手動更新一下證書,看看流程是否一切正確

acme.sh --cron -f

應該會重新申請了一次證書,並在最後自動重啟Nginx,而且不需要我們手動輸入密碼。

就這樣,我們的網站的HTTPS的設定就配置好了

要知道的地方是:

more reference

-- end of file--