又省了一千多塊錢

  • 2020 年 2 月 21 日
  • 筆記

「 閱讀本文大概需要 5 分鐘。 」

現在爬蟲的文章,面臨的一個很大的問題就是網站改版問題。本來好好地寫了一篇文章,結果過了幾天網站改版了,案例就跑不通了,文章就沒有意義了。

我也為此深感頭痛,之前我的書《Python3網路爬蟲開發實戰》裡面的很多案例已經失效了,大部分的原因都是選取的案例網站改版了,要麼是不能訪問了,要麼是改樣式了,要麼是改邏輯了,要麼是加反爬蟲了。這一變,導致程式碼、文章內容都完全沒法用了,但書已經印刷了,內容又不好改,頂多在 GitHub 上面改過來,但大部分讀者看書的時候發現又發現對應不起來,頻繁的變動和改版實在是讓我焦頭爛額。

解決方案

所以,怎麼解決呢?那就是自建爬蟲練習平台。

首先,自建練習平台,這樣我的平台是完全受我控制的,就不會再出現網站改版或案例失效的問題了;另外自建平台還有個好處就是避免了很多不必要的麻煩,之前很多人寫爬某多多、某寶、搞某驗、搞某雲,收到過警告甚至律師函,所以接下來我不會再寫具體爬某個網站了,所有的案例包含的知識點全部遷移到自建平台上面,這樣也規避了很多風險。練習平台的案例都把想要講解的知識點融進去,比如講驗證碼,就對接驗證碼的案例;講代理,就做一個能檢測 IP 頻率並反爬的案例;講 JavaScript 逆向的,就專門做 JavaScript 混淆的案例。接下來《Python3網路爬蟲開發實戰(第二版)》的案例將會全部遷移到自建平台上面,現在已經完成了一部分了。

案例的程式碼全部公開:https://github.com/Germey/Scrape,大家可以到這裡體驗下或者來監控我的進度。

話說回來

不過,這節文章內容並不是為了說這個的,是說著省了 1000 多塊錢的事的。

咋回事呢?因為要做練習平台嘛,所以一定需要一個域名的,我自己常用的域名就是 cuiqingcai.com,就是我的名字加上 .com,所以這個練習平台我自己想了一個二級域名,就叫做 scrape.cuiqingcai.com,然後每個案例都用它的子域名,比如 xxx.scrape.cuiqingcai.com,其中前面的 xxx 就是案例的名字,比如現在已經成功搭建的有 static1.scrape.cuiqingcai.com,就是一個簡易的靜態網站,可以供靜態網站爬取。

截圖如下:

樣例

在這裡有人要說,為什麼不用子路徑呢?比如 scrape.cuiqingcai.com/static1,之前試過了,每個案例都是獨立的,會造成很多路由衝突的問題,不如用三級域名。

問題

好,那麼問題來了,現在很多網站都需要 HTTPS 化,非 HTTPS 的網站都會提示不安全,所以我需要為每個三級站點申請一個 HTTPS 證書。現在每個案例都對應一個三級域名,隨著案例的變多,我不能每次都單獨申請個 HTTPS 證書吧,這太麻煩了。我現在用的是騰訊雲,現在證書都是從 TrustAsia 來申請的,現在還有單域名 20 個的限制。這肯定不行啊,所以我肯定要申請一個通配符三級域名證書,那就是 *.scrape.cuiqingcai.com,這樣它可以適用於平台的每個案例,因為每個案例都是符合這個域名規則的,如 static1.cuiqingcai.com 是能夠使用 *.scrape.cuiqingcai.com 這個證書的。

好,那麼這證書咋搞呢?騰訊雲官方是不支援直接申請免費的泛域名證書的,得買。

多少錢呢?分了好多種吧,有企業級 OV、增強型 EV、域名型 DV 等等,看看價格。

企業型

企業型就算了,好幾萬呢,不了不了。

域名型

最便宜的,域名型 DV,一年 1699,說貴倒不是很貴。

但是我這平台可能得一直維護好多年呢,一年為了個證書單獨搞個 1699,想了想是有點那啥。

尋路

然後我就去找有沒有免費的,找到了這麼個網站:https://freessl.cn/,它可以申請免費的 SSL 證書,甚至泛域名的也可以,這個是 Let's Encrypt V2 頒發的,可以可以。

為此,我興緻勃勃去試了試,但試了好幾種方法要麼是在頒發的時候卡殼,要麼是在 DNS 解析的時候卡殼,算了不用了,你們可以試試。

使用截圖

然後看了看控制台,發現這個網站它有這麼個收費項目「證書自動化」,用的是 acme.sh 自動化,還收費一塊錢。

證書自動化

