爛泥:學習ssh之ssh隧道應用

前幾篇有關ssh的文章,咱們只是介紹了ssh的登陸功能。其實ssh功能不僅是這些,這篇文章咱們來介紹下有關ssh隧道的功能。    前端

ssh隧道也叫ssh端口轉發,或者叫ssh tunnel,這些都是說的是ssh隧道功能。在此,咱們統稱爲ssh隧道。node

ssh隧道分爲正向隧道和反向隧道,在實際工做中咱們能夠根據須要來隨其分別使用。mysql

下面開始對正向和反向隧道分別介紹下,因爲使用平臺的不一樣,咱們分爲Linux和windows平臺。nginx

1、ssh正向隧道

什麼是ssh正向隧道?sql

就是client連上server後,而後把server能訪問的IP地址和端口(固然也包括server本身)鏡像到client的端口上。shell

在平時工做中,正向隧道是咱們使用最多的一種方式。數據庫

ssh正向隧道的命令以下:windows

ssh –L clientC_IP:clientC_port:serverB_IP:serverB_port -p serverA_sshport username@serverA_IP後端

上述命令的意思是在客戶端clientC上經過ssh鏈接服務器serverA,而後再把服務器serverB上的serverB_port端口映射到客戶端clientC的clientC_port端口。安全

也就是說若是咱們如今鏈接clientC的clientC_port端口的話,就是鏈接服務器serverB上的serverB_port的端口。

上述命令的使用場景通常是,客戶端clientC在公司內部使用的是內網IP,而服務器serverA和serverB在IDC機房或者在雲服務器商那邊。服務器serverA有公網IP能與客戶端clientC正常通訊,而服務器serverB沒有公網IP不能與客戶端clientC直接通訊,可是服務器serverA和服務器serverB是經過內網進行通訊的。如今要求客戶端clientC訪問serverB的相關端口。

客戶端clientC、服務器serverA與服務器serverB,通訊示意圖以下:

clip_p_w_picpath001

要達到上述要求,咱們就能夠經過ssh正向隧道的功能。爲了看出實際的效果,在此以鏈接後端的mysql數據庫爲例具體配置根據操做平臺的不一樣,分別介紹以下。

1.1 Linux下配置ssh正向隧道

在Linux下配置ssh正向隧道比較簡單,直接使用上述命令便可。以下:

ssh -g -f -NL 192.168.7.7:44010:10.66.115.185:3306 -i /home/ilanni/id_dsa_1024_0601 ilanni@115.159.39.187

ps -ef |grep 44010

clip_p_w_picpath002

上述命令的意思是在192.168.7.7這臺機器經過ssh方式鏈接115.159.39.187這臺服務器,而後把10.66.115.185這臺服務器的3306端口也便是mysql端口映射爲192.168.7.7的44010端口。

如今在局域網內,只要咱們鏈接192.168.7.7的44010端口,其實就在鏈接10.66.115.185的3306端口。

如今咱們來測試下,是否能夠鏈接成功。在與192.168.7.7同一個LAN中的任意一臺能鏈接192.168.7.7的44010端口的機器上,使用mysql的客戶端,以下:

clip_p_w_picpath003

注意:IP地址和端口必定要填寫爲192.168.7.7和44010,而用戶名和密碼只須要填寫mysql數據庫對應的用戶名和密碼便可。

clip_p_w_picpath004

clip_p_w_picpath005

經過上面兩張圖,咱們能夠看到鏈接192.168.7.7的44010端口,確實就是鏈接的10.66.115.185的3306端口。也便是在公司內部鏈接IDC內的後端數據庫。

若是公司內部對訪問後端數據庫有權限要求的話,咱們能夠在服務器serverB(mysql數據庫10.66.115.185)上只容許服務器serverA(115.159.39.187)訪問服務器serverB(10.66.115.185)的3306端口經過相關的安全策略好比IPtables或者mysql用戶受權對服務器serverA(115.159.39.187)。

而後再在服務器serverA(115.159.39.187)也便是192.168.7.7上經過IPtables配置相關的內網機器能訪問44010端口。

經過這樣的操做就能夠在公司內部達到控制後端mysql數據庫的權限控制。

1.2 windows下配置ssh正向隧道

在windows下配置ssh正向隧道,須要咱們使用ssh相關的客戶端軟件。在此我使用的xshell,固然你也可使用putty等之類的軟件。

打開xshell,新建一個鏈接到serverA(115.159.39.187)的會話,以下:

clip_p_w_picpath006

注意:這個地方填寫的是serverA的IP地址。

clip_p_w_picpath007

在這填寫的用戶就是serverA的用戶。

clip_p_w_picpath008

clip_p_w_picpath009

這張圖很重要,由於是ssh正向隧道,因此在此類型裏面選擇的是Local。

源主機填寫的是clientC的IP地址(在哪臺機器就填寫哪臺機器的IP),偵聽端口就是serverB的serverB_Port端口映射到clientC上的端口。注意偵聽端口能夠隨便自定義。

目標主機填寫的是serverB的IP地址,目標端口填寫的是serverB_Port端口號。

以上配置完畢後,咱們在本機192.168.1.180上鍊接看看是否能夠正確鏈接serverB的serverB_Port端口。以下:

clip_p_w_picpath010

clip_p_w_picpath011

clip_p_w_picpath012

經過以上幾張圖,咱們能夠很明顯的看出,以上配置是正確的。

注意:windows下配置ssh正向隧道和Linux仍是有所不一樣的。windows正確配置後,若是要使用隧道的話。xshell鏈接serverA的會話不能關閉。也就是說clientC鏈接serverA的ssh會話要一直開着,並且即便正常鏈接後,該ssh會話也是一直存在的。以下:

clip_p_w_picpath013

2、ssh反向隧道

什麼是ssh反向隧道?

就是client連上server後,而後把client能訪問的IP地址和端口(也包括client本身)鏡像到server的端口上。

ssh反向隧道使用場景,好比你的客戶端在內網,在外網是沒法直接訪問到的,這時用反向隧道打通一條鏈接,就能夠從外網經過這條隧道進來了。

ssh反向隧道的命令以下:

ssh –R serverA_IP:serverA_port:clientC_IP:clientC_port -p serverA_sshport username@serverA_IP

上述命令的意思是在客戶端clientC(或者clientC所在的LAN中的任意一臺能鏈接clientC_port的機器)上經過ssh鏈接服務器serverA,而後再把客戶端clientC的clientC_port端口映射到服務器serverA上的serverA_port端口。

也就是說若是咱們如今在服務器serverB上鍊接服務器serverA上的serverA_port端口的話,就是鏈接clientC的clientC_port端口。數據流向,以下圖示:

clip_p_w_picpath014

注意:建議修改serverA服務器的ssh配置文件sshd_config,添加GatewayPorts yes。而後重啓ssh服務。

clip_p_w_picpath015

這樣ssh反向隧道創建成功後,在serverA服務器監聽的端口爲serverA服務器的全部地址。以下:

clip_p_w_picpath016

若是不這樣修改的話,在serverA服務器監聽的端口會爲127.0.0.1。以下:

clip_p_w_picpath017

2.1 Linux下配置ssh反向隧道

在Linux下配置ssh反向隧道比較簡單,直接使用上述命令便可。以下:

ssh -g -f -NR 115.159.39.187:44010:192.168.5.174:3306 -i /home/ilanni/id_dsa_1024_0601 ilanni@115.159.39.187

ps -ef |grep 44010

clip_p_w_picpath018

上述命令的意思是在192.168.5.174這臺機器經過ssh方式鏈接115.159.39.187這臺服務器,而後把192.168.5.174這臺服務器的3306端口也便是mysql端口在115.159.39.187服務器上映射爲44010端口。

也就是說如今在公網上,只要咱們鏈接115.159.39.187的44010端口,其實就是在鏈接192.168.5.174的3306端口。

爲了能很實際的效果,如今咱們在192.168.5.174上新建ilanni這個一個數據庫。以下:

mysql -uroot -p123456

create database ilanni;

show databases;

clip_p_w_picpath019

如今咱們登陸到115.159.39.187服務器上進行查看。以下:

netstat -tunlp

clip_p_w_picpath016[1]

經過上圖,咱們能夠看到115.159.39.187服務器上確實在監聽44010端口。

下面咱們在115.159.39.187服務器上來鏈接下192.168.5.4的3306端口。以下:

mysql -h127.0.0.1 -P44010 -uroot -p123456

show databases;

clip_p_w_picpath020

經過上圖,咱們能夠很明顯的看到在115.159.39.187服務器上鍊接44010端口確實鏈接到了192.168.5.4的3306端口。

2.2 windows下配置ssh反向隧道

在windows下配置ssh反向隧道,和配置ssh正向隧道基本同樣也須要使用ssh相關的客戶端軟件,在此我使用的仍是xshell。

注意:ssh反向隧道,咱們能夠在與clientC同一LAN的任意一臺能訪問clientC_Port端口的機器上進行。

打開xshell,新建一個鏈接到serverA(115.159.39.187)的會話,以下:

clip_p_w_picpath021

注意:這個地方填寫的是serverA的IP地址。

clip_p_w_picpath007[1]

在這填寫的用戶就是serverA的用戶。

clip_p_w_picpath008[1]

clip_p_w_picpath022

這張圖很重要,由於是ssh反向隧道,因此在此類型裏面選擇的是Remote。

源主機填寫的是serverA的IP地址,偵聽端口就是clientC的clientC_Port端口映射到serverA上的端口。注意偵聽端口能夠隨便自定義。

目標主機填寫的是clientC的IP地址,目標端口填寫的是clientC_Port端口號。

如今咱們登陸到115.159.39.187服務器上進行查看。以下:

netstat -tunlp

clip_p_w_picpath016[2]

經過上圖,咱們能夠看到115.159.39.187服務器上確實在監聽44010端口。

下面咱們在115.159.39.187服務器上來鏈接下192.168.5.4的3306端口。以下:

mysql -h127.0.0.1 -P44010 -uroot -p123456

show databases;

clip_p_w_picpath020[1]

