這篇文章主要介紹了如何利用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,你可以這樣獲得它:
下面在b上做之前類似的事情,不同的是該隧道會由autossh
來維持:
-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
開關開啟:
然後重啟sshd
:
然後在b上對之前用到的autossh
指令略加修改:
之後在c上利用a的6766 埠ssh 連線到b:
c $ ssh -p 6766 [email protected]至此你已經輕而易舉的穿透了兩層nat。
整合一下前面提到的,最終的解決方案如下:
首先開啟a上sshd
的gatewayports
開關,並重啟sshd
(如有需要)。
然後在b上新建乙個使用者autossh,根據許可權最小化思想,b 上的autossh
服務將以autossh 使用者的身份執行,以盡大可能避免出現安全問題:
b $ sudo passwd autossh
緊接著在b上為autossh 使用者建立ssh 金鑰,並上傳到a:
b $ su - autosshb $ 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:
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 $ sudo systemctl enable autosshsystemd-networkd
,你需要啟用的服務則應當是systemd-networkd-wait-online
。
如果你願意,在這之後可以立刻啟動它:
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是你公司的電腦。如果你這樣做了,那麼為瀏覽器設定埠為7677
的sock4
本地(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...