得了,開源項目封裝了一下,就能收費了。

算了我還是自己搞搞吧。

然後我就找到了 acme.sh 這個項目,GitHub 地址是:https://github.com/acmesh-official/acme.sh。

好,下面一段貼一下 acme.sh 的官方介紹和使用方法吧,不是我寫的,直接拿來了。

注意:下面這個「acme.sh 介紹」這一段是來自官方介紹,不想看的可以跳過。

acme.sh 介紹

acme.sh 實現了 acme 協議, 可以從 Let's Encrypt 生成免費的證書.

主要步驟

1.安裝 acme.sh2.生成證書3.copy 證書到 nginx/apache 或者其他服務4.更新證書5.更新 acme.sh6.出錯怎麼辦, 如何調試

下面詳細介紹。

安裝 acme.sh

安裝很簡單, 一個命令:

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

普通用戶和 root 用戶都可以安裝使用。

安裝過程進行了以下幾步:

1) 把 acme.sh 安裝到你的 home 目錄下:

~/.acme.sh/

並創建 一個 bash 的 alias, 方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

2) 自動為你創建 cronjob, 每天 0:00 點自動檢測所有的證書, 如果快過期了, 需要更新, 則會自動更新證書。

更高級的安裝選項請參考: https://github.com/Neilpang/acme.sh/wiki/How-to-install

安裝過程不會污染已有的系統任何功能和文件,所有的修改都限制在安裝目錄中: ~/.acme.sh/

生成證書

acme.sh 實現了 acme 協議支援的所有驗證協議。

一般有兩種方式驗證:http 和 dns 驗證。

1.http 方式需要在你的網站根目錄下放置一個文件,來驗證你的域名所有權,完成驗證. 然後就可以生成證書了。

acme.sh  --issue  -d mydomain.com -d www.mydomain.com  --webroot  /home/wwwroot/mydomain.com/

只需要指定域名,並指定域名所在的網站根目錄。acme.sh 會全自動的生成驗證文件,並放到網站的根目錄,然後自動完成驗證。最後會聰明的刪除驗證文件,整個過程沒有任何副作用。

如果你用的 apache 伺服器, acme.sh 還可以智慧的從 apache 的配置中自動完成驗證,你不需要指定網站根目錄:

acme.sh --issue  -d mydomain.com   --apache

如果你用的 nginx 伺服器或者反代,acme.sh 還可以智慧地從 *

nginx *

的配置中自動完成驗證,你不需要指定網站根目錄:

acme.sh --issue  -d mydomain.com   --nginx

注意:無論是 apache 還是 nginx 模式, acme.sh 在完成驗證之後, 會恢復到之前的狀態, 都不會私自更改你本身的配置。好處是你不用擔心配置被搞壞,也有一個缺點,你需要自己配置 ssl 的配置,否則只能成功生成證書,你的網站還是無法訪問 https。但是為了安全, 你還是自己手動改配置吧。

如果你還沒有運行任何 web 服務,80 埠是空閑的,那麼 acme.sh 還能假裝自己是一個 webserver,臨時聽在 80 埠,完成驗證:

acme.sh  --issue -d mydomain.com   --standalone

更高級的用法請參考: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert

1.手動 dns 方式,手動在域名上添加一條 txt 解析記錄, 驗證域名所有權。

這種方式的好處是:你不需要任何伺服器, 不需要任何公網 ip,只需要 dns 的解析記錄即可完成驗證。壞處是:如果不同時配置 Automatic DNS API,使用這種方式 acme.sh 將無法自動更新證書,每次都需要手動再次重新解析驗證域名所有權。

acme.sh  --issue  --dns   -d mydomain.com

然後 acme.sh 會生成相應的解析記錄顯示出來,你只需要在你的域名管理面板中添加這條 txt 記錄即可。

等待解析完成之後, 重新生成證書:

acme.sh  --renew   -d mydomain.com

注意第二次這裡用的是 --renew

dns 方式的真正強大之處在於可以使用域名解析商提供的 api 自動添加 txt 記錄完成驗證。

acme.sh 目前支援 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等數十種解析商的自動集成。

以 dnspod 為例,你需要先登錄到 dnspod 帳號, 生成你的 api id 和 api key,都是免費的。

然後:

export DP_Id="1234"  export DP_Key="sADDsdasdgdsf"  acme.sh   --issue   --dns dns_dp   -d aa.com  -d www.aa.com

證書就會自動生成了。這裡給出的 api id 和 api key 會被自動記錄下來,將來你在使用 dnspod api 的時候, 就不需要再次指定了。

直接生成就好了:

acme.sh  --issue   -d  mydomain2.com   --dns  dns_dp

更詳細的 api 用法: https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

