SSL證書及HTTP轉HTTPS
搭建的個人網站,申請公安備案時,提示我沒有證書。HTTP本身就是前期臨時措施,總之后面是要轉HTTPS的。因此走一遍HTTPS流程。
1.申請Let's Encrypt證書
窮人一個,當然是能省則省,證書不用高大上的,免費的最好,當然找Let's Encrypt了。
1.1 腳本
申請Let's Encrypt也不輕松,找來找去,certbot提示要安裝一堆包,實在煩。
搜索到一個github上的工程,acme.sh,一個腳本,深合朕意。鏈接:https://github.com/acmesh-official/acme.sh
1.1.1 依賴程序
acme.sh依賴於其他程序來完成相應證書申請、刷新、刪除等工作。
因此,需要加上openssl、curl所在的路徑后再執行
PATH=$PATH:/xxxx/bin ./acme.sh --issue -w /XXX/web -d YYYY.cn --server letsencrypt --preferred-chain "ISRG Root X1"
但會提示錯誤:
Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 60
搜索得到答案,將acme.sh中的curl --silent中加入一個-k參數即可(是由於客戶端缺少證書導致)。
再次運行后,即可得到正確的證書、私鑰等,位於當前用戶目錄的.acme.sh/YYYY.cn/下。
如需要方便后續的renew操作,可以通過install-cert命令將證書復制到指定位置,復制完成后並可執行reload命令(除命令當次會執行拷貝、並reload外,同時會的.acme.sh/YYYY.cn/YYYY.cn.conf文件中保存證書目標位置、reload命令,方便renew命令自動完成這些復雜動作)。
PATH=$PATH:/xxxx/bin /YYY/acme.sh-3.0.1/acme.sh --install-cert -d mingtech.net.cn --cert-file /ZZZZ/etc/ssl/certs/YYYY.cer --key-file /ZZZZ/etc/ssl/private/YYYY.cn.key --fullchain-file /ZZZZ/etc/ssl/certs/fullchain.cer --reloadcmd "systemctl reload nginx.service"
PS:當前用戶需要在/XXX/web目錄下有寫權限。
2. nginx服務上配置
首先,修改nginx的server配置模塊,將http定向到https。
server {
listen 80;
listen [::]:80;
server_name mingtech.net.cn;
# enforce https
return 301 https://$server_name$request_uri;
}
然后將證書、私鑰、DH文件及相關配置項配置上。
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mingtech.net.cn;
ssl_certificate /ZZZZ/etc/ssl/certs/fullchain.cer;
#ssl_certificate /ZZZZ/etc/ssl/certs/YYYY.cn.cer;
ssl_certificate_key /ZZZZ/etc/ssl/private/YYYY.cn.key;
# ECDH 系列交換算法依賴的DHparams文件,通過openssl dhparam -out dhparam.pem 2048/4096方式生成。
ssl_dhparam /ZZZZ/etc/ssl/dhparam_2048.pem;
# 開啟 OCSP Stapling ---當客戶端訪問時 NginX 將去指定的證書中查找 OCSP 服務的地址,獲得響應內容后通過證書鏈下發給客戶端。
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /ZZZZ/etc/ssl/certs/YYYY.cn.cer; #若 ssl_certificate 指令指定了完整的證書鏈,則 ssl_trusted_certificate 可省略。
resolver 8.8.8.8 8.8.4.4 216.146.35.35 216.146.36.36 valid=60s; #添加resolver解析OSCP響應服務器的主機名,valid表示緩存。
resolver_timeout 2s; # resolver_timeout表示網絡超時時間
#安全鏈接可選的加密協議
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 如果要提高SSL評分,應如下配置,關閉TLSv1 TLSv1.1的支持
#ssl_protocols TLSv1.2;
#可選的加密算法,順序很重要,越靠前的優先級越高.
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:HIGH:!RC4-SHA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
#在 SSLv3 或 TLSv1 握手過程一般使用客戶端的首選算法,如果啟用下面的配置,則會使用服務器端的首選算法.
ssl_prefer_server_ciphers on;
#儲存SSL會話的緩存類型和大小
ssl_session_cache shared:SSL:10m;
#緩存有效期
ssl_session_timeout 60m;
# topic first.
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
同時,使用fastCGI協議的location的,HTTPS字段需要從off修改為on
location ~ ^\/blog\/.*\.php(\/.*)*$ {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name = 404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
重啟nginx服務。
部署在雲上的服務器,需要在雲上開放443端口,通過frps透傳的,需要將添加frpc一個新的開放端口。
就可以將Web服務從HTTP切換至HTTPS了。
3.Let's Encrypt證書自動續期
Let's Encrypt雖然好用,但有效期只有90天,所以還是加上自動續期的功能。
root用戶下加上一個crond的任務:
# m h dom mon dow command
0 13 * * 1 PATH=$PATH:/xxxx/bin /YYY/acme.sh-3.0.1/acme.sh --renew -d YYYY.cn > /root/RenewCert_`date +\%Y-\%m-\%d_\%H_\%M`.log 2>&1
每周一的13點進行一次renew動作。