linux 如何设置后台ssh隧道的自动(重新)启动

7jmck4yq  于 2023-06-29  发布在  Linux
关注(0)|答案(3)|浏览(184)

我是linux的初学者,也是ssh和tunnels的新手。
无论如何,我的目标是在后台保持一个ssh隧道打开。
为了做到这一点,我编写了以下批处理,然后将其添加到crontab中(该批处理在工作日从上午8点到晚上9点每5分钟自动处理一次)。我在stackoverflow中的其他一些线程中读到,应该使用autossh,这将确保ssh通过定期检查总是可以的。我也是

#!/bin/bash
LOGFILE="/root/Tunnel/logBatchRestart.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date & time of log

if ! ps ax | grep ssh | grep tunnelToto &> /dev/null
then
    echo "[$NOW] ssh tunnel not running : restarting it" >> $LOGFILE
    autossh -f -N -L pppp:tunnelToto:nnnnn nom-prenom@193.xxx.yyy.zzz -p qqqq
    if ! ps ax | grep ssh | grep toto &> /dev/null
    then
            echo "[$NOW] failed starting tunnel" >> $LOGFILE
    else
            echo "[$NOW] restart successfull" >> $LOGFILE
    fi
fi

我的问题是,有时隧道停止工作,虽然一切看起来都很好(ps ax| grep ssh >结果显示了两个预期的任务:autossh主任务和ssh隧道本身)。实际上我知道这个问题,因为隧道被第三方软件使用,一旦隧道不再响应,该软件就会触发错误。
因此,我想知道我应该如何改善我的一批,以便它将能够检查隧道,并重新启动它,如果它碰巧是死的。我在there中看到了一些想法,但它是由“autossh”提示得出的结论...我已经在用了所以,我没办法了…如果你们中的任何人有,我很乐意看看他们!
谢谢你对我的问题感兴趣,以及你的(可能)建议!

ig9co6j1

ig9co6j11#

您可以使用以下技巧来代替使用ps检查ssh进程
创建脚本,执行以下操作并通过crontab -e将其添加到crontab

#!/bin/sh

REMOTEUSER=username
REMOTEHOST=remotehost 

SSH_REMOTEPORT=22
SSH_LOCALPORT=10022

TUNNEL_REMOTEPORT=8080
TUNNEL_LOCALPORT=8080

createTunnel() {
    /usr/bin/ssh -f -N  -L$SSH_LOCALPORT:$REMOTEHOST:SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:TUNNEL_REMOTEPORT $REMOTEUSER@$REMOTEHOST
    if [[ $? -eq 0 ]]; then
        echo Tunnel to $REMOTEHOST created successfully
    else
        echo An error occurred creating a tunnel to $REMOTEHOST RC was $?
    fi
}

## Run the 'ls' command remotely.  If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER@localhost ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
    echo Creating new tunnel connection
    createTunnel
fi

实际上,这个脚本将打开两个端口

  • 端口22,用于检查隧道是否仍然有效
  • 端口8080,这是您可能要使用的端口

请检查并通过评论向我发送进一步的问题

dsf9zpds

dsf9zpds2#

你不需要bash来做这个!
现在大多数linux机器都带有**systemd**,它对启动/停止/重新启动服务提供了可靠的支持,并具有可配置的条件和超时。
1.以root用户身份创建systemd服务单元:

sudo vim /etc/systemd/system/ssh-tunnel.service

1.将以下配置粘贴到新文件中:

[Unit]
Description=ssh
Wants=network-online.target
After=network-online.target
StartLimitIntervalSec=5
StartLimitBurst=1

[Service]
# NOTE: you MUST start ssh *without!* the -f (forking) switch, 
# so that systemd can monitor it and detect when the tunnel goes down
Type=simple
# forward *local* port 80 to port 8088 on the remote host
ExecStart=ssh username@myremote-host.com -N -R 8088:localhost:80
# send an exit signal to the SSH master process that controls the tunnel
ExecStop=ssh arh -O exit -R 8088:localhost:80
# see: https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStartSec=
TimeoutStartSec=10
TimeoutStopSec=10
Restart=always
RestartSec=10

# TODO: set the user name here; root will be used if unset
# make sure the user has the correct ssh key or otherwise 
# explicitly pass the key with `ssh -i /path/to/key/id_rsa   
User=my-user-name

# TODO: for debugging only; remove once you get the service working
StandardOutput=console

[Install]
WantedBy=multi-user.target

1.启用并启动服务单元:

# make service start on every boot (after network is up)
sudo systemctl enable ssh-tunnel

sudo systemctl start ssh-tunnel

1.(可选)检查服务状态:

systemctl status ssh-tunnel
如何操作?

StartLimitIntervalSec配置服务开始计数的间隔。如果一个服务在此时间间隔内启动超过StartLimitBurst次 *,则不允许再启动。TimeoutStartSec配置systemd在服务被视为处于失败状态之前等待服务启动的最长时间。
使用上面的配置,如果SSH隧道关闭,例如,由于临时网络故障,systemd将等待10秒,然后重新启动隧道。
这种方法是可靠的,可配置的,并实现了与其他答案或实用程序(如autossh)中给出的脚本相同的结果,但可以与任何其他工具一起使用的通用方式。
这里的关键是在 foreground 模式下启动SSH(即不要使用-fn交换机将其发送到后台),以便systemd可以监视服务是否仍处于活动状态,并在出现故障时重新启动它。

另请参阅:

a14dhokn

a14dhokn3#

  • (我把这个作为一个答案,因为没有足够的空间来评论它)*

好了,我成功地运行了批处理来启动ssh隧道(我必须指定我的主机名而不是localhost,以便它可以被触发):

#!/bin/bash

LOGFILE="/root/Tunnel/logBatchRedemarrage.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date et heure du log

REMOTEUSER=username
REMOTEHOST=remoteHost

SSH_REMOTEPORT=22
SSH_LOCALPORT=10022

TUNNEL_REMOTEPORT=12081
TUNNEL_SPECIFIC_REMOTE_PORT=22223
TUNNEL_LOCALPORT=8082

createTunnel() {
    /usr/bin/ssh -f -N  -L$SSH_LOCALPORT:$REMOTEHOST:$SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:$TUNNEL_REMOTEPORT $REMOTEUSER@193.abc.def.ghi -p $TUNNEL_SPECIFIC_REMOTE_PORT
    if [[ $? -eq 0 ]]; then
        echo [$NOW] Tunnel to $REMOTEHOST created successfully >> $LOGFILE
    else
        echo [$NOW] An error occurred creating a tunnel to $REMOTEHOST RC was $? >> $LOGFILE
    fi
    }

## Run the 'ls' command remotely.  If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER@193.abc.def.ghi ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
    echo [$NOW] Creating new tunnel connection >> $LOGFILE
    createTunnel
fi

然而,我得到了一些即时消息(如下),当隧道运行时,当cron试图再次启动批处理...听起来好像它听不进去。此外,因为我需要一些时间来得到一个证明,我不能说,但它将成功地重新启动,如果隧道是。
下面是对批处理第二次启动的响应。
bind:地址已在使用channel_setup_fwd_listener:无法侦听端口:10022结合:地址已在使用channel_setup_fwd_listener:无法侦听端口:8082无法请求本地转发。

相关问题