範例環境為 Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-48-generic x86_64)

首先先來說普通的反向SSH作用,需要先備知識知道SSH預設是22 port
假設有兩台電腦,
Private IP是內部網路,無法被外部連線
Public IP是可以被外部連線的伺服器,只要確保可以被Private IP所連線到,可以在任意地方。

1. Private IP是192.168.0.2
2. Public IP是120.105.128.100

建立Tunnel

首先先在Public IP建立一個帳號給Private IP連線,範例建立stem帳號,因為不用建立多於東西,所以使用useradd指令。在Public IP主機中執行↓

sudo adduser stem

然後應該一路按Enter到底即可

如果使用其他網路介面卡存取,否則只能localhost連線,當然如果沒需求可以不用執行此步驟,需要設定編輯/etc/ssh/sshd,在Public IP主機中執行↓

sudo nano /etc/ssh/sshd_config

然後在最下方加入GatewayPorts yes
之後儲存離開,並且重開sshd

sudo service sshd restart

接下來使用在Private IP主機中執行↓

ssh -NfR 0.0.0.0:2222:localhost:22 stem@120.105.128.100 -p 22

參數說明:

  • ssh 是實現SSH協定的程式
  • N 參數是不要進去遠端的Shell,拿掉就如同平常登入SSH一樣,只是有R參數功能。
  • f 參數是讓ssh在背景執行,通常搭配N參數,如果你要關掉可以用kill,但測試時可以考慮拿掉Nf參數,用exit退出。
  • R 參數是Remote Port Forwarding的意思
  • 0.0.0.0:2222:localhost:22 是指將Public IP主機的所有網路卡2222 port對應到Prvate IP的22 port
  • stem@120.105.128.100 是指你的登入帳號stem和主機位置120.105.128.100,登入的port是22

目前為止基本上功能已經正常了,但我們希望可以無時無刻確認連線正常,以及開機執行,所以我們繼續~

設定憑證登入(不須密碼登入)

首先呢,我們希望登入時不需輸入密碼,所以用憑證登入,我們先產生一個金鑰,在Private IP主機中執行↓

ssh-keygen

然後一路按Enter到底應該就好了,它會把憑證存在~/ssh/id_rsa
接下來把憑證上傳到遠端主機,在Private IP主機中執行↓

ssh-copy-id -p 22 stem@120.105.128.100

然後測試一下是不是登入ssh都不用輸入密碼了

※如果無法使用ssh-copy-id指令,請編輯Public IP主機中~/.ssh/authorized_keys檔案,自己加上去Private IP主機中檔案~/.ssh/id_rsa.pub


安裝AutoSSH,並設定自動連線

然後我們先用AutoSSH來確保無時無刻連線正常,要先安裝AutoSSH,在Private IP主機中執行↓

sudo apt install autossh

然後設定自動連線,我知道網路上有些教學沒有參數f,但我在測試時不會有效果,所以在Private IP主機中執行↓

autossh -M 20000 -NfR 0.0.0.0:2222:localhost:22 stem@120.105.128.100 -p 22

參數說明

  • autossh 是指令名稱
  • M 參數是監聽的port,會利用該port發送數據,port+1會接收它
  • 後面就是按照SSH的指令

開機執行

接下來要設定開機時執行該指令,接下來的指令都在Private IP主機中執行

sudo nano /lib/systemd/system/rc-local.service

檔案最後面加入

[Install] 
WantedBy=multi-user.target
Alias=rc-local.service

然後建立rc.local檔案

sudo nano /etc/rc.local

檔案內容為(desktop是要執行的使用者名稱)

#!/bin/sh -e

/bin/su -c '/usr/bin/autossh -M 20000 -NfR 0.0.0.0:2222:localhost:22 stem@120.105.128.100 -p 22' - desktop

exit 0

加入可執行權限

sudo chmod u+x /etc/rc.local

然後設定開機啟動,並且測試

sudo systemctl enable rc-local
sudo systemctl start rc-local

可以檢視看看是否已啟用,當然更保險是重開機

sudo systemctl status rc-local