如何通過SSH反向隧道,訪問NAT后面的Linux服務(wù)器?
譯文假設(shè)你在家里運(yùn)行一臺Linux服務(wù)器,該服務(wù)器位于NAT路由器或限制性防火墻后面。現(xiàn)在,你想在不在家的時候,可以通過SSH連接到家用服務(wù)器。你該如何做到這一點(diǎn)?SSH端口轉(zhuǎn)發(fā)無疑是一個辦法。然而,如果你面對的是多重嵌套NAT環(huán)境,端口轉(zhuǎn)發(fā)會變得很棘手。此外,由于每家ISP的情況不一樣,比如限制性ISP防火墻阻止轉(zhuǎn)發(fā)端口,或者運(yùn)營商級NAT在諸多用戶之間共享IPv4端口,端口轉(zhuǎn)發(fā)也會受到干擾。
何謂SSH反向隧道?
除了SSH端口轉(zhuǎn)發(fā)外,另一個辦法就是SSH反向隧道。SSH反向隧道這個概念其實(shí)很簡單。為此,你需要在限制性家用網(wǎng)絡(luò)外面有另一個主機(jī),即所謂的“中繼主機(jī)”(relay host),你可以從所在地方通過SSH連接到該主機(jī)。你可以使用帶公共IP地址的虛擬專用服務(wù)器(VPS)實(shí)例來建立中繼主機(jī)。然后要做的就是建立一條持久性SSH隧道,從你家用網(wǎng)絡(luò)的服務(wù)器通向公共中繼主機(jī)。有了這條隧道,你就可以從中繼主機(jī)“連回”到家用服務(wù)器(這就是為什么它叫“反向”隧道)。無論你人在什么地方,或者你家用網(wǎng)絡(luò)中的NAT或防火墻限制多嚴(yán)格,只要你可以連接到中繼主機(jī),就可以連接到家用服務(wù)器。
在Linux上建立SSH反向隧道
不妨看看我們?nèi)绾慰梢越⒉⑹褂靡粭lSSH反向隧道。我們假設(shè)下列設(shè)置。我們將建立一條從家用服務(wù)器(homeserver)到中繼服務(wù)器(relayserver)的SSH反向隧道,那樣我們就可以從另一臺名為clientcomputer的計算機(jī),通過中繼服務(wù)器以SSH的方式連接到家用服務(wù)器。中繼服務(wù)器的公共IP地址是1.1.1.1。
在家用服務(wù)器上,打開通向中繼服務(wù)器的SSH連接,如下所示。
homeserver~$ ssh -fN -R 10022:localhost:22 relayserver_user@1.1.1.1
這里的端口10022是你可以選擇的任何隨意的端口號。只要確保該端口沒有被中繼服務(wù)器上的其他程序所使用就行。
“-R 10022:localhost:22”選項(xiàng)定義了反向隧道。它通過中繼服務(wù)器的端口1022,將流量轉(zhuǎn)發(fā)到家用服務(wù)器的端口22。
若使用“-fN”選項(xiàng),一旦你成功驗(yàn)證了身份、登錄到SSH服務(wù)器,SSH就會徑直進(jìn)入后臺。如果你不想在遠(yuǎn)程SSH服務(wù)器上執(zhí)行任何命令,只想轉(zhuǎn)發(fā)端口,就像在本文的示例中,這個選項(xiàng)很有用。
運(yùn)行上述命令后,你將直接回到家用服務(wù)器的命令提示符。
登錄進(jìn)入到中繼服務(wù)器,核實(shí)127.0.0.1:10022綁定到sshd。如果是這樣,那意味著反向隧道已正確建立起來。
relayserver~$ sudo netstat -nap | grep 10022 tcp 0 0 127.0.0.1:10022 0.0.0.0:* LISTEN 8493/sshd
現(xiàn)在可以從其他任何計算機(jī)(比如clientcomputer),登錄進(jìn)入到中繼服務(wù)器。然后訪問家用服務(wù)器,如下所示。
relayserver~$ ssh -p 10022 homeserver_user@localhost
需要注意的一個地方就是,你為localhost輸入的SSH登錄信息/密碼應(yīng)該適用于家用服務(wù)器,而不是適用于中繼服務(wù)器,因?yàn)槟闶峭ㄟ^隧道的本地端點(diǎn)登錄進(jìn)入到家用服務(wù)器。所以別為中繼服務(wù)器輸入登錄信息/密碼。成功登錄后,你就接入到了家用服務(wù)器。
通過SSH反向隧道,直接連接到NAT后面的服務(wù)器
雖然上述方法讓你可以連接到NAT后面的家用服務(wù)器,但是你需要登錄兩次,先登錄到中繼服務(wù)器,然后登錄到家用服務(wù)器。這是由于中繼服務(wù)器上SSH隧道的端點(diǎn)綁定到回送地址(127.0.0.1)。
但實(shí)際上,只要單次登錄到中繼服務(wù)器,就可以直接連接到NAT后面的家用服務(wù)器。為此,你需要讓中繼服務(wù)器上的sshd不僅可以從回送地址轉(zhuǎn)發(fā)端口,還可以從外部主機(jī)轉(zhuǎn)發(fā)端口。這可以通過在中繼服務(wù)器上運(yùn)行的sshd里面指定GatewayPorts選項(xiàng)來實(shí)現(xiàn)。
打開中繼服務(wù)器的/etc/ssh/sshd_conf,添加下面這一行。
relayserver~$ vi /etc/ssh/sshd_conf GatewayPorts clientspecified
重啟sshd。
基于Debian的系統(tǒng):
relayserver~$ sudo /etc/init.d/ssh restart
基于紅帽的系統(tǒng):
relayserver~$ sudo systemctl restart sshd
現(xiàn)在不妨從家用服務(wù)器開始建立SSH反向隧道,如下所示。
homeserver~$ ssh -fN -R 1.1.1.1:10022:localhost:22 relayserver_user@1.1.1.1
登錄進(jìn)入到中繼服務(wù)器,用netstat命令核實(shí)SSH反向隧道已成功建立起來。
relayserver~$ sudo netstat -nap | grep 10022 tcp 0 0 1.1.1.1:10022 0.0.0.0:* LISTEN 1538/sshd: dev
不像之前的情況,隧道的端點(diǎn)現(xiàn)在是1.1.1.1:10022(中繼服務(wù)器的公共IP地址),而不是127.0.0.1:10022。這意味著,可以從外部主機(jī)連接到隧道端點(diǎn)。
現(xiàn)在可以從其他任何計算機(jī)(比如clientcomputer),輸入下列命令,訪問NAT后面的家用服務(wù)器。
clientcomputer~$ ssh -p 10022 homeserver_user@1.1.1.1
在上述命令中,雖然1.1.1.1是中繼服務(wù)器的公共IP地址,但homeserver_user必須是與家用服務(wù)器關(guān)聯(lián)的用戶帳戶。這是由于,你實(shí)際登錄進(jìn)入的主機(jī)是家用服務(wù)器,而不是中繼服務(wù)器。后者只是將你的SSH流量中繼轉(zhuǎn)發(fā)到家用服務(wù)器而已。#p#
在Linux上建立持久性SSH反向隧道
想必你已明白了如何建立一條SSH反向隧道,現(xiàn)在不妨讓隧道具有“持久性”,那樣隧道隨時建立并運(yùn)行起來(無論面對什么樣的情況:暫時網(wǎng)絡(luò)擁塞、SSH超時還是中繼主機(jī)重啟等)。畢竟,要是隧道沒有始終建立起來,你也就無法可靠地連接到家用服務(wù)器。
為了建立持久性隧道,我要使用一款名為autossh的工具。顧名思義,萬一SSH會話由于任何原因而斷開,這個程序讓你可以自動重啟SSH會話。所以,讓SSH反向隧道保持持久連接很有用。
第一步,不妨建立無需密碼的SSH登錄機(jī)制,從家用服務(wù)器登錄到中繼服務(wù)器。那樣一來,autossh就能重啟斷開的SSH反向隧道,不需要用戶干預(yù)。
下一步,將autossh安裝到發(fā)起隧道的家用服務(wù)器上。
從家用服務(wù)器運(yùn)行帶下列變量的autossh,從而建立一條通向中繼服務(wù)器的持久性SSH隧道。
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 relayserver_user@1.1.1.1
“-M 10900”選項(xiàng)指定了中繼服務(wù)器上的一個監(jiān)控端口,將用來交換測試數(shù)據(jù),以監(jiān)控SSH會話。該端口不應(yīng)該被中繼服務(wù)器上的任何程序所使用。
“-fN”選項(xiàng)傳遞給ssh命令,讓SSH隧道可以在后臺運(yùn)行。
“-o XXXX”選項(xiàng)指令ssh執(zhí)行下列操作:
•使用密鑰驗(yàn)證,而不是密碼驗(yàn)證。
•自動接受(未知的)SSH主機(jī)密鑰。
•每60秒就交換持久連接(keep-alive)消息。
•最多發(fā)送3個持久連接消息,而不接受任何響應(yīng)。
與SSH反向隧道有關(guān)的其余選項(xiàng)仍與之前一樣。
如果你希望SSH隧道一啟動就自動建立起來,可以在/etc/rc.local中添加上述的autossh命令。
結(jié)束語
我在本文中介紹了如何可以使用SSH反向隧道,從外面訪問限制性防火墻或NAT網(wǎng)關(guān)后面的Linux服務(wù)器。我演示的使用場合是通過公共VPS訪問家用網(wǎng)絡(luò),可是你在用于企業(yè)網(wǎng)絡(luò)時需要小心。可以認(rèn)為這類隧道違反了企業(yè)政策,因?yàn)樗荛_了企業(yè)防火墻,因而將企業(yè)網(wǎng)絡(luò)暴露在外部攻擊者面前。它被誤用或?yàn)E用的可能性很大。所以,在建立SSH反向隧道之前總是要牢記因此帶來的影響或后果。
英文:How to access a Linux server behind NAT via reverse SSH tunnel