如何判断是在 Linux 控制台中运行还是在 ssh 会话中运行?
我有一个应用程序,如果直接从 Linux 控制台运行,则需要有不同的行为。因此,如果用户使用 SSH 连接来运行 FooBar,或者用户走到控制台并直接登录来运行 FooBar,我希望它做一些不同的事情。
我需要调用什么 C API 来区分这两种情况?我想我必须查看“tty/pts”信息(例如我运行“ps axf”时看到的信息),但我不确定这是否是最好的解决方案,也不确定要调用什么 API获取该信息。
提示表示赞赏。 :)
I have an application that needs to behave differently if run directly from the linux console. So if a user connects with SSH to run FooBar, or the user walks over to the console and logs in directly to run FooBar, I want it to do something different.
What C API do I need to call to tell the difference between these two scenarios? I was thinking I'd have to look at the "tty/pts" information (such as what I see when I run "ps axf"), but I'm not certain if that is the best solution, nor what API to call to get that information.
Hints appreciated. :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据您对被欺骗的担心程度,一个简单的检查是检查是否存在 SSH_CLIENT 和 SSH_CONNECTION 环境变量,在这种情况下您需要使用
getenv
函数。Depending on how much you're worried about it being spoofed, an easy check would be for the presence/absence of the SSH_CLIENT and SSH_CONNECTION environment variables, in which case you'd want the
getenv
function.根据您的标准输入检查 ttyname(3) 的返回值应该会给出为进程提供输入的终端的名称。
如果程序在控制台上运行(并且没有对其输入进行重定向),则它将是 /dev/console。您还可以检查 stdout 以查看它是否连接到 /dev/console - 看看哪个更适合您的使用场景。
Checking the return value of ttyname(3) against your stdin should give you the name of the terminal which is feeding the input of your process.
It will be /dev/console if the program is being run on the console (and doesn't have it's input redirected). You can also check stdout to see if it is connected to /dev/console - see which fits your usage scenario better.
ttyname 将告诉您连接到给定文件描述符的终端的名称;例如,
ttyname(0)
会告诉您标准输入的终端。如果输入或输出被重定向,这当然会失败。
除此之外,您可以检查各种环境变量(
SSH_CONNECTION
、SSH_CLIENT
、REMOTEHOST
、DISPLAY
、SESSIONNAME )。 Wireshark 具有检测其是否远程运行的逻辑,以便它不会捕获其生成的网络流量;您可能对其 get_conn_cfilter 函数使用的逻辑感兴趣实施这一点。
ttyname will tell you the name of the terminal connected to a given file descriptor; for example,
ttyname(0)
will tell you stdin's terminal.This will of course fail if input or output is redirected.
Barring that, you can check various environment variables (
SSH_CONNECTION
,SSH_CLIENT
,REMOTEHOST
,DISPLAY
,SESSIONNAME
). Wireshark has logic to detect if it's being run remotely so that it doesn't capture network traffic that it generates; you might be interested in the logic that its get_conn_cfilter function uses to implement this.我将环境变量视为正在发生的事情的合理标志。我不确定您需要什么 C API,但我确信存在一个。
例如,无论使用什么 SSH 客户端,我的计算机上都会设置
SSH_CLIENT
或SSH_CONNECTION
环境变量。可能值得检查一下这些基于计算机上运行的 SSH 服务器的通用性。
I'd look at environment variables as a reasonable sign of what's going on. I'm not sure what C API you'd want for that, but I'm sure one exists.
For example, both the
SSH_CLIENT
orSSH_CONNECTION
environment variables are set on my machine regardless of the SSH client being used.It may be worth checking how universal these are based on the SSH server running on the machine.
丑陋,但有效:
ugly, but works: