@Author : Roger TX (425144880@qq.com)
@Link : https://github.com/paotong999
什么是SSH隧道
首先看下面的例子,我們所面臨的大部分情況都和它類似。
- 內網的機器A,公網的機器B,某服務器C
- A可以連接B,B可以連接C,但是AC之間不能連接
- 這個時候如果B能運行一個OpenSSH服務器,那么就可以通過B形成隧道連接AC
跳轉機的端口轉發服務
我們建立ssh隧道的時候,往往是想通過一臺公網的主機或者是大家都可以訪問的主機做跳轉機,來訪問內部或者外部不能直接訪問的機器。所以一般像這種情況下,請將跳轉機中的ssh服務器中的GatewayPorts設為yes
ssh是linux遠程登錄的安全協議,是 C/S 模式的架構,配置文件分為服務器端配置文件 [/etc/ssh/sshd_config] 與客戶端配置文件默認配置文件[/etc/ssh/ssh_config] 用戶配置文件[~/.ssh/config]。sshd_config 是服務端主配置文件這個文件的宿主應當是root,權限最大可以是"644"
關于sshd_config配置詳解,這里不會過多涉及,有興趣的同學可以自行查找材料,這里主要說下GatewayPorts
GatewayPorts
1、是否允許遠程主機連接本地的轉發端口。默認值是"no"。
2、sshd(8) 默認將遠程端口轉發綁定到loopback地址。這樣將阻止其它遠程主機連接到轉發端口。
3、GatewayPorts 指令可以讓 sshd 將遠程端口轉發綁定到非loopback地址,這樣就可以允許遠程主機連接了。
4、"no"表示僅允許本地連接,"yes"表示強制將遠程端口轉發綁定到統配地址(wildcard address),
"clientspecified"表示允許客戶端選擇將遠程端口轉發綁定到哪個地址。
修改完成之后,重啟sshd服務
service sshd reload
本地SSH隧道
在建立本地SSH隧道之前要清楚下面幾個參數:
- 公網機器B的IP地址(這里是192.168.199.16)
- 公網機器B的端口號(這里是3333)
- 某服務器C的IP地址(這里是139.199.0.37)
- 某服務器C的端口號(端口:22)
在清楚了上面的參數后,我們使用下面的命令來建立一個遠程SSH隧道,在192.168.199.16的主機上執行下面的命令:
ssh -Nf -L 192.168.199.16:3333:139.199.0.37:22 192.168.199.16
這里我們用到了SSH客戶端的三個參數,下面我們一一做出解釋:
- -N 告訴SSH客戶端,這個連接不需要執行任何命令。僅僅做端口轉發
- -f 告訴SSH客戶端在后臺運行
- -L 做本地映射端口,被冒號分割的三個部分含義分別是最后一個參數是我們用來建立隧道的中間機器的IP地址(IP: 192.168.199.16)
- 需要使用的本地端口號(端口: 3333)
- 需要訪問的目標機器IP地址(IP: 139.199.0.37)
- 需要訪問的目標機器端口(端口: 22)
那么本地局域網的任何機器訪問192.168.199.16:3333都會自動被映射到139.199.0.37:22。
遠程SSH隧道
內網的機器A,公網的機器B,某服務器C
A可以連接B,B可以連接C,但是AC之間不能連接
這個時候如果B能運行一個OpenSSH服務器,那么就可以通過B形成隧道連接AC
1、上述例子中A-B-C連通后,我們思考一個問題,如果C想通過B連接A,也就是C-B-A可以連接嗎?
2、也許你已經注意到了,A是內網機器,所以C-B-A這個方向的連接不通。
3、雖然D-B-A這個方向的連接不通,但是A-B-D這個方向的連接是沒有問題的。
4、我們可以使用遠程SSH隧道的功能利用一條已經連接好的A-B-D方向的連接來完成 D-B-A方向的訪問。
與本地SSH一樣,我們在建立遠程SSH隧道之前要清楚下面幾個參數:
- 公網機器B的IP地址(這里是139.199.0.37)
- 公網機器B的端口號(這里是2222)
- 內網的機器A的IP地址(這里是192.168.199.16)
- 內網的機器A的端口號(端口:22)
在清楚了上面的參數后,我們使用下面的命令來建立一個遠程SSH隧道,在192.168.199.16的主機上執行下面的命令:
ssh -Nf -R 139.199.0.37:2222:192.168.199.16:22 139.199.0.37
1、這個命令也可以在局域網里192.168.199.12上執行
2、只要在局域網里192.168.199.12可以直接連接內網主機192.168199.16
3、且192.168.199.12可以直接與公網主機139.199.0.37建立ssh連接
4、那么任何外網主機通過訪問公網主機139.199.0.37:2222就會被連接到192.168.199.16:22
5、從而可以完成外網穿越NAT到內網的訪問,而不需要在內網網關和路由器上做任何操作。
現在,在IP是139.199.0.37的機器上,我們用下面的命令就可以登陸公司的IP是192.168.199.16的機器了。
ssh -p 2222 localhost
SSH隧道需要注意的地方
自動重連
? ? ? ?隧道可能因為某些原因斷開,例如:機器重啟,長時間沒有數據通信而被路由器切斷等等。因此我們可以用程序控制隧道的重新連接,可以使用一個簡單的循環控制隧道重新連接。
保持長時間連接
? ? ? ?有些路由器會把長時間沒有通信的連接斷開。SSH客戶端的TCPKeepAlive選項可以避免這個問題的發生,默認情況下它是被開啟的。如果它被關閉了,可以在ssh的命令上加上-o TCPKeepAlive=yes來開啟。
? ? ? ?另一種方法是,去掉-N參數,加入一個定期能產生輸出的命令。例如: vmstat,下面給出一個這種方法的例子:
ssh -R 139.199.0.37:2222:192.168.199.16:22 139.199.0.37 "vmstat 30"
如何將端口綁定到外部地址上
? ? ? ?使用上面的方法,映射的端口只能綁定在127.0.0.1這個接口上。也就是說,只能被本機自己訪問到。如何才能讓其他機器訪問這個端口呢?我們可以把這個 映射的端口綁定在0.0.0.0的接口上,方法是加上參數-b 0.0.0.0。同時還需要打開SSH服務器端的一個選項-GatewayPorts。默認情況下它應當是被打開的。如果被關閉的話,可以在/etc /sshd_config中修改GatewayPorts no為GatewayPorts yes來打開它。