我正在通过 ssh 将本地端口转发到远程服务器。由于我不想跟踪哪些端口可用,因此我为远程本地端口指定 0:
ssh -R0:127.0.0.1:9100 example.com
现在我想确定 sshd 从远程系统分配的端口。拥有 root 权限时可以这样做,如下所示:
$ ssh -R0:127.0.0.1:9100 [email protected]
# ss -4lntp|grep pid=$(ps -o ppid= -p $$),|awk '{print $4}'
127.0.0.1:39152
不幸的是,这对于非特权用户来说不起作用,因为端口转发是由以 root 身份运行的 sshd 完成的。
还有其他方法可以确定分配的端口吗?即使使用 bash 不可能,使用 ssh 协议是否可能?
答案1
不幸的是,我不认为这是非特权用户能够做到的。我自己也搜索过很多次了。
为了达到我的目的,我允许我的“隧道”用户 sudo 访问 lsof 命令。我正在通过我的客户端将一个网络上的服务隧道传输到服务器,以便服务器网络上的任何人都可以访问。我不允许此用户执行任何其他操作(因此“睡眠无限期”,并且我制定了其他规则来禁用 TTY 等)
/etc/sudoers
tunnel ALL=NOPASSWD:/usr/bin/lsof *
使用此脚本在客户端窗口中报告连接的端口
#!/bin/bash
#ip and port used by client to connect to server
ip=`echo $SSH_CLIENT | awk '{ print $1 }'`
sport=`echo $SSH_CLIENT | awk '{ print $2 }'`
search="$ip:$sport"
echo "Connected through $search"
#returns the PID of the SSH Session
spid=`sudo lsof -i 4 -n -P | grep "$search" | grep "tunnel" | awk '{ print $2 }'`
#uses the pid of SSH session to find the tunneled port
port=`sudo lsof -i 4 -n -P | grep "$spid" | grep "*:" | awk '{ print $9}' | sed 's/[^0-9]*//g'`
if [ -z "$port" ]
then
#port returned empty
echo "Unable to open tunnel. Please try again."
echo " session closing in $i seconds"
sleep 10
else
echo "You've been assigned port $port"
sleep infinity
fi
然后我强制该命令在 /etc/sshd_config 文件登录时运行
Match User tunnel
ForceCommand /home/tunnel/tunnel.sh
目前我只希望搜索一个端口。如果要检查多个端口,则需要进行修改。我删除了原始脚本中一些可能多余的错误检查。如果您希望用户能够访问 TTY,则可能需要进一步修改。