經過上圖,咱們能夠很明顯的看到在115.159.39.187服務器上鍊接44010端口確實鏈接到了192.168.5.4的3306端口。

3、實際應用

以上介紹了ssh正反向隧道詳細使用方法,以mysql的3306端口爲例子。下面我就結合實際的工做需求,介紹下ssh隧道的其餘使用場合。

3.1 遠程桌面

ssh隧道也是代理能夠在windows以及Linux的遠程桌面的,這種場合通常是在這樣的場合下使用。

公司對外提供×××服務,可是該***服務器在網絡DMZ防火區。***服務器能夠訪問lan內的機器,可是lan內的機器不能訪問***服務器。結構圖,以下:

clip_p_w_picpath023

***客戶端鏈接進來後,咱們只須要在DMZ區的服務器上,建議一條ssh正向隧道便可鏈接隧道指定的lan機器。

以下:

ssh -g -f -N -L 7002:192.168.5.140:3389 wangxy@192.168.7.7

clip_p_w_picpath024

上述命令的意思是把192.168.5.140的3389端口映射到192.168.7.7的7002端口。也就說咱們如今在***客戶端鏈接192.168.7.7的7002端口其實就是鏈接192.168.5.140的3389端口。以下:

clip_p_w_picpath025

clip_p_w_picpath026

clip_p_w_picpath027

經過上圖,咱們能夠很明顯的看出ssh正向隧道已經代理了遠程桌面。

3.2 nginx訪問

如今公司線上雲服務器上有一臺業務serverB,前端使用nginx作反向代理,後端使用的是nodejs,serverB只對雲服務器提供訪問。

目前要求在公司內部也能夠訪問serverB上的nginx,而且不是公司內部全部人員均可以訪問,只有指定的個別人才能有權限訪問。

分析:若是要使公司內部訪問serverB上的nginx,咱們只須要在serverB開放對公司公網的IP訪問權限便可。

可是若是還要控制訪問權限的話,這個就須要藉助ssh正向隧道來實現了。

在雲服務器上開放一臺serverA,serverA能訪問serverB的nginx(該訪問權限的控制能夠經過nginx或者iptables進行控制),而serverA又對公司的公網IP開放SSH端口。

而後在公司內網的任意一臺lanC上,作一條ssh正向隧道。該隧道把serverB的nginx端口映射到serverC上一個PortC端口。

此時咱們再在lanC上對PortC端口的訪問權限進行控制(該訪問權限的控制能夠經過nginx或者iptables進行控制)便可達到上述要求。

如今lanC上使用以下命令:

ssh -g -f -NL 192.168.5.4:8080:10.104.13.164:80 -i id_dsa_1024_0601 ilanni@115.159.39.187

ps -ef |grep 8080

clip_p_w_picpath028

上述命令的意思是在192.168.5.4上經過115.159.44.136這臺服務器把10.105.12.163這臺服務器的80端口映射爲192.168.5.4的8080端口。

lanC的nginx配置以下:

server {

listen 80;

server_name 192.168.5.4;

allow 127.0.0.1;

allow 192.168.5.140;

deny all;

location / {

proxy_pass http://192.168.5.4:8080;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection $connection_upgrade;

proxy_connect_timeout 200;

proxy_send_timeout 200;

proxy_read_timeout 600;

}

}

上述nginx配置的意思是容許192.168.5.140這臺機器訪問192.168.5.4的80端口,而192.168.5.4會把訪問192.168.5.4:80的請求交給192.168.5.4:8080進行處理。

這樣就達到了前文的要求。

如今在192.168.5.140上訪問192.168.5.4的80端口。以下:

clip_p_w_picpath029

經過上圖,咱們能夠很明顯的看出ssh正向隧道已經能夠代理nginx。

3.3 ssh多級隧道跳轉

ssh多級隧道跳轉看起來感受很難,其實若是細細拆分的話很簡單的。

下面有一個實際的要求,咱們來分析下。

狀況介紹:

serverC只容許serverB鏈接serverC的1001端口其餘端口不容許serverB鏈接,而serverB只容許serverA能鏈接serverB的22端口,不能鏈接serverC的1001端口,同時serverA是隻對公網開放的ssh的22端口其餘端口不對公網開放。

要求:

如今要求lan內部的clientC能鏈接serverC的1001端口。

分析:

若是咱們直接serverC的1001端口那是不可能的,由於安全策略有限制。那麼咱們能夠經過ssh正向隧道來解決此問題。

首先在serverA上經過serverB作一條ssh正向隧道把serverC的1001端口映射爲serverA的1002端口。

即訪問serverA的1002端口就是訪問serverC的1001端口。

由於serverA的1002端口不對公網開放,那麼爲了能訪問serverA的1002端口,咱們能夠在clientC經過serverA再作一條ssh正向隧道把serverA的1002端口映射爲clientC的1003端口。

也就是說此時咱們鏈接clientC的1003端口其實就是在鏈接serverC的1001端口。

以上ssh多級隧道跳轉的原理介紹清楚了,在次就不在進行演示。若是有哪位不懂的能夠多多理解理解上面的描述。

相關文章
相關標籤/搜索