问题(TL; DR)
动态分配端口以进行远程转发(aka -R
选项)时,远程计算机上的脚本(例如来自的源.bashrc
)如何确定OpenSSH选择了哪些端口?
背景
我使用OpenSSH(在两端)连接到我们与多个其他用户共享的中央服务器。对于远程会话(暂时而言),我想转发X,cups和pulseaudio。
最简单的是使用-X
选项转发X。分配的X地址存储在环境变量中DISPLAY
,从此我可以在大多数情况下确定相应的TCP端口。但是我几乎不需要,因为Xlib非常荣幸DISPLAY
。
我需要类似的机制来制作杯子和Pulseaudio。两种服务的基础都以环境变量CUPS_SERVER
和的形式存在PULSE_SERVER
。以下是用法示例:
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
问题是设置CUPS_SERVER
和PULSE_SERVER
正确。
我们经常使用端口转发,因此我需要动态端口分配。静态端口分配不是一种选择。
通过指定0
为远程转发的绑定端口(该-R
选项),OpenSSH具有在远程服务器上动态分配端口的机制。通过使用以下命令,OpenSSH将为杯子和脉冲转发动态分配端口。
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
当我使用该命令时,ssh
将以下内容打印到STDERR
:
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
有我想要的信息!最终我想生成:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
但是,“已分配的端口...”消息是在我的本地计算机上创建的,并发送到STDERR
,我无法在远程计算机上访问。奇怪的是,OpenSSH似乎没有办法检索有关端口转发的信息。
如何获取该信息,把它变成一个shell脚本适当地设置CUPS_SERVER
和PULSE_SERVER
远程主机上?
死胡同
我能找到的唯一简单的事情就是增加了详细程度,sshd
直到可以从日志中读取该信息为止。这是不可行的,因为该信息所公开的信息远远超出了非root用户可以访问的范围。
我当时正在考虑修补OpenSSH以支持附加的转义序列,该转义序列可以打印出内部struct的一个很好的表示形式permitted_opens
,但是即使这是我想要的,我仍然无法编写脚本来从服务器端访问客户端转义序列。
肯定有更好的办法
以下方法似乎非常不稳定,并且仅限于每个用户一个这样的SSH会话。但是,我至少需要两个并发的会话和其他用户。但是我尝试了...
当牺牲一两只鸡正确对准星星时,我可以滥用这样一个事实:sshd
它不是以我的用户身份启动的,而是在成功登录后放弃特权的,以便执行以下操作:
获取属于我的用户的所有侦听套接字的端口号列表
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'
获取属于用户启动的进程的所有侦听套接字的端口号列表
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'
所有端口是在第一盘,但不是在第二盘有很高的情形产生是我转发端口,确实减去套的产量
41273
,55710
和6010
; 杯,脉冲和X。6010
使用标识为X端口DISPLAY
。41273
是cups端口,因为lpstat -h localhost:41273 -a
return0
。55710
是脉冲端口,因为pactl -s localhost:55710 stat
return0
。(它甚至会打印我的客户端的主机名!)
(要执行设置的减法运算I,sort -u
并存储上述命令行的输出,并用于comm
进行减法运算。)
Pulseaudio让我可以识别客户端,并且出于所有目的和目的,它可以用作分离需要分离的SSH会话的锚点。但是,我还没有找到一种方法来配合41273
,55710
并6010
以同样的sshd
过程。netstat
不会将该信息透露给非root用户。我只-
在PID/Program name
要阅读的列中得到一个2339/54
(在此特定情况下)。很近 ...
netstat
不会显示您不拥有或内核空间的进程的PID。例如