启动多个“ssh”会话,每个会话转发到不同的端口

启动多个“ssh”会话,每个会话转发到不同的端口

我有一个别名,可以启动ssh带有端口转发的自定义命令,如下所示:

ssh -Y -L 8888:localhost:8888 hostname

当然,这对于我为同一主机启动的第一个会话来说效果很好,但在随后的时间中,转发将失败,因为端口 8888 已在使用中。

我想要做的是想出一种方法,每次启动ssh到同一服务器的连接时,端口都会自动调整,以便每个不同的ssh连接都有自己单独的端口可以转发。

因此,例如,我第一次发出命令时,它相当于

ssh -Y -L 8888:localhost:8888 hostname

第二次它相当于

ssh -Y -L 8889:localhost:8889 hostname

等等。

我知道我可以使用 Python 或其他东西来做到这一点,但我想知道是否有比编写自己的(可能有点复杂)脚本更简单的解决方案。那可能吗?

PS:我知道我可以轻松地手动完成此操作,但我每天都会启动其中几个,这不仅需要我输入更多内容,而且还需要跟踪哪些端口已在使用以及哪些端口已在使用中不是。

答案1

这是一个简短的脚本,可以完成您所描述的事情。它的工作原理是尝试锁定以端口号命名的文件,如果失败,则增加端口号并重试。

端口锁定文件是在$HOME/.ssh/ports.它们在创建后不会被清理,但这没关系;我们不会检查是否存在;我们正在获取文件锁。

该脚本并不关心您每次连接到同一服务器还是不同的服务器;每个连接都会获得一个唯一的端口。

#!/bin/bash

PORTPATH="$HOME/.ssh/ports"

port=8888
while :; do

  # We use the -E option to specify a custom exit code so that we can
  # differentiate between "failed to lock file" and "ssh failed for some
  # reason".
  flock -n -E 121 "$PORTPATH/$port" \
    ssh -Y -L "${port}:localhost:${port}" "$@" && break
  exitcode=$?

  if (( exitcode == 121 )); then
    (( port++ ))
    continue
  fi

  exit $exitcode
done

如果我将此脚本保存在名为的文件中portfw.sh并运行它三次,如下所示:

sh portfw.sh remote.example.com

我将在输出中看到以下进程ps

flock -n -E 121 /home/lars/.ssh/ports/8888 ssh -Y -L 8888:localhost:8888 remote.example.com
flock -n -E 121 /home/lars/.ssh/ports/8889 ssh -Y -L 8889:localhost:8889 remote.example.com
flock -n -E 121 /home/lars/.ssh/ports/8890 ssh -Y -L 8890:localhost:8890 remote.example.com

相关内容