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

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

很多天来,我一直在思考如何自动建立反向隧道。

我有许多在其 LAN 内使用 NAT 的远程 Raspberry,还有一个用作服务器的 Raspberry,可通过互联网访问。

我在我的网站上实现了一个系统,用于向远程 Raspberries 发送单个命令。

每个远程 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

您不需要通过 运行cron命令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而不是在 as 下运行此脚本。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 上的反向端口应该不同,以避免服务器上的端口发生冲突

相关内容