SSH遠端埠轉發實戰詳解

iX發表於2021-08-03

問題

前段時間在外地沒有在實驗室,隨身攜帶了一個膝上型電腦。但是筆記本效能不夠,想用SSH遠端連線實驗室的電腦。問如何連線?現有以下裝置

裝置 IP 備註 系統
實驗室電腦C1 192.168.0.24 內網,可訪問外網。SSH登陸埠為321。 Linux
膝上型電腦A1 動態變化 無公網IP Linux、win
雲端伺服器B1 113.4.67.278 有公網IP Linux
20210803153222

目標:

訪問實驗室電腦C1321埠。

解決辦法:

  1. 如果區域網共用一個公網IP(此公網IP可以在外網訪問),且可以操作實驗室的路由器,可以在路由器上新增埠對映。這樣可以通過直接訪問公網IP的虛擬埠,訪問到區域網內的電腦。

    但是很遺憾筆者實驗室的公網IP被學校的防火牆攔住了,無法在外網直接訪問。

  2. 藉助各種內網穿透的軟體,但是題主沒有找到一個魯棒可靠的軟體。實在要推薦一個那就 ngrok

  3. SSH遠端埠轉發訪問區域網電腦,此方法需要一箇中轉伺服器(有公網IP)。

前面兩種方法本文就不展開介紹了,主要介紹第三種方法。

SSH遠端埠轉發

所謂遠端埠轉發,就是將傳送到遠端埠的請求,轉發到目標埠。這樣就可以通過訪問遠端埠,來訪問目標埠的服務。

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

通過遠端轉發,我們就可以通過訪問雲主機B1XXX埠來訪問實驗室主機C1321埠。

使用-R屬性,就可以指定需要轉發的埠,語法是這樣的:

-R 遠端網路卡地址:遠端埠:目標地址:目標埠

實現

實驗室主機C1上操作

ssh -fCNR port:localhost:321 root@113.4.67.278
# 遠端網路卡地址可省略,表示繫結了C1的所有網路卡
# port : 自定義一個埠,如1321
# 321 : 實際想訪問的本地埠
# root和ip地址根據實際情況改寫

# -f : 表示SSH連線在後臺執行
# -C : 表示壓縮資料傳輸
# -N : 用於埠轉發,表示建立的SSH只用於埠轉發,不能執行遠端命令
# -R : 指定遠端埠轉發

通過遠端轉發,我們可以直接通過SSH在雲端伺服器B1上登入C1

ssh -p 1321 name@localhost
# name改寫成C1的使用者名稱

但是我們還不能在A1上直接登入C1,還要在B1電腦上操作:

sudo echo 'GatewayPorts yes' >> /etc/ssh/sshd_config
sudo service ssh restart
# GatewayPorts yes確保外網也能訪問這個1321這個監聽埠,而不是隻能被localhost訪問。

這樣我們就可以直接在A電腦訪問C電腦了:

ssh -p 1321 name@113.4.67.278
# name改寫成C1的使用者名稱

存在問題

  1. ssh會因為超時而關閉,因此不穩定
  2. 開關機之後通道就不存在了,因此還要設定開機自啟

為了解決兩個問題我採用了crontab。通過crontab 命令,我們可以在固定的間隔時間執行指定的系統指令或 shell script指令碼。

C1金鑰連線B1

因為每次ssh遠端轉發,都需要輸入B1的使用者密碼,因此要設定金鑰連線,省去輸入密碼的過程。

C1上操作

ssh-copy-id -i keyfile nameB1@113.4.67.278
# -i keyfile keyfile指定公鑰檔案上傳到B1上,也可以不指定
# nameB1 B1使用者名稱

cron

在Linux系統中,計劃任務一般是由 cron 承擔,我們可以把 cron 設定為開機時自動啟動。

/sbin/service cron start //啟動服務 
/sbin/service cron stop //關閉服務  

/sbin/service cron restart //重啟服務 
/sbin/service cron reload //重新載入配置

cron可以讓系統在指定的時間,去執行某個指定的工作,我們可以使用 crontab 指令來管理cron機制

crontab 引數

usage:	crontab [-u user] file
	crontab [ -u user ] [ -i ] { -e | -l | -r }
		(default operation is replace, per 1003.2)
	-u 指定使用者,不指定使用者就預設自身
	-e	(edit user's crontab) (使用預設的編輯器,開啟crontab並編輯)
	-l	(list user's crontab) (列出crontab中的內容)
	-r	(delete user's crontab) (移除crontab)
	-i	(prompt before deleting user's crontab) (移除crontab,不過會再確認一下)

語法示例

分(0-59) 時(0-23) 日期(1-31) 月(1-12) 星期(0-7)(0和7都是周天)
*/5 * * * * 每五分鐘執行
0-5 * * * * 每小時的前五分鐘執行
0,1 * * * * 每小時的前兩分鐘執行
0 * * * *   0分時執行,即每小時執行一次
0 0 * * *   0時0分時執行,即每天執行一次
0 0 1 * *   1號0時0分時執行,即每月執行一次      
* : 代表取值範圍內的所有數字
/ : 代表“每”
- : 代表從某數字到某數字
, : 代表分開幾個離散的數字

因此我們定時執行ssh遠端轉發,就可以確保連線的穩定性。

# 編輯crontab
crontab -e 
# 新增命令
*/10 * * * * ssh -fCNR 1321:localhost:321 root@113.4.67.278
# 開機自啟
systemctl enable --now cron

至此大功告成。

最後

SSH除了遠端轉發,還有逆向的本地轉發。還有動態轉發,動態轉發可以做簡易的VPN。

埠轉發詳解可參考文章2,3

參考文章

  1. https://www.cnblogs.com/bubaya/p/7828817.html
  2. https://blog.fundebug.com/2017/04/24/ssh-port-forwarding/
  3. https://wangdoc.com/ssh/port-forwarding.html
  4. https://zhuanlan.zhihu.com/p/271980834

相關文章