博客的遷移及自動(dòng)化部署并全站https化

過(guò)完年來(lái)想把博客做一個(gè)遷移,放到自己購(gòu)買(mǎi)的服務(wù)器上,并實(shí)現(xiàn)?自動(dòng)化部署,并啟用全站HTTPS

hexo本地部署

這一步驟網(wǎng)上有很多教程,這里不再多說(shuō)了

服務(wù)器自動(dòng)化部署

大體的流程就是,我們通過(guò)hexo g命令在本地生成靜態(tài)文件以后,通過(guò)git push到我們的遠(yuǎn)程倉(cāng)庫(kù)(這里我用的是GitHub),然后由于我們事先在項(xiàng)目庫(kù)中配置了webhooks,由它post到你的服務(wù)器一個(gè)請(qǐng)求鏈接,我們的服務(wù)器收到請(qǐng)求后,對(duì)應(yīng)執(zhí)行我們提前寫(xiě)好的腳本,再將push的內(nèi)容同步到我們的服務(wù)器,從而更新了服務(wù)器的內(nèi)容。

服務(wù)器環(huán)境配置

我們通過(guò)ssh(windows用戶(hù)可以通過(guò)putty登錄)登錄到我們的服務(wù),我這里用的是Ubuntu系統(tǒng),安裝好nodejs,git,nginx后,將我們的文件從遠(yuǎn)程倉(cāng)庫(kù)拉下來(lái)

mkdir blog
cd blog
git init
git remote add origin https://github.com/yuxingxin/yuxingxin.github.io.git
git pull origin master
  1. 配置nginx
    這個(gè)配置之前寫(xiě)的有相關(guān)文章,不明白得可以看這里,不過(guò)這里的系統(tǒng)是Ubuntu,所以nginx的安裝路徑也不太一樣(/etc/nginx)
    默認(rèn)我們需要在/etc/nginx/conf.d/目錄下添加配置文件blog.conf
    注意這里的后綴名一定是.conf
vim /etc/nginx/conf.d/blog.conf

然后配置上我們的域名,端口和映射地址

server {
    listen       80;  #修改這里為其他端口如8081
    server_name  yuxingxin.com www.yuxingxin.com; # 這里是你的域名
    location / {
        root   /root/blog/; #修改這里的路徑為自己的路徑
        index  index.html index.htm;
    }
}

然后重啟nginx通過(guò)域名就可以訪問(wèn)我們的博客了

nginx -s reload
  1. webhooks配置
    也就是人們常說(shuō)的鉤子,是一個(gè)很有用的工具。你可以通過(guò)定制 Webhook 來(lái)監(jiān)測(cè)你在 Github.com 上的各種事件,最常見(jiàn)的莫過(guò)于 push 事件,如果你設(shè)置了一個(gè)監(jiān)測(cè) push 事件的 Webhook,那么每當(dāng)你的這個(gè)項(xiàng)目有了任何提交,這個(gè) Webhook 都會(huì)被觸發(fā),這時(shí) Github 就會(huì)發(fā)送一個(gè) HTTP POST 請(qǐng)求到你配置好的地址。如此一來(lái),你就可以通過(guò)這種方式去自動(dòng)完成一些重復(fù)性工作;比如,你可以用 Webhook 來(lái)自動(dòng)觸發(fā)一些持續(xù)集成(CI)工具的運(yùn)作,比如 Travis CI;又或者是通過(guò) Webhook 去部署你的線上服務(wù)器。
    Webhook 的配置是十分簡(jiǎn)單的。首先進(jìn)入你的 repo 主頁(yè),通過(guò)點(diǎn)擊頁(yè)面上的按鈕 [settings] -> [Webhooks & service] 進(jìn)入 Webhooks 配置主頁(yè)面。在Payload URL配置鏈接,比如:
http://xxxxx.com:8246/webhooks/push/deploy

