1. 程式人生 > >調試利器:SSH隧道

調試利器:SSH隧道

dns 數據傳輸 調試 步驟 unity 監控 工具 而不是 健康

歡迎大家前往騰訊雲社區,獲取更多騰訊海量技術實踐幹貨哦~

本文作者:ivweb 吳浩麟 原文出處:IVWEB社區 未經同意,禁止轉載

在開發微信公眾號或小程序的時候,由於微信平臺規則的限制,部分接口需要通過線上域名才能正常訪問。但我們一般都會在本地開發,因為這能快速的看到源碼修改後的運行結果。但當涉及到需要調用微信接口時,由於不和你在同一個局域網中的用戶是無法訪問你的本地開發機的,就必須把修改後的代碼重新發布到線上域名所在的服務器才能去驗證結果。每次修改都重新發布很繁瑣也很浪費時間。

本文將教你如何通過 SSH 隧道把本地服務映射到外網,以方便調試,通常把這種方法叫內網穿透。

閱讀完本文後,你能解決以下常見問題:
開發微信公眾號等應用時把本地服務映射到外網,加速調試流程;
把你正在開發的本地服務分享給互聯網上其它人訪問體驗;
在任何地方通過互聯網控制你家中在局域網裏的電腦;

技術分享圖片

最終目的

把運行在本地開發機上的 HTTP 服務映射到外網,讓全世界都能通過外網 IP 服務到你本地開發機上的 HTTP 服務。例如你本地的 HTTP 服務監聽在 127.0.0.1:8080,你有一臺公網 IP 為 12.34.56.78 的服務器,通過本文介紹的方法,可以讓全世界的用戶通過 http://12.34.56.78:8080 訪問到你本地開發機上的 HTTP 服務。

總結成一句話就是:把內網端口映射到外網。

前提條件

為了把內網服務映射到外網,以下資源為必須的:

  • 一臺有外網 IP 的服務器;
  • 能在本地開發機上通過 ssh 登入到外網服務器。

要滿足以上條件很簡單:

  • 對於條件1:購買一臺低配 Linux 服務器,推薦國外的 DigitalOcean;
  • 對於條件2:對於 Mac、Linux 開發機是內置了 ssh 客戶端的,對於 Windows 可以安裝 Cygwin。

實現原理

要實現把內網端口映射到外網,最簡單的方式就是通過 SSH 隧道。

SSH 隧道就像一根管道,能把任何2臺機器連接在一起,把發送到其中一臺機器的數據通過管道傳輸到另一臺機器。假如已經通過 SSH 隧道把本地開發機和外網服務器連接在了一起,外網服務器端監聽在 12.34.56.78:8080,那麽所有發給 12.34.56.78:8080 的數據都會通過 SSH 隧道原封不動地傳輸給本地開發機的 127.0.0.1:8080,如圖所示:

技術分享圖片

也就是說,去訪問 12.34.56.78:8080 就像是訪問本地開發機的 127.0.0.1:8080,本地開發機上的 8080 端口被映射到了外網服務器上的 8080 端口。

如果你的外網服務器 IP 配置了域名解析,例如 yourdomin.com 會通過 DNS 解析為 12.34.56.78,那麽也可以通過 yourdomin.com:8080 去訪問本地開發機上的服務。 這樣就做到了訪問外網地址時其實是本地服務返回的結果。

通過 SSH 隧道傳輸數據時,數據會被加密,就算中間被劫持,黑客也無法得到數據的原內容。 所以 SSH 隧道還有一個功能就是保證數據傳輸的安全性。

實現步驟

把本地開機和外網服務器通過 SSH 隧道連接起來就和在本地開發機 SSH 登入遠程登入到外網服務器一樣簡單。

先來回顧以下 SSH 遠程登入命令,假如想在本地遠程登入到 12.34.56.78,可以在本地開發機上執行以下命令:

ssh username@12.34.56.78

而實現 SSH 隧道只需在本地開發機上執行:

ssh -R 8080:127.0.0.1:8080 username@12.34.56.78

可以看出實現 SSH 隧道的命令相對於 SSH 登入多出來 -R 8080:127.0.0.1:8080,多出的這部分的含義是: 在遠程機器(12.34.56.78)上啟動 TCP 8080端口監聽著,再把遠程機器(12.34.56.78)上8080端口映射到本地的127.0.0.1:8080。 執行完以上命令後,就可以通過 12.34.56.78:8080 去訪問本地的 127.0.0.1:8080 了。

