LINE Bot 程式需要一個對 Internet 公開的 HTTPS URL 作為 Webhook 端點,以接收來自 LINE 聊天室的訊息、使用者回應及檔案。在開發偵測階段,我們通常是用 http://localhost:12345 這樣的本機隨機 Port 執行網站專案,每次都得先上傳雲端或對外開放主機測試太沒效率,更何況程式得在本機執行較易設定中斷點及 Line by Line 偵錯,不浪費 Visual Studio/VSCode 的強大功能。

這類問題的常見解法是使用 ngrok,透過一支 ngrok.exe 將 http://localhost:12345 導向 ngrok 公司的對外網站,對映成 https://1234abcd.ngrok.io 的隨機配發 URL 網址(而且有 HTTPS,當今跑網站的必要條件),外界送到該網址的 HTTP 請求將轉到你的本機 12345 Port,如此既可在本機修改偵錯,同時又能接受來自 Internet 的請求,兩全其美。(若是要用 ngrok 在 Visual Studio 偵錯 Webhook 程式,可參考 David 老師的教學影片)

如果你跟我一樣,嫌用 ngrok 技術含量過低,想多學些突破網路限制的野外求生技巧,還剛好在雲端有台 Linux VM 跑 Docker Nginx ,這篇用 SSH Tunneling 實現 Webhook 本機偵錯的做法可以參考一下。

首先,我們要在雲端建一台小 VM 跑 Linux 並支援 HTTPS,如果有 Azure 學生帳戶、Visual Studio 訂閱的免費額度,在 Azure 開台 B1s 小機器跑 Ubuntu 或 Debian應該綽綽有餘,不測試時關掉,幾乎用不到什麼額度。要在 Linux 安裝 HTTPS 網站基本環境可以參考這兩篇 - HTTPS Nginx Docker 之懶人安裝法一行指令建好 Azure VM 跑 HTTPS 網站,大約五到十分鐘搞定。(另外建議限定 SSH 存取來源 IP以策安全)

依上述懶人包安裝,Linux 上會有 Nginx + Certbot 負責自動申請及更新 TLS 憑證,用 https://your-vm-name.region.cloudapp.azure.com 將連到 ASP.NET Core 範例網站。為了要跑 SSH Tunneling,我們要先 ssh 登入 Linux 主機用 sudo docker-compose down 停用 ASP.NET Core 範例網站,把 localhost:5000 Port 讓出來。

隨便在本機建個 ASP.NET Core 專案跑起來,確認網站的 HTTP Port 為 5130,順便在 MapGet() 加上自訂程式及中斷點:

下一步,用以下 ssh 指令將本機 5130 Port 導向到 Linux VM 的 localhost 5000 Port:

ssh -R 5000:localhost:5130 my-ngrok.eastasia.cloudapp.azure.com

上述 SSH 指令如一般登入進入 Shell 環境,但此時本機端的 5130 Port 已對映到 Linux 端的 5000 Port:

換言之,當外界呼叫 https://my-ngrok.eastasia.cloudapp.azure.com/,Linux 主機上的 Nginx Docker 容器會將 80 Port 對映到 localhost 5000 Port,SSH Tunneling 再將其轉送到我們本機的 5130 Port,觸發 VSCode 設定的中斷點:

就醬,一個類似 ngrok 的私人服務就完成囉。

SSH Tunneling 功能十分強大,除了將本機 Port 透過 SSH 伺服器提供外部存取(Remote Port Forwarding),也能將 SSH 伺服器當跳板去存取伺服器本身特定 Port 或再連到遠端主機特定 Port (Local Port Forwarding),甚至當成 Socket Proxy 轉接任意主機 (Dynamic Port Forwarding),相關介紹推薦這篇:SSH Tunneling (Port Forwarding) 詳解 by John Engineer Stuff

[2023-08-21 補充]

補上許多讀者大力推薦的 Cloudflare Tunnel,可免費使用,且可自訂 DNS 網域名稱,就近分配節點並有一些安全防護,功能比 ngrok 強大,跟 ngrok 一樣可做為本機開發測試階段轉接對外連線,甚至用於正式營運。

延伸閱讀:

Tutorial of using SSH tunneling to simulate ngrok function to enable ASP.NET Core debugging for webhook.


Comments

# by Anonymous

只要入坑 SSH 就回不去了~

Post a comment