這樣一來(lái),倉(cāng)庫(kù)的配置就算好了,接下來(lái)看服務(wù)器端如何響應(yīng)

  1. 服務(wù)器配置webhooks響應(yīng)
    首先我們?cè)谖覀兊牟┛湍夸浵聞?chuàng)建一個(gè)js文件,用來(lái)啟動(dòng)我們的監(jiān)聽(tīng)服務(wù),端口就是我們?cè)趥}(cāng)庫(kù)配置那里的端口地址:8246
var http = require('http')
var exec = require('child_process').exec
http.createServer(function (req, res) {
    if(req.url === '/webhooks/push/deploy'){
        exec('sh ./deploy.sh',function(error,stdout,stderr){
         if(error){
          console.log(error.stack);
          console.log('Error code:'+ error.code);
         }else{
              console.log('success');
         }
    })
    }
    res.end()
}).listen(8246)

這段代碼就能啟動(dòng)一個(gè)nodejs服務(wù),監(jiān)聽(tīng)8246端口。
當(dāng)請(qǐng)求過(guò)來(lái)的url完全匹配的時(shí)候,執(zhí)行deploy.sh。
再新建一個(gè)deploy.sh文件處理部署相關(guān)腳本

git pull origin master
  1. 運(yùn)行nodejs服務(wù)
node ./webhooks.js

如果你使用上面的命令運(yùn)行nodejs服務(wù),nodejs服務(wù)會(huì)在前臺(tái)運(yùn)行,可以使用pm2使nodejs運(yùn)行在后臺(tái)。
安裝
npm install pm2 -g
啟動(dòng)服務(wù)
pm2 start webhooks.js
停止服務(wù)
pm2 stop webhooks.js
重啟服務(wù)
pm2 restart webhooks.js
另外我們也可以實(shí)時(shí)查看pm2的日志服務(wù)
pm2 logs

到此為止我們的自動(dòng)化部署就全部完成了,以后我們只需在本地將文件push到遠(yuǎn)程倉(cāng)庫(kù),就會(huì)自動(dòng)同步到我們的服務(wù)器上

啟用全站HTTPS

這里簡(jiǎn)單總結(jié)下在 Nginx 配置 HTTPS 服務(wù)器:主要簽署第三方可信任的證書(shū)和配置HTTPS

關(guān)于證書(shū)

SSL證書(shū)需要向國(guó)際公認(rèn)的證書(shū)證書(shū)認(rèn)證機(jī)構(gòu)(簡(jiǎn)稱(chēng)CA,Certificate Authority)申請(qǐng)。
CA機(jī)構(gòu)頒發(fā)的證書(shū)有3種類(lèi)型:

  • 域名型SSL證書(shū)(DV SSL):信任等級(jí)普通,只需驗(yàn)證網(wǎng)站的真實(shí)性便可頒發(fā)證書(shū)保護(hù)網(wǎng)站;
  • 企業(yè)型SSL證書(shū)(OV SSL):信任等級(jí)強(qiáng),須要驗(yàn)證企業(yè)的身份,審核嚴(yán)格,安全性更高;
  • 增強(qiáng)型SSL證書(shū)(EV SSL):信任等級(jí)最高,一般用于銀行證券等金融機(jī)構(gòu),審核嚴(yán)格,安全性最高,同時(shí)可以激活綠色網(wǎng)址欄。

關(guān)于證書(shū)服務(wù),市面上大體的都是收費(fèi)的證書(shū),當(dāng)然也有部分是免費(fèi)的,比如Let's Encrypt 剛剛又拍云也上線了免費(fèi)的 SSL 證書(shū),另外StartSSL也提供免費(fèi)證書(shū),有效期3年;另外還有騰訊云和阿里云都有相關(guān)的免費(fèi)證書(shū),這里我使用的是Let's Encrypt ,這也是目前最知名的開(kāi)源SSL證書(shū)。

證書(shū)申請(qǐng)