通常把這種技術叫做 SSH 遠程端口轉發(remote forwarding)。
其實不限於只能把本地開發機上運行的服務映射到外網服務器上去,還可以把任何本地開發機可以訪問的服務映射到外網服務器上去。例如在本地開發機上能訪問 github.com:80,在本地開發機上執行:

ssh -R 8080:github.com:80 username@12.34.56.78

就能通過 12.34.56.78:8080 去訪問 github.com:80 了。

保持運行

在執行完上面介紹的 SSH 隧道命令後,你會發現登入到了外網服務器上去了,如果你登出外網服務器,就會發現 12.34.56.78:8080 無法訪問了。導致這個問題的原因是你登出外網服務器時,在外網服務器上本次操作對應的 SSH 進程也跟著退出了,而這個退出的進程曾負責監聽在 8080 端口進行轉發操作。

為了讓 SSH 隧道一直保持在後臺執行,有以下方法。

通過 SSH 自帶的參數
SSH 還支持這些參數:

  • N參數:表示只連接遠程主機,不打開遠程shell;
  • T參數:表示不為這個連接分配TTY;
  • f參數:表示連接成功後,轉入後臺運行;

因此要讓 SSH 隧道一直保持在後臺執行,可以通過以下命令:

ssh -NTf -R 8080:127.0.0.1:8080 username@12.34.56.78

通過 AutoSSH
SSH 隧道是不穩定的,在網絡惡劣的情況下可能隨時斷開。如果斷開就需要手動去本地開發機再次向外網服務器發起連接。 AutoSSH 能讓 SSH 隧道一直保持執行,他會啟動一個 SSH 進程,並監控該進程的健康狀況;當 SSH 進程崩潰或停止通信時,AutoSSH 將重啟動 SSH 進程。
使用AutoSSH 只需在本地開發機上安裝 AutoSSH ,方法如下:

  • Mac 系統:brew install autossh;
  • Linux 系統:apt-get install autossh;
    安裝成功後,在本地開發機上執行:
    autossh -N -R 8080:127.0.0.1:8080 username@12.34.56.78

就能完成和上面一樣的效果,但本方法能保持 SSH 隧道一直運行。 可以看出這行命令和上面的區別在於把 ssh 換成了 autossh,並且少了 -f 參數,原因是 autossh 默認會轉入後臺運行。

常見問題

如果你遇到通過以上方法成功啟動 SSH 隧道後,還是無法訪問 12.34.56.78:8080,那麽很有可能是外網服務器上的 SSH 沒有配置對。為此你需要去外網服務器上修改 /etc/ssh/sshd_config 文件如下:

GatewayPorts yes

這個選項的意思是,SSH 隧道監聽的服務的 IP 是對外開放的 0.0.0.0,而不是只對本機的 127.0.0.1。不開 GatewayPorts 的後果是不能通過 12.34.56.78:8080 訪問,只能在外網服務器上通過 127.0.0.1:8080 服務到本地開發機的服務。

修改好配置文件後,你還需要重啟 sshd 服務來加載新的配置,命令如下:

service sshd restart

如果使用以上方法還是無法訪問 12.34.56.78:8080,請檢查你外網服務器的防火墻配置,確保 8080 端口是對外開放的。

其它代替方案

除了 SSH 隧道能實現內網穿透外,還有以下常用方法。

frp
frp 是一個可用於內網穿透的高性能的反向代理應用,支持 tcp, udp, http, https 協議。 frp 有以下特性:

  • frp 比 SSH 隧道功能更多,配置項更多;
  • frp 也需要一臺外網服務器,並且需要在外網服務器上安裝 frps,在本地開發機上安裝 frpc;

ngrok
ngrok 是一個商用的內網穿透工具,它有以下特點:

  • 不需要有外網服務器,因為 ngrok 會為你提供;
  • 只需要在本地開發機安裝 ngrok 客戶端,和註冊 ngrok 賬戶;
  • 按照服務收費;

這些代替方案的缺點在於都需要再額外安裝其它工具,沒有 SSH 隧道來的直接。 想了解更多可以訪問它們的主頁。

相關閱讀

爸爸去哪兒玩轉黑科技:快來測測自己和老爸有多像?

研究 AI 識別同性戀竟受到死亡威脅!論文作者回應如下

人臉對齊:ASM (主動形狀模型)算法

此文已由作者授權騰訊雲技術社區發布,轉載請註明原文出處

原文鏈接:https://cloud.tencent.com/community/article/789943?fromSource=gwzcw.632114.632114.632114

調試利器:SSH隧道