ssh端口轉發

玩轉SSH端口轉發

SSH有三種端口轉發模式,本地端口轉發(Local Port Forwarding)遠程端口轉發(Remote Port Forwarding)以及動態端口轉發(Dynamic Port Forwarding)。對於本地/遠程端口轉發,二者的方向剛好相反。動態端口轉發則能夠用於FQ。html

SSH端口轉發也被稱做SSH隧道(SSH Tunnel),由於它們都是經過SSH登錄以後,在SSH客戶端SSH服務端之間創建了一個隧道,從而進行通訊。SSH隧道是很是安全的,由於SSH是經過加密傳輸數據的(SSH全稱爲Secure Shell)。linux

在本文全部示例中,本地主機A1爲SSH客戶端,遠程雲主機B1爲SSH服務端。從A1主機經過SSH登錄B1主機,指定不一樣的端口轉發選項(-L、-R和-D),便可在A1與B1之間創建SSH隧道,從而進行不一樣的端口轉發。git

本地端口轉發

應用場景:

遠程雲主機B1運行了一個服務,端口爲3000,本地主機A1須要訪問這個服務。github

示例爲一個簡單的Node.js服務:shell

var http = require('http');

var server = http.createServer(function(request, response)
{
    response.writeHead(200,
    {
        "Content-Type": "text/plain"
    });
    response.end("Hello Fundebug\n");
});

server.listen(3000);

假設雲主機B1的IP爲103.59.22.17,則該服務的訪問地址爲:http://103.59.22.17:3000ubuntu

爲啥須要本地端口轉發呢?

通常來說,雲主機的防火牆默認只打開了22端口,若是須要訪問3000端口的話,須要修改防火牆。爲了保證安全,防火牆須要配置容許訪問的IP地址。可是,本地公網IP一般是網絡提供商動態分配的,是不斷變化的。這樣的話,防火牆配置須要常常修改,就會很麻煩。瀏覽器

什麼是本地端口轉發?

所謂本地端口轉發,就是將發送到本地端口的請求,轉發到目標端口。這樣,就能夠經過訪問本地端口,來訪問目標端口的服務。使用-L屬性,就能夠指定須要轉發的端口,語法是這樣的:安全

-L 本地網卡地址:本地端口:目標地址:目標端口

經過本地端口轉發,能夠將發送到本地主機A1端口2000的請求,轉發到遠程雲主機B1的3000端口。網絡

# 在本地主機A1登錄遠程雲主機B1,並進行本地端口轉發
ssh -L localhost:2000:localhost:3000 root@103.59.22.17

若是遠程主機也是經過隧道來進行訪問的話,那麼須要加入端口號來進行登陸而不是默認的ssh的22端口號ssh

# 假設要訪問的主機是屬於遠程內網主機,那麼此時就是搭建的隧道來訪問了(隧道的搭建也是經過ssh端口轉發來搭建的),這裏的2061端口就是暴露出的端口,經過這個端口能夠訪問到遠程內網主機
ssh -L localhost:2000:localhost:3000 root@103.59.22.17 -p 2061

這樣,在本地主機A1上能夠經過訪問http://localhost:2000來訪問遠程雲主機B1上的Node.js服務。

# 在本地主機A1訪問遠程雲主機B1上的Node.js服務
curl http://localhost:2000
Hello Fundebug

實際上,-L選項中的本地網卡地址是能夠省略的,這時表示2000端口綁定了本地主機A1的全部網卡:

# 在本地主機A1登錄遠程雲主機B1,並進行本地端口轉發。2000端口綁定本地全部網卡
ssh -L 2000:localhost:3000 root@103.59.22.17

若本地主機A2可以訪問A1,則A2也能夠經過A1訪問遠程遠程雲主機B1上的Node.js服務。

另外,-L選項中的目標地址也能夠是其餘主機的地址。假設遠程雲主機B2的局域網IP地址爲192.168.59.100,則能夠這樣進行端口轉發:

# 在本地主機A1登錄遠程雲主機B1,並進行本地端口轉發。請求被轉發到遠程雲主機B2上
ssh -L 2000:192.168.59.100:3000 root@103.59.22.17

若將Node.js服務運行在遠程雲主機B2上,則發送到A1主機2000端口的請求,都會被轉發到B2主機上。

遠程端口轉發

應用場景:

本地主機A1運行了一個服務,端口爲3000,遠程雲主機B1須要訪問這個服務。

將前文的Node.js服務運行在本地,在本地就能夠經過http://localhost:3000訪問該服務。

