在 Raspberry Pi 上自動化 SSH 反向隧道

在 Raspberry Pi 上自動化 SSH 反向隧道

很多天來,我一直在想如何自動建立反向隧道。

我有許多在 LAN 內使用 NAT 的遠端 Raspberry,以及一個我用作伺服器的 Raspberry,可透過 Internet 存取。

我在我的網站上實作了一個向遠端樹莓派發送單一命令的系統。

每個遠端 Raspberry 每分鐘 (crontab) 都會檢查可用命令的存在,如果有,則它會下載該命令,建立可執行檔並執行它。這是 crontab 檔案的程式碼:

#! /bin/bash

sudo wget -c --output-document=ipdiscover.php "www.myserver.com/checkforcommands.php";

comando=$(cat ipdiscover.php);

sudo rm "/esegui.sh";

echo "#! /bin/bash" >> /esegui.sh;
echo "" >> /esegui.sh;
echo -e $comando >> /esegui.sh;
echo "exit 0" >> /esegui.sh;

sudo chmod +x /esegui.sh;

sudo /esegui.sh;

sudo rm "ipdiscover.php";

sudo date >>/tmp/crontest.txt;

這個系統功能很好,但是我不能用它來建立反向隧道。

如果在遠端伺服器上執行以下程式碼:

sudo /usr/bin/ssh -gNnT -R 2222:localhost:22 pi@publicserverIP;

然後一切正常,但如果我從 crontab 腳本運行它,它就不起作用。

我創建了沒有密碼的證書,並將其從遠端 Raspberry 發送到伺服器,以便不進行登入存取。

答案1

您不需要從cronvia執行命令sudo

建立一些如下所示的腳本,並將其放入將與伺服器建立反向 SSH 連線的使用者的主目錄中:

#!/bin/sh

### reverseSSHscript.sh ###

### (use public key authentication, so you don't need 
### to enter password for your server)
PrivateKeyToAccessCentralServer='/path/to/the/private/ssh/ServerKey.pem'

(
/usr/bin/nohup     \ 
 /usr/bin/ssh -gNnT \
  -i "${PrivateKeyToAccessCentralServer}" \
  -o ExitOnForwardFailure=yes     \
  -o ServerAliveInterval=60       \
  -o ServerAliveCountMax=1        \
  -o TCPKeepAlive=no              \
  -o UserKnownHostsFile=/dev/null \
  -o StrictHostKeyChecking=no     \
  -o CheckHostIP=no               \
  -R 2222:localhost:22 pi@publicserverIP
) &

然後創建 cron 的任務來運行它:

echo "@reboot User /path2the_script_shown_above/reverseSSHscript.sh" |
   sudo tee /etc/cron.d/reverseSSH2home

那麼它應該可以工作。
順便說一句,您可能希望在某些限制下運行此腳本,User而不僅僅是root為了安全起見。

您還需要實作一些邏輯來reverseSSHscript.sh檢查連線是否已建立,以防止建立多個會話。

也定期從 cron 執行一些額外的檢查,以測試反向連線連接埠在您的伺服器上是否仍然有效;像這樣的東西:

chkRemPort() {
    # Connect to intermediate host and check if remote forwarded port is alive
    echo $(/usr/bin/ssh -4 -f -q        \
        -o BatchMode=yes                \
        -o UserKnownHostsFile=/dev/null \
        -o StrictHostKeyChecking=no     \
        -o CheckHostIP=no               \
        -i /path/to/the/private/ssh/ServerKey.pem      \
        pi@publicserverIP               \
        /bin/nc -w 3 -zv localhost 2222 2>&1 | /bin/grep succeeded > /dev/null ;    \
        [ $? -eq 0 ] && { echo 'OK'; } || { echo 'FAILED'; }; exit; )
}

如果檢查失敗,請嘗試與您的伺服器建立新的反向會話。

PS
每個 Raspberry Pi 上的反向連接埠應該不同,以避免伺服器上的連接埠之間發生衝突

相關內容