可以通过环境变量(例如SSH_CONNECTION)访问连接SSH客户端的IP地址,如中所述
在SSH会话中查找客户端的IP地址
但是,在GNU屏幕会话中,这些环境变量是由开始屏幕的人定义的。 是否有任何方法可以获取SSH连接信息,对于稍后输入已存在的屏幕会话的人,例如来自其他主机的人?
我无法想出一种确定这种方法的方法,但这对于例如在不同的人之间共享屏幕会话的情况非常有用。
链接问题有几个答案,有些涉及环境变量以外的事情。
这可能是,但仍然让我想知道是否有办法弄清楚谁在屏幕会话中调用某个脚本,尤其是。如果屏幕会话可能由不同的人共享。
您可以遍历当前进程的PPID并查看其环境变量和标准句柄(在Linux上通过/proc)。
@牛米。 - 我仍然没有看到这将如何帮助我分离不同的客户。让我们假设两个客户端(两个用户)通过SSH从不同的IP连接,例如以root身份连接到机器。如果两者在这里的给定屏幕会话(屏幕-x)中都处于活动状态,并且其中一个在此处调用脚本 - 是否有任何方法可以判断它们中的哪一个(即通过SSH客户端IP)实际上是这样做的?在这种情况下,PPID将是相同的。
嗯,不,那是不可能的。这就像让几个人在键盘上打字,然后试图确定是谁键入了什么。有人可以键入l另一个s而另一个按下回车,谁调用了ls?与screen完全相同。
好吧,这就是我所担心的。以为可能还有办法解决。感谢您的投入 - 随意将其纳入完整的答案,而不是评论,但赏金赢得:)
如果屏幕会话以root用户身份启动,则可以,但它不会完全可靠
如果两个用户键入同一个屏幕窗口,它们将在同一个shell中进行交互。人们可以写一个命令。另一个可以按键。
您必须能够访问环境变量SSH_CONNECTION(或更好的SSH_CLIENT),这只有在您是root用户的情况下才可以访问,或者您在屏幕会话中使用相同的用户。
假设您是屏幕会话中的root用户,则可以使用ps命令并查找上一个活动会话来了解屏幕会话中最后一个活动用户。
ps h -C screen katime -o pid,user
通过使用pid并访问/proc//environ文件,您可以获得SSH_CLIENT变量。
sed -z '/SSH_CLIENT/p;d' /proc/`ps h -C screen katime -o pid |head -1`/environ
--> SSH_CLIENT=257.31.120.12
所有这些都假设您的屏幕以root身份执行
您还可以选择记录所有活动连接。
对于这种需要,我建议你存储完整的连接列表和它们的最后一个活动。
ps eh -C screen kstime -o pid,atime | while read pid stime; do echo -n"$stime:";\
gawk -v 'RS=\0' -F= '$1=="SSH_CLIENT" {print $2}' /proc/$pid/environ; done
Result:
00:00:00: 257.31.120.12 61608 22
00:07:11: 258.1.2.3.4 49947 22
请注意,如果您觉得更容易,也可以解析ps eh -C screen kstime -o args命令的结果。
编辑:
这是一个有效的Debian命令,用于使当前连接到同一屏幕会话的所有用户:
find /var/run/screen/
-name $(pstree -sp $$ |sed 's/.*screen(\([0-9]*\)).*/\1/;q').*
-printf"%h
"
| cut -f2 -d-
感谢您付出的努力!正如你所说的那样,100%的案例并不适用,但这样我就可以很好地覆盖我感兴趣的案例。
如果您的屏幕通常以分离模式启动,则在.screenrc中添加以下内容:
shell -$SHELL
然后你的屏幕将拥有所有变量。
对于您遇到的当前正在运行的屏幕,只需运行即可。
source ~/.bash_profile
替换路径和文件名以匹配您的环境。
如果您正在尝试支持多显示模式('screen -x'),那么就像上面有人说的那样,您可能会失败。
另一方面,如果你可以假设单用户模式,那么你可以为屏幕命令创建一个包装器/别名,它将环境变量带入屏幕(参见'screen -X stuff ...');在这种情况下,您只是传递具有适当值的SSH_CLIENT。
如果您可以假设给定的用户名来自单个位置(或者,如果有多个位置,则只需选择最近的位置),那么您可以在'last'命令的输出上执行一些grep / sed。
client_ip=`last -ai | grep"still logged in" | grep"$USER" | grep -v '0.0.0.0' | tail -n 1 | sed 's/.* //g'`
echo"Hello $client_ip"
感谢您的输入,但在一个屏幕内,SSH_TTY(就像SSH_CONNECTION一样)给了我开始屏幕的人的价值。因此,如果我再次从另一个SSH会话进入现有屏幕,我似乎无法抓住我目前以这种方式连接的TTY。
你是对的。我不知道如何处理多显示器的情况,但我对单用户模式提出了一些想法,以防它以某种方式适用于你。
我一般对屏幕-x场景感兴趣,因为我们经常在给定的屏幕上同时有多个人。仍然很有兴趣在这里了解更多选项,谢谢:)
如果sshd是连接到服务器的唯一方法,则可以检查last命令的输出,该输出将列出所有连接的IP addresses或hostnames。
ec2-user]# last
ec2-user pts/0 115.250.185.183 Sun May 29 13:49 still logged in
ec2-user pts/0 115.250.140.241 Sat May 28 07:26 - 10:15 (02:48)
root pts/4 113.21.68.105 Tue May 3 10:15 - 10:15 (00:00)
或者(在Linux上),您可以检查/var/log/secure,其中sshd通常会记录所有连接的所有详细信息,即使它们不会导致登录成功。
到目前为止,这对我的问题没什么帮助。我在机器上有一些脚本,可以通过SSH访问(来自不同的客户端IP)由不同的人调用。调用时,这些脚本会记录谁(如:客户端IP)调用它们以及何时调用它们。要在此确定客户端IP,我使用SSH_CONNECTION的信息 - 除非使用屏幕会话(尤其是共享的),否则工作正常。我想知道是否有一种可靠的方法可以在屏幕会话中知道谁调用了脚本(可能有多个人在给定时间登录到它)。
@weiresr有趣的问题,但imo,这是设计不可能的。当您附加屏幕会话时,您冒充为启动会话的用户(或更好地说,会话中的程序) - 带来所有后果。
@ hek2mgl我最近看到的一件事是你至少可以在屏幕上获得附加显示的列表(C-a:显示)。这样的事情可能会有所帮助 - 但我不知道是否有可能对该信息进行脚本访问,即使这样,它也无法告诉我(按设计)哪一个触发了某个命令,如果当前连接了多个显示器。
@weiresr我编辑了自己的答案,添加了一个如何使用/var/run/screen目录实现的示例