据我了解,该requiretty
选项不允许在 PTY 上使用 sudo。
我的虚拟机sudoers
:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Defaults passwd_tries=3
Defaults badpass_message="WRONG PASSWORD T_T"
Defaults log_input, log_output, iolog_dir="/var/log/sudo"
Defaults requiretty
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d`
通过 SSH 连接到该系统后,tty
程序输出/dev/pts/0
.
但我仍然可以在 SSH 会话中使用密码执行 sudo。该requiretty
选项与 SSH 或 PTY 无关吗?如何在 SSH 会话中使用 sudo?
答案1
您的理解不正确:伪 TTY 被认为完全等同于“真实”TTY。
tty
打印时/dev/pts/0
表示会话具有有效的 TTY。
但如果你使用 SSH 默认设置连接到虚拟机并指定要运行的命令,情况就会有所不同:
$ ssh VM-user@VM-hostname "hostname; tty"
VM-hostname
not a tty
和那sudo
是被选项拒绝的情况requiretty
。
对 TTY 的要求允许 SSH 拒绝通过标准输入通过管道输入对密码提示的响应的尝试,就像许多其他 Unix 程序在请求密码时所做的那样。
它还允许您执行以下操作:
sudo -u some-user data_producing_command 2> error-log-file | data_consuming_command
没有密码提示既不会混合到通过管道传输到 的数据中data_consuming_command
,也不会混合到error-log-file
. (注意data_consuming_command
这里是以你自己的身份运行的,而不是以some-user
!)
换句话说,对于requiretty
set,您不能sudo
在以下上下文中使用:
- 通过 SSH 进行远程命令,除非强制 TTY 分配,即
ssh VM-user@VM-host sudo something
会失败,但ssh -tt VM-user@VM-host sudo something
会成功。 - crontab 命令,或通过 crontab 执行的脚本
at
或batch
命令 - 脚本通过执行
nohup
- 通过
cgi-bin
或任何其他与用户会话无关的守护进程执行的脚本
当requiretty
设置并sudo
请求密码时,它的执行方式在概念上与此脚本片段大致相似:
printf "[sudo] password for $USER: " > /dev/tty # display prompt
TTYSETTINGS=$(stty -F /dev/tty --save) # save current TTY settings
stty -F /dev/tty -echo -echoe # prevent displaying the password
read PASSWORD < /dev/tty
stty -F /dev/tty $TTYSETTINGS # restore TTY settings
# now check if $PASSWORD is correct...
/dev/tty
是一个“神奇”设备,如果会话有 TTY,它将始终充当会话实际 TTY 设备的别名。它的存在正是为了这样的事情:允许任何脚本或程序“逃避”管道或其他输入/输出重定向,并在必要时直接与用户交互。
如果requiretty
设置并且/dev/tty
不可用(即当进程没有与其关联的真实 TTY 时),则将其视为密码身份验证失败。