用 raspi-config 做完 Raspberry Pi OS Trixie Lite 的基本設定連上網路後, 接下來最重要的便是遠端連線了, 由於 Lite 版的樹莓派 OS 沒有桌面環境, 所以無法使用 VNC Cloud/Server, 加上我這台 Pi 3A+ 放在高雄家的社區網路內, 也無法使用 Port forwarding 穿牆, 想用 ssh 遠端連線最簡單方便的做法便是透過 ngrok 提供的 TCP 連線.
1. 註冊 ngrok 取得 authtoken :
首先到 Ngrok 網站註冊帳號 :
註冊完進入 ngrok 官網的 setup&instalation 頁面 :
將其中第二項的的授權碼複製下來, 記在文字檔中備用 :
注意, 如果有啟用 MFA 驗證機制, 登入時會要求輸入驗證碼, Android 用戶可以用 Google Authenticator App 取得驗證碼 :
參考 :
2. 下載 GPG 公鑰存入信任金鑰資料夾 :
首先用 curl 指令從 ngrok 官方網站下載 GPG 公鑰用來驗證套件來源的合法性, 然後用 tee 指令將下載的公鑰寫入系統的 APT 信任金鑰資料夾, 這兩個指令的目的是要讓 APT 安裝 ngrok 時能驗證來源安全, 避免下載到偽造之套件 :
pi@pi3aplus:~ $ curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
/7JXRqfXsWxyTbOUVnmRWIXPXHU=
=ghCR
-----END PGP PUBLIC KEY BLOCK-----
3. 將套件來源寫入新的列表檔 :
用 echo 指令生成一行 APT 軟體源列表, 用來指定 ngrok 官方套件的來源; 再用 tee 指令將這個套件源寫入新的列表檔, 這樣 APT 就知道從這個來源抓 ngrok 套件 :
pi@pi3aplus:~ $ echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
deb https://ngrok-agent.s3.amazonaws.com buster main
pi@pi3aplus:~ $ sudo apt update
已有:1 http://deb.debian.org/debian trixie InRelease
已有:2 http://deb.debian.org/debian trixie-updates InRelease
已有:3 http://deb.debian.org/debian-security trixie-security InRelease
下載:4 https://ngrok-agent.s3.amazonaws.com buster InRelease [20.3 kB]
下載:5 http://archive.raspberrypi.com/debian trixie InRelease [54.9 kB]
下載:6 https://ngrok-agent.s3.amazonaws.com buster/main armhf Packages [9,550 B]
下載:7 https://ngrok-agent.s3.amazonaws.com buster/main arm64 Packages [9,531 B]
下載:8 http://archive.raspberrypi.com/debian trixie/main arm64 Packages [363 kB]
取得 457 kB 用了 3s (150 kB/s)
All packages are up to date.
4. 安裝 ngrok 套件 :
經過上面準備後, 即可用 apt 下載安裝 ngrok 了 :
pi@pi3aplus:~ $ sudo apt install ngrok
Installing:
ngrok
Summary:
Upgrading: 0, Installing: 1, Removing: 0, Not Upgrading: 0
Download size: 5,835 kB
Space needed: 0 B / 26.9 GB available
下載:1 https://ngrok-agent.s3.amazonaws.com buster/main arm64 ngrok arm64 3.33.0 [5,835 kB]
取得 5,835 kB 用了 27s (215 kB/s)
選取了原先未選的套件 ngrok。
(讀取資料庫 ... 目前共安裝了 70933 個檔案和目錄。)
正在準備解包 .../ngrok_3.33.0_arm64.deb……
Unpacking ngrok (3.33.0) ...
設定 ngrok (3.33.0) ...
5. 將 ngrok 帳號授權與主機綁定 :
用 ngrok config add-authtoken <YOUR_TOKEN> 指令將 ngrok 授權寫到機器裡, 這會建立一個 ngrok 設定檔 ~/.config/ngrok/ngrok.yml, 以後啟動 TCP, HTTPS, SSH 等隧道時就不需要再用 email , 密碼, 或 MFA 登入 ngrok, 直接用這個 token 代表我們的 ngrok 帳號, 這樣啟動隧道時不會跳出登入畫面, 就算是未來重開機, 或重跑 ngrok 都不用登入或被要求 MFA 驗證 :
pi@pi3aplus:~ $ ngrok config add-authtoken 1n4EbyjkVWZ1RXPyZVSQ1ToNY1966_3kbM2zgjAt62W7RGhsx1L (此為範例 token)
Authtoken saved to configuration file: /home/pi/.config/ngrok/ngrok.yml
6. 建立 ngrok TCP 隧道並取得埠號 :
所謂的隧道 (tunnel) 是從外網透過 ngrok 走到樹莓派主機的路徑, 因為 Pi 3 A+ 主機是在社區網路內網, 其私有 IP (192.168.x.x) 從外網無法連線, 建立一個 ngrok 的 TCP 隧道就是幫我們的主機在 ngrok 的伺服器上開一個公開的 TCP 埠號, 這樣送到 ngrok 此埠號的資料就會送到我們的主機的某個埠號了, 換句話說, 就是讓 ngrok 幫我們開一個在 Internet 上能連到我們主機的入口, 毋須使用公網 IP.
以下為透過 ngrok 建立 TCP 隧道的 Python 程式 :
pi@pi3aplus:~ $ nano ngrok_tcp.py
# ngrok_tcp.py
import subprocess
import time
import requests
# 1. 啟動 ngrok TCP 隧道(背景執行)
subprocess.Popen(["ngrok", "tcp", "22", "--log", "stdout"])
time.sleep(5) # 等 ngrok 啟動
# 2. 取得隧道資訊
try:
r = requests.get("http://127.0.0.1:4040/api/tunnels")
data = r.json()
for t in data['tunnels']:
if t['proto'] == 'tcp':
public_url = t['public_url']
print("Public TCP URL:", public_url)
except Exception as e:
print("Error:", e)
執行 ngrok_tcp.py :
pi@pi3aplus:~ $ python ngrok_tcp.py
INFO[11-18|00:55:27] no configuration paths supplied
INFO[11-18|00:55:27] using configuration at default config path path=/home/pi/.config/ngrok/ngrok.yml
INFO[11-18|00:55:27] open config file path=/home/pi/.config/ngrok/ngrok.yml err=nil
t=2025-11-18T00:55:28+0800 lvl=info msg="FIPS 140 mode" enabled=false
t=2025-11-18T00:55:28+0800 lvl=info msg="starting web service" obj=web addr=127.0.0.1:4040 allow_hosts=[]
t=2025-11-18T00:55:29+0800 lvl=info msg="client session established" obj=tunnels.session
t=2025-11-18T00:55:29+0800 lvl=info msg="tunnel session started" obj=tunnels.session
t=2025-11-18T00:55:29+0800 lvl=info msg="started tunnel" obj=tunnels name=command_line addr=//localhost:22 url=tcp://0.tcp.ap.ngrok.io:19669
t=2025-11-18T00:55:32+0800 lvl=info msg=start pg=/api/tunnels id=2f56e23924a75aa0
t=2025-11-18T00:55:32+0800 lvl=info msg=end pg=/api/tunnels id=2f56e23924a75aa0 status=200 dur=2.126497ms
Public TCP URL: tcp://0.tcp.ap.ngrok.io:19669
可見 ngrok 已建立埠號為 19669 的 TCP 隧道, 網址為 :
tcp://0.tcp.ap.ngrok.io:19669 (此為範例埠號)
7. 用 ssh 遠端連線 :
從遠端 (我的 LG Gram) 用 ssh 連線位於社區網路防火牆後面的 Pi 3A+ 主機 :
C:\Users\tony1>ssh pi@0.tcp.ap.ngrok.io -p 19669
The authenticity of host '[0.tcp.ap.ngrok.io]:19669 ([18.141.106.224]:19669)' can't be established.
ED25519 key fingerprint is SHA256:4BubX0iFouGpd/DtCG1966... (略) .....
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[0.tcp.ap.ngrok.io]:19669' (ED25519) to the list of known hosts.
pi@0.tcp.ap.ngrok.io's password:
Linux pi3aplus 6.12.47+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.47-1+rpt1 (2025-09-16) aarch64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Nov 18 00:18:43 2025 from 192.168.50.76
連線成功! 出現樹莓派終端機提示號 :
pi@pi3aplus:~ $ ls -ls
總用量 4
4 -rw-rw-r-- 1 pi pi 518 11月 18 00:54 ngrok_tcp.py
pi@pi3aplus:~ $
Lite 版的 Raspberry Pi OS 使用者根目錄果然很乾淨, 目前只有上面的建立 TCP 隧道的程式 ngrok_tcp.py 而已, 沒有桌面環境效能更好.
2025-12-04 補充 :
由於社區網路只剩五戶參加, 主辦的九樓張先生會賠本決定結束營業, 我 12/1 去中華電信申辦光世代 300M, 昨天工程師來拉光纖裝機, 我也同步把 Pi 3A+ 的連線 SSID 更換, 重新執行上面的 ngrok_tcp.py 程式卻出現如下錯誤 :
d:\python\test>ssh pi@0.tcp.jp.ngrok.io -p 18959
The authenticity of host '[0.tcp.jp.ngrok.io]:18959 ([3.114.158.133]:18059)' can't be established.
ED25519 key fingerprint is SHA256:4BubX0iFouGpd/DtC... (略) ....
This host key is known by the following other names/addresses:
C:\Users\tony1/.ssh/known_hosts:1: [0.tcp.ap.ngrok.io]:19669
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Host key verification failed.
詢問 AI 得知原來我的筆電 C:\Users\tony1\.ssh\known_hosts 裡已經記錄過之前那個 ngrok 伺服器的 SSH 金鑰 :
[0.tcp.ap.ngrok.io]:19669
由於 ngrok 每次重新連線都會分配不同伺服器, 也會有不同的 Host Key, SSH 發現同一個主機名稱但金鑰不一樣而覺得可疑便拒絕連線, 這是 SSH 的安全機制.
用 type 指令列印使用者目錄底下的 .ssh\known_hosts 檔就能看到之前的連線資訊 :
d:\python\test>type C:\Users\tony1\.ssh\known_hosts
[0.tcp.ap.ngrok.io]:19669 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAA ... (略) ...
[0.tcp.ap.ngrok.io]:19669 ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB ... (略) ...
[0.tcp.ap.ngrok.io]:19669 ecdsa-sha2-nistp256 AAAAE2VjZHNhL ... (略) ...
最簡單的解決方法式用下列指令刪除 known_hosts 裡與 ngrok 相關的舊紀錄 :
d:\python\test>ssh-keygen -R "[0.tcp.ap.ngrok.io]:19669"
# Host [0.tcp.ap.ngrok.io]:19669 found: line 1
# Host [0.tcp.ap.ngrok.io]:19669 found: line 2
# Host [0.tcp.ap.ngrok.io]:19669 found: line 3
C:\Users\tony1/.ssh/known_hosts updated.
Original contents retained as C:\Users\tony1/.ssh/known_hosts.old
然後連線新的伺服器就不會出現 Host key verification 失敗訊息了 :
d:\python\test>ssh pi@0.tcp.jp.ngrok.io -p 18959
pi@0.tcp.jp.ngrok.io's password: (輸入密碼)
Linux pi3aplus 6.12.47+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.47-1+rpt1 (2025-09-16) aarch64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Dec 3 21:49:43 2025 from ::1
pi@pi3aplus:~ $
2025-12-08 補充 :
如果忘記或未記下 ngrok 產生的網址, 可以到原主機上用 curl 查詢 tunnels :
pi@pi3aplus:~ $ curl http://localhost:4040/api/tunnels
{"tunnels":[{"name":"command_line","ID":"acc9f9c13483e07a123456735c8ce82f","uri":"/api/tunnels/command_line","public_url":"tcp://0.tcp.jp.ngrok.io:18959","proto":"tcp","config":{"addr":"localhost:22","inspect":false},"metrics":{"conns":{"count":17,"gauge":1,"rate1":2.964393875e-314,"rate5":7.937875243996238e-142,"rate15":6.890263591892029e-50,"p50":308761884155,"p90":1365783669392.4001,"p95":1756118554850,"p99":1756118554850},"http":{"count":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0}}}],"uri":"/api/tunnels"}
其中 public_url 屬性即為公開網址.
2025-12-11 補充 :
我之前測試 WordPress 網站時用過 ngrok, 那時用 wget 下載 zip 檔解壓後使用, 參考 :
用 sudo apt install ngrok 安裝的 ngrok 通常是舊版 (V1 版本), 軟體倉庫中的版本更新較慢, 現在官方主推 V3 版, 用 wget 下載的則最新版本 (目前為 V3), 支援所有最新的 ngrok 功能, 指令和連線協定. 可從 ngrok 儀表板取得最新連結 :
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm64.tgz (64 位元)
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm.tgz (32 位元)






沒有留言 :
張貼留言