申請(qǐng) Let's Encrypt 證書(shū)不但免費(fèi),還非常簡(jiǎn)單,雖然每次只有 90 天的有效期,但可以通過(guò)腳本定期更新,配好之后一勞永逸。Let's Encrypt 的證書(shū)簽發(fā)過(guò)程使用的就是 ACME 協(xié)議,這里也推薦一個(gè)小工具就是acme-tiny,它可以幫助我們簡(jiǎn)化創(chuàng)建證書(shū)的流程。

  1. 創(chuàng)建帳號(hào)
    創(chuàng)建一個(gè)目錄存放私鑰證書(shū)等各種文件,然后進(jìn)入后創(chuàng)建我們的RSA賬戶(hù)私鑰
mkdir ssl
cd ssl
openssl genrsa 4096 > account.key
  1. 創(chuàng)建 CSR 文件
    這一步生成我們的證書(shū)簽名文件,即CSR,首先要?jiǎng)?chuàng)建RSA私鑰
openssl genrsa 4096 > domain.key

接下來(lái)就可以生成我們的證書(shū)文件了,單個(gè)域名和多個(gè)域名生產(chǎn)的參數(shù)還不太一樣.

//單個(gè)域名
openssl req -new -sha256 -key domain.key -subj "/CN=yuxingxin.com" > domain.csr
//多個(gè)域名(比如yuxingxin.com和www.yuxingxin.com)
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yuxingxin.com,DNS:www.yuxingxin.com")) > domain.csr
  1. 配置驗(yàn)證服務(wù)
    CA 在簽發(fā) DV(Domain Validation)證書(shū)時(shí),需要驗(yàn)證域名所有權(quán),而大部分都是通過(guò)郵件驗(yàn)證的方式,Let's Encrypt 則是在你的服務(wù)器上生成一個(gè)隨機(jī)驗(yàn)證文件,再通過(guò)創(chuàng)建 CSR 時(shí)指定的域名訪問(wèn),如果可以訪問(wèn)則表明你對(duì)這個(gè)域名有控制權(quán)。
    首先創(chuàng)建用于存放驗(yàn)證文件的目錄
mkdir ~/www/challenges/

然后配置一個(gè) HTTP 服務(wù),以 Nginx 為例:

server {
    listen       80;
    # 這里改成自己的域名
    server_name yuxingxin.com www.yuxingxin.com;
   
    location /.well-known/acme-challenge/ {
        alias /root/www/challenges/;
        try_files $uri =404;
    }
}
  1. 生成網(wǎng)站證書(shū)
    先把a(bǔ)cme-tiny腳本保存到之前的ssl目錄
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

指定賬戶(hù)私鑰、CSR 以及驗(yàn)證目錄,在ssl目錄下執(zhí)行腳本

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

如果一切正常,當(dāng)前目錄ssl下就會(huì)生成一個(gè) signed.crt,這就是申請(qǐng)好的證書(shū)文件。
這里遇到一個(gè)錯(cuò)誤,大致如下:

ValueError: Wrote file to /root/www/challenges/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg, but couldn't download http://www.yuxingxin.com/.well-known/acme-challenge/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg

網(wǎng)上查了一些方案,覺(jué)得有一個(gè)比較靠譜,也得到了解決,大致就是原來(lái)庫(kù)做了一個(gè)驗(yàn)證導(dǎo)致有些情況通不過(guò),這里有人fork源庫(kù)修改了部分代碼,地址在這里,如果出現(xiàn)上述錯(cuò)誤,可以獲取這個(gè)庫(kù)的腳步然后在執(zhí)行上面那條命令。

  1. 下載中間證書(shū)
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
  1. 為了后續(xù)能順利啟用 OCSP Stapling,我們?cè)侔迅C書(shū)和中間證書(shū)合在一起:
wget -O - https://letsencrypt.org/certs/isrgrootx1.pem > root.pem
cat intermediate.pem root.pem > full_chained.pem
  1. 修改nginx證書(shū)配置
