天天看點

如何通過反向 SSH 隧道通路 NAT 後面的 Linux 伺服器

你在家裡運作着一台 linux 伺服器,它放在一個 nat 路由器或者限制性防火牆後面。現在你想在外出時用 ssh 登入到這台伺服器。你如何才能做到呢?ssh 端口轉發當然是一種選擇。但是,如果你需要處理多級嵌套的 nat 環境,端口轉發可能會變得非常棘手。另外,在多種 isp 特定條件下可能會受到幹擾,例如阻塞轉發端口的限制性 isp 防火牆、或者在使用者間共享 ipv4 位址的營運商級 nat。

<a target="_blank"></a>

如何通過反向 SSH 隧道通路 NAT 後面的 Linux 伺服器

讓我們來看看怎樣建立和使用反向 ssh 隧道。我們做如下假設:我們會設定一個從家庭伺服器(homeserver)到中繼伺服器(relayserver)的反向 ssh 隧道,然後我們可以通過中繼伺服器從用戶端計算機(clientcomputer) ssh 登入到家庭伺服器。本例中的中繼伺服器 的公網 ip 位址是 1.1.1.1。

在家庭伺服器上,按照以下方式打開一個到中繼伺服器的 ssh 連接配接。

<code>homeserver~$ ssh -fn -r 10022:localhost:22 [email protected]</code>

這裡端口 10022 是任何你可以使用的端口數字。隻需要確定中繼伺服器上不會有其它程式使用這個端口。

“-r 10022:localhost:22” 選項定義了一個反向隧道。它轉發中繼伺服器 10022 端口的流量到家庭伺服器的 22 号端口。

用 “-fn” 選項,當你成功通過 ssh 伺服器驗證時 ssh 會進入背景運作。當你不想在遠端 ssh 伺服器執行任何指令,就像我們的例子中隻想轉發端口的時候非常有用。

運作上面的指令之後,你就會回到家庭主機的指令行提示框中。

登入到中繼伺服器,确認其 127.0.0.1:10022 綁定到了 sshd。如果是的話就表示已經正确設定了反向隧道。

<code>relayserver~$ sudo netstat -nap | grep 10022</code>

<code>tcp 0 0 127.0.0.1:10022 0.0.0.0:* listen 8493/sshd</code>

現在就可以從任何其它計算機(用戶端計算機)登入到中繼伺服器,然後按照下面的方法通路家庭伺服器。

<code>relayserver~$ ssh -p 10022 homeserver_user@localhost</code>

需要注意的一點是你在上面為localhost輸入的 ssh 登入/密碼應該是家庭伺服器的,而不是中繼伺服器的,因為你是通過隧道的本地端點登入到家庭伺服器,是以不要錯誤輸入中繼伺服器的登入/密碼。成功登入後,你就在家庭伺服器上了。

上面的方法允許你通路 nat 後面的 家庭伺服器,但你需要登入兩次:首先登入到 中繼伺服器,然後再登入到家庭伺服器。這是因為中繼伺服器上 ssh 隧道的端點綁定到了回環位址(127.0.0.1)。

事實上,有一種方法可以隻需要登入到中繼伺服器就能直接通路nat之後的家庭伺服器。要做到這點,你需要讓中繼伺服器上的 sshd 不僅轉發回環位址上的端口,還要轉發外部主機的端口。這通過指定中繼伺服器上運作的 sshd 的 gatewayports 實作。

打開中繼伺服器的 /etc/ssh/sshd_config 并添加下面的行。

<code>relayserver~$ vi /etc/ssh/sshd_config</code>

<code>gatewayports clientspecified</code>

重新開機 sshd。

基于 debian 的系統:

<code>relayserver~$ sudo /etc/init.d/ssh restart</code>

基于紅帽的系統:

<code>relayserver~$ sudo systemctl restart sshd</code>

現在在家庭伺服器中按照下面方式初始化一個反向 ssh 隧道。

<code>homeserver~$ ssh -fn -r 1.1.1.1:10022:localhost:22 [email protected]</code>

登入到中繼伺服器然後用 netstat 指令确認成功建立的一個反向 ssh 隧道。

<code>tcp 0 0 1.1.1.1:10022 0.0.0.0:* listen 1538/sshd: dev</code>

不像之前的情況,現在隧道的端點是 1.1.1.1:10022(中繼伺服器的公網 ip 位址),而不是 127.0.0.1:10022。這就意味着從外部主機可以通路隧道的另一端。

現在在任何其它計算機(用戶端計算機),輸入以下指令通路網絡位址變換之後的家庭伺服器。

<code>clientcomputer~$ ssh -p 10022 [email protected]</code>

在上面的指令中,1.1.1.1 是中繼伺服器的公共 ip 位址,homeserver_user必須是家庭伺服器上的使用者賬戶。這是因為你真正登入到的主機是家庭伺服器,而不是中繼伺服器。後者隻是中繼你的 ssh 流量到家庭伺服器。

現在你已經明白了怎樣建立一個反向 ssh 隧道,然後把隧道設定為 “永久”,這樣隧道啟動後就會一直運作(不管臨時的網絡擁塞、ssh 逾時、中繼主機重新開機,等等)。畢竟,如果隧道不是一直有效,你就不能可靠的登入到你的家庭伺服器。

對于永久隧道,我打算使用一個叫 autossh 的工具。正如名字暗示的,這個程式可以讓你的 ssh 會話無論因為什麼原因中斷都會自動重連。是以對于保持一個反向 ssh 隧道非常有用。

在家庭伺服器上,用下面的參數運作 autossh 來建立一個連接配接到中繼伺服器的永久 ssh 隧道。

<code>homeserver~$ autossh -m 10900 -fn -o "pubkeyauthentication=yes" -o "stricthostkeychecking=false" -o "passwordauthentication=no" -o "serveraliveinterval 60" -o "serveralivecountmax 3" -r 1.1.1.1:10022:localhost:22 [email protected]</code>

“-m 10900” 選項指定中繼伺服器上的監視端口,用于交換監視 ssh 會話的測試資料。中繼伺服器上的其它程式不能使用這個端口。

“-fn” 選項傳遞給 ssh 指令,讓 ssh 隧道在背景運作。

“-o xxxx” 選項讓 ssh:

使用密鑰驗證,而不是密碼驗證。

自動接受(未知)ssh 主機密鑰。

每 60 秒交換 keep-alive 消息。

沒有收到任何響應時最多發送 3 條 keep-alive 消息。

其餘 ssh 隧道相關的選項和之前介紹的一樣。

如果你想系統啟動時自動運作 ssh 隧道,你可以将上面的 autossh 指令添加到 /etc/rc.local。

在這篇博文中,我介紹了你如何能從外部通過反向 ssh 隧道通路限制性防火牆或 nat 網關之後的 linux 伺服器。這裡我介紹了家庭網絡中的一個使用事例,但在企業網絡中使用時你尤其要小心。這樣的一個隧道可能被視為違反公司政策,因為它繞過了企業的防火牆并把企業網絡暴露給外部攻擊。這很可能被誤用或者濫用。是以在使用之前一定要記住它的作用。

<b>原文釋出時間為:2015-08-08</b>

<b></b>

<b>本文來自雲栖社群合作夥伴“linux中國</b>

繼續閱讀