在最近兩次 Jenkins LTS 資安更新後,都出現了如封面圖的錯誤,大意是「經由 https 訪問某個網址時,無法驗證該網站所提供的 SSL 憑證有效性」,但問題來了,我們明明看這個網站,幾乎從頭到尾都沒問題,就只有在管理者檢查 Plugins 是否有更新的情況下出現,為何會如此呢?
首先我們要設法辨別「真正的 Request URL」,以這個例子來說,架在公司內網的 Jenkins 不僅侷限於本機,會有部份對 Intranet,甚至於極少部份對 Internet 存取,預設的 Plugins 更新檢查就是其中一例。我們可以利用瀏覽器的開發者工具,看到錯誤訊息的出處,來自於 update-center-error 如下圖:
那又是什麼機制把這段話顯示出來呢?接著搜尋下去我們會發現,這段錯誤訊息是 Server 端直接丟下來的,而不是從 Client 端向 Internet 發送 Request 所得的錯誤,我們可以在查詢幾乎同時間的 System Log 發現佐證:
先確定問題來自於一個從 Server 端發送的 Request 之後,瀏覽器的開發者工具就可以關起來了,問題不在 Client Side。這時候我們剩下幾個方向:
可想而知,雖然 Jenkins 是 OpenSource,我們可以輕易地查到原始碼,但要從結果倒推回去,那麼多程式絶不是件簡單的事吧?側錄工具應該容易些,但問題是我們已經正式服務了,每分每秒都有很多 Request,有來自人的,也有來自排程的,很難請其他不相干的都先靜一靜,也先不列入考慮。所幸,在瀏覽器我們還是可以觀察到:
在預設狀況下,Jenkins 是向畫面中最底下那個 URL 查詢,所以我們回到 Server 端試試看。這裡要特別注意的是,完整的 URL 是必要的,如果只有主機名稱,可能會是不一樣的結果(讓你找不到答案):
看起來是能得到一樣的錯誤,那就有希望了。接著我們要拆解這一連串的重導,看是到哪個環節出的問題:
前兩步還順利,到了第三步鏡像站就沒反應了,所以把它展開看看,curl -v 得到一大串,最後會是:
Jenkins 發了一個 Request 往 westeurpoe.cloudflare.jenkins.io,但這個網址的 TLS handshake Unknown 失敗。那我們用另一個工具單獨驗證一下:
幾個深度的結果都一樣代表錯誤,看起來是 Fortinet 把憑證換掉了。我們比對其他網路位址的正常結果:
像這樣一層一層到信任根憑證才是正確的。