申請Let's Encrypt永久免費SSL證書過程教程及常見問題,及續期
近幾年,在瀏覽器廠商的強力推動下,HTTPS的使用率大增。據統計,Firefox載入的網頁中啟用HTTPS的佔比為67%,谷歌搜尋結果中HTTPS站點佔比已達50%,HTTPS網站已獲得瀏覽器和搜尋引擎的共同青睞。據悉,瀏覽器開發商Mozilla,Google準備採取下一步措施:將所有的HTTP網站標記為不安全。
近兩年,微信小程式也異常火爆,小程式相關話題頻頻在朋友圈刷屏。如果你想開發微信小程式,一樣繞不開HTTPS。根據微信小程式開發文件介紹,小程式與伺服器互動必須使用HTTPS協議。
不管是大勢所趨,還是實際專案開發需要,掌握如何給網站新增HTTPS協議支援(Web伺服器設定使用SSL證書後,網站就能支援HTTPS訪問了)都是非常有必要的。
一般來說,很多公司都會直接購買由GlobalSign、GeoTrust、Verisign等全球公認的數字證書頒發機構頒發的SSL證書。購買?沒錯,大多數SSL證書都需要按年付費使用,而且價格不菲。很多小公司、創業團隊或個人開發者往往不願意承擔這筆費用,那有沒有免費的SSL證書可以使用?
Let's Encrypt 是一個免費、開放,自動化的證書頒發機構,由 ISRG(Internet Security Research Group)運作。ISRG 是一個關注網路安全的公益組織,其贊助商包括 Mozilla、Akamai、Cisco、EFF、Chrome、IdenTrust、Facebook等公司。ISRG 的目的是消除資金和技術領域的障礙,全面推進網站從HTTP到HTTPS過度的程序。
目前,包括FireFox、Chrome在內的主流瀏覽器都支援Let's Encrypt證書,已經有不少使用者在真實專案中使用Let's Encrypt證書。Let's Encrypt免費SSL證書的有效期是90天,到期後可以再續期,這樣也就可以變相長期使用了。
實驗環境
- Ubuntu 14.04.2 LTS
- Python 2.7.6
- tomcat-7.0.68
PS:所有不說明實驗環境的技術文章都是耍流氓!
筆者使用的是一臺 Ubuntu 測試機,上面沒有跑 Apache 和 Nginx,單獨執行的 Tomcat,然後通過 iptables 進行埠轉發(將 80 埠的請求轉發到 8080,將 443 埠的請求轉發到 8443),並且已完成域名解析。
獲取Let's Encrypt免費SSL證書
- # 使用git下載指令碼
- $ git clone https://github.com/letsencrypt/letsencrypt
- # 進入到指令碼所在目錄
- $ cd letsencrypt
- # 檢視 letsencrypt-auto 工具的用法
- $ ./letsencrypt-auto --help
指令碼下載好了,來看看怎麼使用吧。letsencrypt-auto工具的用法如下:
- [email protected]:~/letsencrypt# ./letsencrypt-auto --help
- -------------------------------------------------------------------------------
- letsencrypt-auto [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...
- Certbot can obtain and install HTTPS/TLS/SSL certificates. By default,
- it will attempt to use a webserver both for obtaining and installing the
- certificate. The most common SUBCOMMANDS and flags are:
- obtain, install, and renew certificates:
- (default) run Obtain & install a certificate in your current webserver
- certonly Obtain or renew a certificate, but do not install it
- renew Renew all previously obtained certificates that are near expiry
- -d DOMAINS Comma-separated list of domains to obtain a certificate for
- --apache Use the Apache plugin for authentication & installation
- --standalone Run a standalone webserver for authentication
- --nginx Use the Nginx plugin for authentication & installation
- --webroot Place files in a server's webroot folder for authentication
- --manual Obtain certificates interactively, or using shell script hooks
- -n Run non-interactively
- --test-cert Obtain a test certificate from a staging server
- --dry-run Test "renew" or "certonly" without saving any certificates to disk
- manage certificates:
- certificates Display information about certificates you have from Certbot
- revoke Revoke a certificate (supply --cert-path)
- delete Delete a certificate
- manage your account with Let's Encrypt:
- register Create a Let's Encrypt ACME account
- --agree-tos Agree to the ACME server's Subscriber Agreement
- -m EMAIL Email address for important account notifications
- More detailed help:
- -h, --help [TOPIC] print this message, or detailed help on a topic;
- the available TOPICS are:
- all, automation, commands, paths, security, testing, or any of the
- subcommands or plugins (certonly, renew, install, register, nginx,
- apache, standalone, webroot, etc.)
- -------------------------------------------------------------------------------
這裡只對幾個重要的命令引數進行說明:
- run:獲取並安裝證書到當前的Web伺服器
- certonly:獲取或續期證書,但是不安裝
- renew:在證書快過期時,續期之前獲取的所有證書
- -d DOMAINS:一個證書支援多個域名,用逗號分隔
- --apache:使用 Apache 外掛來認證和安裝證書
- --standalone:執行獨立的 web server 來驗證
- --nginx:使用 Nginx 外掛來認證和安裝證書
- --webroot:如果目標伺服器已經有 web server 執行且不能關閉,可以通過往伺服器的網站根目錄放置檔案的方式來驗證
- --manual:通過互動式方式,或 Shell 指令碼手動獲取證書
關於域名驗證和證書的獲取安裝,上面提到了5種方式:--apache, --standalone, --nginx, --webroot 和 --manual,請根據實際情況選擇其一。再次重申,筆者使用的是公司的其中一臺測試機,上面沒有跑 Apache 和 Nginx,單獨執行的 Tomcat,然後通過 iptables 進行埠轉發(將 80 埠的請求轉發到 8080,將 443 埠的請求轉發到 8443),並且已完成域名解析。因此,筆者選擇採用 --standalone 方式進行域名驗證和證書獲取。
- # 獲取證書
- $ ./letsencrypt-auto certonly --standalone --email [email protected] -d quqianzhao.top -d www.quqianzhao.top
此處需要注意:
(1)執行此命令必須使用 root使用者獲得資料夾的許可權
(2)域名能訪問並且有繫結的公網IP
(3)必須在此域名繫結的伺服器上執行
(4)會使用80斷埠,如果nginx監聽80埠,把nginx先關掉
注意將上面的郵箱和域名替換成自己的。上面命令中的 certonly 表示只獲取證書,不安裝;-d 有兩個,表示將要獲取的SSL證書繫結兩個域名。
上面的命令在執行過程中,會有兩次確認。命令執行完成後,如果看到提示資訊"Congratulations! Your certificate and chain..."就說明證書建立成功了,如下圖所示。
如果使用nginx,可以直接在nginx上配置,具體參見https://blog.csdn.net/u013378306/article/details/80029828,把自己生成的正證書替換一下
server {
listen 443 ssl;
server_name kf.aigoes.com;
#ssl on;
ssl_certificate /etc/letsencrypt/live/quqianzhao.top/fullchain.pem; #2
ssl_certificate_key /etc/letsencrypt/live/quqianzhao.top/privkey.pem; #3
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
location /aaa {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 3600s;
proxy_pass http://127.0.0.1:8080;
}}
Tomcat7配置Let's Encrypt免費SSL證書
從上圖(證書獲取成功的提示資訊)可以看出,獲取到的 Let's Encrypt 證書儲存在 /etc/letsencrypt/live/quqianzhao.top/ 目錄下,相關的證書檔案有4個:
- cert.pem
- chain.pem
- fullchain.pem
- privkey.pem
我們需要用到的是後面兩個證書檔案: fullchain.pem 和 privkey.pem。接下來,還需要用到 Linux 下的 openssl 和 keytool 工具,將SSL證書由 .pem 格式轉換成 Tomcat 所支援的 .jks 格式。
- # 匯出.p12格式的證書
- $ openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out zyxx_letsencrypt.p12 -name tomcat_letsencrypt
- # 再將證書由.p12格式轉換成.jks格式
- $ keytool -importkeystore -deststorepass 'zxxx_123' -destkeypass 'zxxx_123' -destkeystore zyxx_letsencrypt.jks -srckeystore zyxx_letsencrypt.p12 -srcstoretype PKCS12 -srcstorepass 'zxxx_123' -alias tomcat_letsencrypt
說明:執行 openssl 命令匯出 .p12 格式證書時會要求設定金鑰,執行 keytool 命令時也有3處要寫金鑰,最簡單的方式就是所有需要金鑰的地方,都使用同一個,這樣也不會搞混。
經過上面的兩步操作,/etc/letsencrypt/live/quqianzhao.top/ 目錄下就生成了一個新的證書 zyxx_letsencrypt.jks。接下來,修改 %tomcat%/conf/server.xml 檔案,新增 keystoreFile 和 keystorePass 兩行配置。其中,keystoreFile 指向 jks 證書檔案,而 keystorePass 則為證書的金鑰。修改後的關鍵配置如下:
- <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
- maxThreads="150" scheme="https" secure="true"
- clientAuth="false" sslProtocol="TLS"
- keystoreFile="/home/test/zyxx_letsencrypt.jks"
- keystorePass="zxxx_123"
- />
OK,到這裡 Tomcat 的配置工作就完成了。接下來,重啟 Tomcat,然後使用瀏覽器訪問 https://www.quqianzhao.top 來驗證伺服器證書是否生效。
檢視伺服器證書資訊:
Let's Encrypt 證書續期
出於安全原因,Let's Encrypt 頒發的 SSL 證書有效期為90天,我們可以通過自動續期來解決。如果到期沒有更新證書,Let's Encrypt 會向申請證書時提交的email傳送提醒郵件。
進入到 letsencrypt-auto 指令碼所在目錄,執行下面的命令即可完成 SSL 證書的續期。
- ./letsencrypt-auto renew
預設情況下,在證書即將到期之前才能執行續期操作,否則會提示“Cert not yet due for renewal”,即證書尚未到期。如果需要強制執行續期操作,可以加上引數 --force-renew ,命令如下:
- ./letsencrypt-auto renew --force-renew
以下是筆者強制執行證書續期的操作結果:
- [email protected]:~/letsencrypt# ./letsencrypt-auto renew --force-renew
- Saving debug log to /var/log/letsencrypt/letsencrypt.log
- -------------------------------------------------------------------------------
- Processing /etc/letsencrypt/renewal/quqianzhao.top.conf
- -------------------------------------------------------------------------------
- Plugins selected: Authenticator standalone, Installer None
- Renewing an existing certificate
- Performing the following challenges:
- tls-sni-01 challenge for quqianzhao.top
- tls-sni-01 challenge for www.quqianzhao.top
- Waiting for verification...
- Cleaning up challenges
- -------------------------------------------------------------------------------
- new certificate deployed without reload, fullchain is
- /etc/letsencrypt/live/quqianzhao.top/fullchain.pem
- -------------------------------------------------------------------------------
- -------------------------------------------------------------------------------
- Congratulations, all renewals succeeded. The following certs have been renewed:
- /etc/letsencrypt/live/quqianzhao.top/fullchain.pem (success)
- -------------------------------------------------------------------------------
考慮到有可能會忘記續期,或者每3個月就要續期一次太麻煩,可以使用 linux crontab 每兩個月(0 0 1 */2 *)執行一次證書續期操作。
關於 https 頁面使用http請求的問題
首先https頁面不支援http請求,會報錯 Mixed Content:This request has been blocked; the content must be served over HTTPS.,
(1)如果請求的地址可以為https,則可以直接在<head> 中加入
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
(2)可以在相應的頁面的<head>里加上這句程式碼,意思是自動將http的不安全請求升級為https
如果必須為http請求,則 可以使用<iframe> 把http請求的頁面巢狀進來
最後注意ssl 443埠 防火牆 問題
其他參考地址https://zhuanlan.zhihu.com/p/24996258?refer=diamondfsd