爲啥須要遠程端口轉發呢?

一般,本地主機是沒有獨立的公網IP的,它與同一網絡中的主機共享一個IP。沒有公網IP,雲主機是沒法訪問本地主機上的服務的。

什麼是遠程端口轉發?

所謂遠程端口轉發,就是將發送到遠程端口的請求,轉發到目標端口。這樣,就能夠經過訪問遠程端口,來訪問目標端口的服務。使用-R屬性,就能夠指定須要轉發的端口,語法是這樣的:

-R 遠程網卡地址:遠程端口:目標地址:目標端口

這時,經過遠程端口轉發,能夠將發送到遠程雲主機B1端口2000的請求,轉發到本地主機A1端口3000。

# 在本地主機A1登錄遠程雲主機B1,並進行遠程端口轉發
ssh -R localhost:2000:localhost:3000 root@103.59.22.17

這樣,在遠程雲主機A1能夠經過訪問http://localhost:2000來訪問本地主機的服務。

# 在遠程雲主機B1訪問本地主機A1上的Node.js服務
curl http://localhost:2000
Hello Fundebug

同理,遠程網卡地址能夠省略,目標地址也能夠是其餘主機地址。假設本地主機A2的局域網IP地址爲192.168.0.100。

# 在本地主機A1登錄遠程雲主機B1,並進行遠程端口轉發
ssh -R 2000:192.168.0.100:3000 root@103.59.22.17

若將Node.js服務運行在本地主機A2上,則發送到遠程雲主機A1端口2000的請求,都會被轉發到A2主機上。

動態端口轉發

應用場景:

遠程雲主機B1運行了多個服務,分別使用了不一樣端口,本地主機A1須要訪問這些服務。

爲啥須要動態端口轉發呢?

一方面,因爲防火牆限制,本地主機A1並不能直接訪問遠程雲主機B1上的服務,所以須要進行端口轉發;另外一方面,爲每一個端口分別建立本地端口轉發很是麻煩。

什麼是動態端口轉發?

對於本地端口轉發遠程端口轉發,都存在兩個一一對應的端口,分別位於SSH的客戶端和服務端,而動態端口轉發則只是綁定了一個本地端口,而目標地址:目標端口則是不固定的。目標地址:目標端口是由發起的請求決定的,好比,請求地址爲192.168.1.100:3000,則經過SSH轉發的請求地址也是192.168.1.100:3000

-D 本地網卡地址:本地端口

這時,經過動態端口轉發,能夠將在本地主機A1發起的請求,轉發到遠程主機B1,而由B1去真正地發起請求。

# 在本地主機A1登錄遠程雲主機B1,並進行動態端口轉發
ssh -D localhost:2000 root@103.59.22.17

而在本地發起的請求,須要由Socket代理(Socket Proxy)轉發到SSH綁定的2000端口。以Firefox瀏覽器爲例,配置Socket代理須要找到首選項>高級>網絡>鏈接->設置:

img

這樣的話,Firefox瀏覽器發起的請求都會轉發到2000端口,而後經過SSH轉發到真正地請求地址。若Node.js服務運行在遠程雲主機B1上,則在Firefox中訪問localhost:3000便可以訪問。若是主機B1可以訪問外網的話,則能夠FQ……

鏈式端口轉發

本地端口轉發遠程端口轉發結合起來使用,能夠進行鏈式轉發。假設A主機在公司,B主機在家,C主機爲遠程雲主機。A主機上運行了前文的Node.js服務,須要在B主機上訪問該服務。因爲A和B不在同一個網絡,且A主機沒有獨立公共IP地址,因此沒法直接訪問服務。

經過本地端口轉發,將發送到B主機3000端口的請求,轉發到遠程雲主機C的2000端口。

# 在B主機登錄遠程雲主機C,並進行本地端口轉發
ssh -L localhost:3000:localhost:2000 root@103.59.22.17

經過遠程端口轉發,將發送到遠程雲主機C端口2000的請求,轉發到A主機的3000端口。

# 在A主機登錄遠程雲主機C,並進行遠程端口轉發
ssh -R localhost:2000:localhost:3000 root@103.59.22.17

這樣,在主機B能夠經過訪問http://localhost:3000來訪問主機A上的服務。

# 在主機B訪問主機A上的服務
curl http://localhost:3000
Hello Fundebug

參考連接

原文連接:https://blog.fundebug.com/2017/04/24/ssh-port-forwarding/

相關文章
相關標籤/搜索