幫忙查了一個 FB 相關問題。

一般我們在 FB 貼文輸入網址時,FB 會擷取網頁資訊帶出標題、摘要、預覽圖,這些資訊來自網頁 HTML 所埋的 og 標籤,例如:

  <meta property=og:type content=article>
  <meta property=og:title content="Facebook 分享預覽測試">
  <meta property=og:description content="測試透過 og 標籤提供預覽資訊">
  <meta property=og:url content="https://output.jsbin.com/jokufer">
  <meta property=og:image content="https://i.imgur.com/nE2We37.png">
  <meta property=og:image:width content="660">
  <meta property=og:image:height content="378"> 

若遇到預覽結果不如預期,FB 有提供一個「分享偵錯工具」幫忙 Debug。(詳細介面請參考這篇:網頁小知識 - 美美的 FB/LINE 連結預覽是如何產生的?)

本次遇到的問題是,某網站在 FB 分享時預覽出現是舊資訊,而用分享偵錯工具無法更新,出現一個奇怪的 418 錯誤:

查了一下,418 是個奇妙的 HTTP 狀態碼,代表「我是一個茶壺」,是 IETF 網際網路工程任務組在 1998 年 4 月 1 日發布的惡搞 RFC - HTCPCP (Hyper Text Coffee Pot Control Protocol) 超文字咖啡壺控制協定,應用在控制、監測和診斷咖啡壺,後來也被拓展到茶壺。最終成為一個非標準 HTTP 狀態碼。(若想了解這段有趣的歷史,推薦這篇:搶救茶壺大作戰:418 I am a teapot)

爬文的心得,418 狀態碼最常出現在 WAF (網站應用程式防火牆) 阻擋爬蟲機器人或惡意程式的回應:

因此推論,最有可能是來自 FB 機器人的 HTTP 存取被 WAF 擋掉,Curl 等到 Timeout。但調閱 WAF 記錄核對時間點有找到 FB 機器人連上來的軌跡,請求並未被阻擋,Log 顯示是客戶端主動切斷連線。我查到 FB 文件,查到可用 whois -h whois.radb.net -- '-i origin AS32934' | grep ^route 列舉 Facebook 網路爬蟲來源 IP,用 curl -v --compressed -H "Range: bytes=0-524288" -H "Connection: close" -A "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" "$URL"模擬機器人行為。在 Windows 跑了一下可正常得到回應,莫非與來源 IP 有關,但也不可能從 FB 的 IP 發 HTTP GET 測試啊! 情陷入焦著之際,我找了一台 Azure Linux VM 試從美國跑 curl 得到不一樣的結果,案情有了突破,curl 回應 curl: (60) SSL certificate problem: unable to get local issuer certificate 錯誤。在 Windows 跑 curl 跟用瀏覽器連該網站沒問題,用 Linux 跑不行,合理推論是 Linux 不認得該 TLS 憑證的中繼 CA 憑證或根 CA 憑證。

網站 TLS 憑證 CLI 快速檢視工具檢查,發現是少裝了中繼 CA 憑證跟根 CA 憑證,Windows 平台可能靠自動更新或從其他來源取得中繼 CA 憑證,故可順利過關,應該可解釋為何移到 Linux 測試 curl 才重現問題。問題在補上中繼 CA 憑證後排除,我也學到新經驗:

HTTP 418 是 WAF 阻擋機器人常見的回應,但 Facebook 爬蟲機器人遇到 TLS 憑證異常時不會顯示詳細錯誤,而是歸納成 418 錯誤。


Comments

# by 小黑

太頂了

# by wen

謝謝您的說明, 補充相關討論 https://developers.facebook.com/community/threads/765686558643258/?locale=zh_TW

Post a comment