SSH 反向隧道

2021-08-30 08:29:08 字數 4466 閱讀 7902

這篇文章主要介紹了如何利用ssh 反向隧道穿透nat,並演示了如何維持一條穩定的ssh 隧道。

假設有機器a 和b,a 有公網ip,b 位於nat 之後並無可用的埠**,現在想由a 主動向b 發起ssh 連線。由於b 在nat 後端,無可用公網ip + 埠這樣乙個組合,所以a 無法穿透nat,這篇文章應對的就是這種情況。

首先有如下約定,因為很重要所以放在前面:

機器代號

機器位置

位址賬戶

ssh/sshd 埠

是否需要執行sshd

a位於公網

a.site

usera22是

b位於nat 之後

localhost

userb22是

c位於nat 之後

localhost

userc22否

這裡預設你的系統init 程式為systemd,如果你使用其他的init 程式,如果沒有特殊理由還是換到乙個現代化的gnu/linux 系統吧……

這種手段實質上是由b 向a 主動地建立乙個ssh 隧道,將a 的6766 埠**到b 的22 埠上,只要這條隧道不關閉,這個**就是有效的。有了這個埠**,只需要訪問a 的6766 埠反向連線b 即可。

首先在b上建立乙個ssh 隧道,將a 的6766 埠**到b 的22 埠上:

b $ ssh -p 22 -qngfntr 6766:localhost:22 [email protected]

然後在a上利用6766 埠反向ssh 到b:

a $ ssh -p 6766 userb@localhost

要做的事情其實就是這麼簡單。

然而不幸的是ssh 連線是會超時關閉的,如果連線關閉,隧道無法維持,那麼a 就無法利用反向隧道穿透b 所在的nat 了,為此我們需要一種方案來提供一條穩定的ssh 反向隧道。

乙個最簡單的方法就是autossh,這個軟體會在超時之後自動重新建立ssh 隧道,這樣就解決了隧道的穩定性問題,如果你使用arch linux,你可以這樣獲得它:

$ sudo pacman -s autossh

下面在b上做之前類似的事情,不同的是該隧道會由autossh來維持:

b $ autossh -p 22 -m 6777 -nr 6766:localhost:22 [email protected]

-m引數指定的埠用來監聽隧道的狀態,與埠**無關。

之後你可以在a 上通過6766 埠訪問b 了:

a $ ssh -p 6766 userb@localhost

然而這又有了另外乙個問題,如果b 重啟隧道就會消失。那麼需要有一種手段在b 每次啟動時使用autossh來建立ssh 隧道。很自然的乙個想法就是做成服務,之後會給出在systemd下的一種解決方案。

之所以標題這麼起,是因為自己覺得這件事情有點類似於udp 打洞,即通過一台在公網的機器,讓兩台分別位於各自nat 之後的機器可以建立ssh 連線。

下面演示如何使用ssh 反向隧道,讓c 連線到b。

首先在a上編輯sshd的配置檔案/etc/ssh/sshd_config,將gatewayports開關開啟:

gatewayports yes

然後重啟sshd

a $ sudo systemctl restart sshd

然後在b上對之前用到的autossh指令略加修改:

b $ autossh -p 22 -m 6777 -nr '*:6766:localhost:22' [email protected]

之後在c上利用a的6766 埠ssh 連線到b

c $ ssh -p 6766 [email protected]

至此你已經輕而易舉的穿透了兩層nat。

整合一下前面提到的,最終的解決方案如下:

首先開啟asshdgatewayports開關,並重啟sshd(如有需要)。

然後在b上新建乙個使用者autossh,根據許可權最小化思想,b 上的autossh服務將以autossh 使用者的身份執行,以盡大可能避免出現安全問題:

b $ sudo useradd -m autossh

b $ sudo passwd autossh

緊接著在b上為autossh 使用者建立ssh 金鑰,並上傳到a:

b $ su - autossh

b $ ssh-keygen -t 'rsa' -c 'autossh@b'

b $ ssh-copy-id [email protected]

注意該金鑰不要設定密碼,也就是執行ssh-keygen指令時儘管一路回車,不要輸入額外的字元。

然後在b上建立以autossh 使用者許可權呼叫autossh的service 檔案。將下面文字寫入到檔案/lib/systemd/system/autossh.service,並設定許可權為644:

[unit]

description=auto ssh tunnel

after=network-online.target

[service]

user=autossh

type=******

execstart=/bin/autossh -p 22 -m 6777 -nr '*:6766:localhost:22' [email protected] -i /home/autossh/.ssh/id_rsa

execreload=/bin/kill -hup $mainpid

killmode=process

restart=always

[install]

wantedby=multi-user.target

wantedby=graphical.target

在b 上讓network-online.target生效:

b $ systemctl enable networkmanager-wait-online

如果你使用systemd-networkd,你需要啟用的服務則應當是systemd-networkd-wait-online

然後設定該服務自動啟動:

b $ sudo systemctl enable autossh

如果你願意,在這之後可以立刻啟動它:

b $ sudo systemctl start autossh

然後你可以在a上使用這條反向隧道穿透b 所在的nat ssh 連線到b:

a $ ssh -p 6766 userb@localhost

或者是在c上直接穿透兩層nat ssh 連線到b:

c $ ssh -p 6766 [email protected]

c $ ssh -p 6766 -qngfntd 7677 [email protected]

假設c是你家中的電腦,a是你的vps,b是你公司的電腦。如果你這樣做了,那麼為瀏覽器設定埠為7677sock4本地(localhost)**後,你就可以在家裡的瀏覽器上看到公司內網的網頁。

最後更新:2016-12-02, 00:03:54

ssh反向隧道

47.47.47.47新增安全組規則,本機安裝cygwin,安裝連線 安裝net下的autossh 和openssh即可 將本機秘鑰匯入47.47.47.47 在cygwin終端,執行 ssh keygen t rsa,一路enter,直到秘鑰生成 伺服器47.47.47.47上,新建使用者,密碼 ...

SSH反向隧道 內網穿透

構建隧道 需要在 a 機器上將sshd服務開啟gatewayports的配置 設定 etc ssh sshd config配置檔案中的 gatewayports no為gatewayports yessed i gatewayports c gatewayports yes etc ssh sshd...

利用雲主機做 ssh 反向隧道

背景 有三颱主機 a s b,系統均為linux。主機 a 和主機 b 在各自不同的內網,主機 s 為一台具有公網 ip 的雲主機。主機 a 與主機 b 都可以通過 ssh 連線主機 s。如下圖 需求 主機 a 需要通過主機 s 連線主機 b。方法 1 設定主機 s。gatewayports yes...