![如何确定客户端 SSH 连接是否具有与之关联的 tty?](https://linux22.com/image/1370659/%E5%A6%82%E4%BD%95%E7%A1%AE%E5%AE%9A%E5%AE%A2%E6%88%B7%E7%AB%AF%20SSH%20%E8%BF%9E%E6%8E%A5%E6%98%AF%E5%90%A6%E5%85%B7%E6%9C%89%E4%B8%8E%E4%B9%8B%E5%85%B3%E8%81%94%E7%9A%84%20tty%EF%BC%9F.png)
我正在编写一个 PAM 模块来处理身份验证(服务器端 - sshd),并且我必须知道 ssh 客户端是否是 tty(交互式)或不是(非交互式)。
有人有线索吗?
答案1
您可以尝试检查$SSH_TTY
,但这并不可靠。
$ ssh -6 fedoraplug.local
Last login: ......
-$ echo "${!SSH*}"
SSH_CLIENT SSH_CONNECTION SSH_TTY
-$ exit
$ ssh -6 fedoraplug.local 'echo "${!SSH*}"'
SSH_CLIENT SSH_CONNECTION
$ ssh -t -6 fedoraplug.local 'echo "${!SSH*}"'
SSH_CLIENT SSH_CONNECTION SSH_TTY
Connection to fedoraplug.local closed.
答案2
在客户端,您可以使用tty
命令(手册页在这里)。假设会话是交互式的,此命令将返回类似以下内容:
breakthrough@lt0:~$ tty
/dev/pts/0
然而,如果客户不是interactive/tty-based,该命令将返回:
not a tty
实际上写作PAM 模块虽然tty
提供了一些可以使用的退出代码,但您不太可能tty
直接将该命令用作系统调用;相反,您应该看看ttyname()
(或ttyname_r()
)函数。
您可以看到以下示例实现这个函数在这里涵盖了一些一般用例。虽然查看是否返回了有效的 ttyname 就足够了,但最佳做法是检查是否引发错误ENOTTY
,表明传递的文件描述符不引用终端设备。
答案3
如果你使用 C 语言编写:
man isatty
描述 isatty() 函数测试 fd 是否是指向终端的打开文件描述符。
返回值如果 fd 是指向终端的打开文件描述符,则 isatty() 返回 1;否则返回 0,并设置 errno 以指示错误。