最後,本文並非完全的使用說明, 還有很多高級的功能, 更高級的用法請參看其他 wiki 頁面:https://github.com/Neilpang/acme.sh/wiki。

我的操作

嗯,上面的文檔讀起來有點彆扭,感覺像是機器翻譯,就在這裡做一下記錄了,看不懂也沒啥關係。

通過看 acme.sh 文檔的內容,大體了解到這麼幾件事:

•acme.sh 支援剛才所說的 Let's Encrypt 機構,而且是默認使用 Let's Encrypt,因此可以用它來頒發我的三級域名證書。•acme.sh 支援自動化 DNS 驗證。•acme.sh 可以實現自動化,可以配置定時更新。

舒服了,開搞!

這裡我的域名解析用的騰訊雲,也就是 DNSPod,怎麼實現自動化 DNS 驗證呢?當然是 API 了,在 https://console.dnspod.cn/account/token 申請一個 API Token 就行了:

DNSPod Token 申請

然後照著文檔說的,設置下環境變數:

export DP_Id='135818'  export DP_Key='c6135f12abd2xxxxxxx98395a5326905'

這裡換成你自己的。

然後調用 acme.sh 的命令,指定域名,還有 dns 的類型為 DNSPod。

最重要的,生成命令:

acme.sh --issue -d '*.scrape.cuiqingcai.com' --dns dns_dp

運行結果類似如下:

運行結果

運行完就 OK 了。

證書的路徑在最後它會告訴我們。

我的伺服器是 Nginx,所以我需要用現在生成的證書轉成 Nginx 專用的證書格式,命令如下:

acme.sh --installcert -d '*.scrape.cuiqingcai.com' --key-file './*.scrape.cuiqingcai.com.key' --fullchain-file './*.scrape.cuiqingcai.com.crt'

這樣本地就會生成 Nginx 專用的證書,直接使用即可。

要用的話,配置類似如下:

http {      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      ssl_prefer_server_ciphers on;      server {          listen 80;          server_name <mydomain>.com;          return 301 https://<mydomain>.com;      }      server {          listen 443 ssl;          ssl_certificate  /etc/nginx/ssl/<domain>.crt;          ssl_certificate_key  /etc/nginx/ssl/<domain>.key;      }  }

我們也可以使用 acme.sh 的 installcert 命令來實現自動安裝,具體可以參考:https://www.jianshu.com/p/b6b172f69c14,我這裡是用的 Kubernetes,就不直接這麼配置了。

最後,自動化的話,大家看自己具體怎麼弄了,我是用的 Kubernetes,只需要用 kubectl 創建一個 tls 類型的 secret 就行了,樣例命令如下:

kubectl create secret tls tls-scrape-cuiqingcai-com -n scrape --cert '*.scrape.cuiqingcai.com.crt' --key '*.scrape.cuiqingcai.com.key' 

Let's Encrypt 的證書有效期是 90 天,為了實現自動化更新,我們可以上面的幾步命令寫到一個腳本,然後使用 crontab 直接運行就好了。

最後部署成功,打開網站 https://static1.scrape.cuiqingcai.com/,驗證下,看看證書:

證書

沒問題,三級泛域名證書配置成功!過期時間是 90 天,到時候自動 crontab 更新即可。

嗯,就這麼省了一千多塊錢。

踩坑

在中間曾經遇到過這麼一個錯誤:

Verify error:CAA record for *.scrape.cuiqingcai.com prevents issuance.

本來懷疑是 DNSPod 不支援 CAA 記錄解析,結果發現不是的,是因為我給 scrape.cuiqingcai.com 配置了 CNAME,如果設置了 CNAME,請求 CAA 記錄但是沒有設置就會返回 CNAME,然後去查找 CNAME 域名的 CAA 記錄。所以可以先把 CNAME 的解析禁用,再執行即可。

踩坑參考來源:https://www.v2ex.com/t/511217,感謝 V2EX。

檢測

最後,大家的 SSL 證書情況可以到 https://www.ssllabs.com/ssltest/analyze.html 來檢查下,檢查一些配置的安全程度,介紹如下:

This free online service performs a deep analysis of the configuration of any SSL web server on the public Internet. Please note that the information you submit here is used only to provide you the service. We don't use the domain names or the test results, and we never will.

比如我這個配置完了,檢查級別為 A+,還不錯!

檢查結果

本文參考

•https://www.zybuluo.com/xiaoyixy/note/1055898#c3•https://cloud.tencent.com/developer/article/1140719•https://www.jianshu.com/p/b6b172f69c14•https://www.ssllabs.com/ssltest/analyze.html•https://github.com/Germey/Scrape•https://www.v2ex.com/t/511217

崔慶才丨靜覓