server {
    listen 443;
    #修改成自己的域名
    server_name yuxingxin.com www.yuxingxin.com;

    ssl on;
    #這里注意證書(shū)路徑
    ssl_certificate /root/ssl/chained.pem;
    ssl_certificate_key /root/ssl/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 /root/ssl/dhparam.pem;
    ssl_prefer_server_ciphers on;
    resolver 8.8.8.8;
    ssl_stapling on;
    ssl_trusted_certificate /root/ssl/signed.crt;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;preload";

    location / {
        # 這里要改成自己存放博客靜態(tài)網(wǎng)頁(yè)的目錄
        root  /root/blog;
        index  index.html index.htm;
    }
}
server {
    listen       80;
    # 這里改成自己的域名
    server_name yuxingxin.com www.yuxingxin.com;
    ssl_certificate /root/ssl/chained.pem;
    ssl_certificate_key /root/ssl/domain.key;

    location / {
        return 301 https://$host$request_uri;
    }

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

    #error_page  404              /404.html;
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

配置自動(dòng)更新

Let's Encrypt 簽發(fā)的證書(shū)只有 90 天有效期,推薦使用腳本定期更新
創(chuàng)建腳本文件并賦予執(zhí)行權(quán)限

mkdir shell
cd shell
vi renew_cert.sh

并復(fù)制下面內(nèi)容

#!/bin/bash
cd /root/ssl/
python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir /root/www/challenges/ > signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
service nginx reload

這里借助crontab來(lái)定時(shí)執(zhí)行任務(wù),它是一個(gè)可以用來(lái)根據(jù)時(shí)間、日期、月份、星期的組合來(lái)調(diào)度對(duì)重復(fù)任務(wù)的執(zhí)行的守護(hù)進(jìn)程。
執(zhí)行

crontab -e

然后 添加如下內(nèi)容

0 0 1 * * /root/shell/renew_cert.sh >/dev/null 2>&1

這樣以后證書(shū)每個(gè)月都會(huì)自動(dòng)更新,一勞永逸。
另外這里也推薦一個(gè)網(wǎng)站,可以監(jiān)測(cè)你的證書(shū)的有效期
https://letsmonitor.org

這樣的話就算完了,但是這里有幾點(diǎn)做說(shuō)明

  • dhparam的生成
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
  • 強(qiáng)制HTTPS
#另外還有兩種其他的配置方式,可以自行Google
 location / {
        return 301 https://$host$request_uri;
    }
  • 關(guān)于HSTS
    HTTP Strict Transport Security的縮寫(xiě),即:“HTTP嚴(yán)格傳輸安全”。假設(shè)一個(gè)用戶(hù)從來(lái)沒(méi)有訪問(wèn)過(guò)我的網(wǎng)站,,并且他第一次訪問(wèn)的時(shí)候訪問(wèn)的是 http://yuxingxin.com ,在正常的情況下,我的服務(wù)器就會(huì)給這位用戶(hù)返回一個(gè) 301 跳轉(zhuǎn)到 https://yuxingxin.com ,并且?guī)仙厦媾渲玫腍STS頭,在用戶(hù)下次訪問(wèn)我的博客時(shí),只要 HSTS 還在有效期中,瀏覽器就會(huì)直接跳轉(zhuǎn)到相對(duì)應(yīng)的 https 頁(yè)面,并且這是不需要經(jīng)過(guò)數(shù)據(jù)傳輸?shù)?,直接在本地瀏覽器進(jìn)行的處理。
    目前大部分瀏覽器對(duì)HSTS的支持已經(jīng)相當(dāng)完美,具體各瀏覽器和版本的支持情況可以在這里上查看。 但是HSTS是有缺陷的,第一次訪問(wèn)網(wǎng)站的客戶(hù)端,HSTS并不工作。 要解決這個(gè)問(wèn)題,就需要我們下面要講解的HSTS preload list。它是一個(gè)站點(diǎn)的列表,并通過(guò)硬編碼寫(xiě)入 Chrome 瀏覽器中,列表中的站點(diǎn)將會(huì)默認(rèn)使用 HTTPS 進(jìn)行訪問(wèn),此外,F(xiàn)irefox 、Safari 、IE 11 和 Edge 也同樣用一份 HSTS 站點(diǎn)列表,它申請(qǐng)加入需要一些條件:
  • 有一張有效的證書(shū)(如果是使用了 SHA-1 證書(shū)簽名算法的必須在 2016 年前失效)
  • 重定向所有的 HTTP 流量到 HTTPS ( HTTPS ONLY )
  • 全部子域名的流量均通過(guò) HTTPS ,如果子域名的 www 存在的話也同樣需要通過(guò) HTTPS 傳輸。
  • 在相應(yīng)的域名中輸出 HSTS 響應(yīng)頭
    1 過(guò)期時(shí)間至少大于 18 周(10886400 秒)
    2 必須聲明 includeSubdomains
    3 必須聲明 preload
    4 跳轉(zhuǎn)過(guò)去的那個(gè)頁(yè)面也需要有 HSTS 頭
    點(diǎn)擊這里開(kāi)始申請(qǐng),申請(qǐng)成功后,你的域名就會(huì)加入到這個(gè)列表
    ssl.png

    如果大多數(shù)瀏覽器都已經(jīng)更新到新的列表,那么針對(duì)國(guó)內(nèi)的 VPS ,不打開(kāi)80端口,只打開(kāi) 443 ,瀏覽器同樣會(huì)跳轉(zhuǎn)過(guò)來(lái),這樣就可以免備案了,不過(guò)好像這樣對(duì)搜索引擎就不太友好。

測(cè)試

所有這些工作完成以后,我們可以對(duì)證書(shū)進(jìn)行檢測(cè)。這里是檢測(cè)地址 ,下面是我的域名的檢測(cè)報(bào)告。

report.jpeg

如果是A+,則說(shuō)明你的配置是好著的。另外這里也給出一個(gè)國(guó)內(nèi)也列一個(gè)檢測(cè)網(wǎng)站

另外上面如果覺(jué)得麻煩的話,這里推薦一個(gè)別人寫(xiě)的腳本,它是一個(gè)快速獲取/更新 Let's encrypt 證書(shū)的 shell script,使用該腳本可以簡(jiǎn)化上面的流程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 一切從劫持開(kāi)始說(shuō)起 在家上網(wǎng)瀏覽網(wǎng)頁(yè),第一次打開(kāi)瀏覽器,輸入網(wǎng)址,回車(chē),發(fā)現(xiàn)頁(yè)面右下角會(huì)出現(xiàn)一個(gè)大概300x300...
    figotan閱讀 8,652評(píng)論 2 49
  • 前段時(shí)間,看見(jiàn)很多大會(huì)都在分享全站HTTPS的經(jīng)驗(yàn)。HTTPS固然好,前提是SSL證書(shū),并且簽發(fā)證書(shū)的機(jī)構(gòu)要靠譜。...
    人世間閱讀 6,190評(píng)論 0 5
  • WWDC 16 中,Apple 表示將繼續(xù)在 iOS 10 和 macOS 10.12 里收緊對(duì)普通 HTTP 的...
    小如99閱讀 6,403評(píng)論 0 25
  • 為什么會(huì)寫(xiě)這樣一個(gè)題目? 因?yàn)榻裉鞂?shí)在想不到寫(xiě)作的話題,但為了保持寫(xiě)作的連續(xù)性,必須硬著頭皮寫(xiě)。 都寫(xiě)些什么呢? ...
    玄鳥(niǎo)天命閱讀 242評(píng)論 0 0

友情鏈接更多精彩內(nèi)容