2021年1月15日 星期五

使用 ngrok 代理伺服器穿透社區網路存取內網的樹莓派本機網站

今天在趙英傑寫的 "超圖解 Python 程式設計入門" 這本書的第十章讀到透過 ngrok 代裡伺服器存取位於內網的本機網站的方法, 我覺得很有意思, 因為家裡使用社區網路, 沒辦法像鄉下家的 ADSL 那樣在路由器上打洞從遠端存取 22 與 80 埠, 所以架設在樹莓派上的網站沒辦法從外網瀏覽, 用這方法應該可行, 今天測試確認 OK, 紀錄如下 :


Source : 博客來


Ngrok 是一個提供 Web 轉發服務的代理伺服器, 使用者須下載 ngrok 程式, 經過驗證後可為內網的網站提供一個外網 URL, 讓外網可以存取內網的 localhost 網站, 但每次啟動 ngrok 程式時轉發的外網 URL 網址會變 . Ngrok 有提供免費方案, 但限制最多同時 40 個連線請求. 

我的樹莓派 Pi 3B 的 80 埠已經被運行中的 Nginx 網頁伺服器占用, 所以開啟樹莓派的 Chromium 瀏覽器連線 localhost (或 127.0.0.1) 會顯示 Nginx 伺服器的歡迎頁面 :




但這只能在內網 (區域網路) 看到, 以下的測試就是希望能在外網也能看到此網頁. 

首先到 Ngrok 網站下載 ngrok 程式 : 


Ngrok 網站會自動偵測作業系統, 它偵測到這是樹莓派, 所以下載頁顯示的是 Linux 版的 ngrok 下載頁面 :




樹莓派網頁下載的檔案預設放在使用者目錄的 Downloads 子目錄下 :

pi@raspberrypi:~ $ cd Downloads   
pi@raspberrypi:~/Downloads $ ls -ls ngrok   
23296 -rwxr-xr-x 1 pi pi 23855086 10月  9  2019 ngrok   

在 Windows 的命令列只要執行 ngrok http 80 即可啟動 80 埠的網站轉發服務, 但在 Linux 必須用 ./ngrok 才行, 否則會找不到 ngrok :

pi@raspberrypi:~/Downloads $ ngrok http 80   
bash: ngrok:命令找不到
pi@raspberrypi:~/Downloads $ ./ngrok http 80

參考 :


這時終端機進入 ngrok 的畫面 : 




可見 ngrok 已產生轉發網址 4c0d8b727244.ngrok.io (預設伺服器在美國), 任何以 HTTP/HTTP 向此 URL 發出的要求都會被轉發到本機的網址 http://localhost:80 (注意 Session Expire 欄位顯示 1 小時 58 分, 表示對於未註冊用戶啟動 ngrok 後只能使用 2 小時而已) : 

ngrok by @inconshreveable                                              (Ctrl+C to quit)
                                                                                       
Session Status                online          
Session Expires           1 hours, 58 minutes                                   
Version                       2.3.35                                                   
Region                        United States (us)                                       
Web Interface                 http://127.0.0.1:4040                                    
Forwarding                    http://4c0d8b727244.ngrok.io -> http://localhost:80      
Forwarding                    https://4c0d8b727244.ngrok.io -> http://localhost:80     
                                                                                       
Connections                   ttl     opn     rt1     rt5     p50     p90              
                              2       0       0.00    0.00    65.52   65.97            
                                                                              

這時在外網用瀏覽器連線此轉發網址 4c0d8b727244.ngrok.io 即可看到內網的網站內容 :




而樹莓派終端機的 ngrok 執行畫面下方也會顯示 HTTP/HTTPS 連線訊息 :




解決 Session Expires 兩小時斷線限制問題的方法是去 ngrok 官網註冊一個免費帳號 : 




按 Get started for free 鈕填寫 email 與密碼 (需 10 碼以上) 按 Sign up 即可 : 




註冊完進入 ngrok 官網的 setup&instalation 頁面, 其中第二項的指令中含有個人的授權碼, 將整個指令複製起來 : 




然後在樹莓派終端機介面先按 CTRL+C 終止目前的轉發服務, 然後把上面所複製的指令貼到終端機即完成授權, 這會產生一個授權檔案 ngrok.yaml  : 

pi@raspberrypi:~/Downloads $ ./ngrok authtoken 1n4EbyjkVWZ1RXPyZVSQ1nKz9Mn_7kbM7zgjAt45W7RGhsx1L
Authtoken saved to configuration file: /home/pi/.ngrok2/ngrok.yml

這時再次輸入 ./ngrok http 80 重新啟動轉發服務 : 

pi@raspberrypi:~/Downloads $ ./ngrok http -region ap 80

此處我們在 http 後用 -region ap 參數指定使用 rgrok 亞太區伺服器 (位於新加坡), 這樣會比上面預設的美國快一些 :




可見已經沒有 Session Expires 這個欄位, 而且伺服器地點也改在亞太區了. 由於重新啟動 ngrok, 所以轉發的網址也改變了, 現在外網必須改用此網址才能存取本機網站 :




Bingo! 但此方法址只是解決了穿透防火牆存取 HTTP/HTTP 埠口問題而已, 如果要完全掌控社區網路內的樹莓派 (即存取桌面), 必須使用樹莓派 Rasbian 作業系統內建的 VNC 才行 (外網使用 VNC Connect), 參考 :


Ngrok 官網提供了許多應用教學, 參考 :



2020-01-16 補充 : 

由於每次執行 ngrok 後產生的外網轉發網址都不同, 這就有一個大問題了, 如果樹莓派不明原因當機重啟, 雖然可以設定樹莓派在系統啟動時自動執行 ngrok, 但是在遠端要怎麼得知轉發網址呢? 我找到下面這篇文章 :


只要開機啟動 ngrok 後執行下列指令 :

curl http://localhost:4040/api/tunnels

此指令會傳回一個 json 格式的回應 :

i@raspberrypi:~ $ curl http://localhost:4040/api/tunnels
{"tunnels":[{"name":"command_line","uri":"/api/tunnels/command_line","public_url":"https://4c0d8b727244.ngrok.io","proto":"https","config":{"addr":"http://localhost:80","inspect":true},"metrics":{"conns": ......}

其中的 public_url 鍵之值即為外網之轉發網址, 只要用 email 傳出去就可以得知最新網址了. 

2 則留言 :

學習筆記 提到...

Good job. This helps me a lot.

小狐狸事務所 提到...

Thanks for your reply.