为什么“requiretty”不起作用?

mis*_*shy 5 ssh debian sudo

我的理解是该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`
Run Code Online (Sandbox Code Playgroud)

使用 SSH 连接到该系统后,tty程序输出/dev/pts/0.

但是我仍然可以在 SSH 会话中使用密码 sudo。此requiretty选项与 SSH 或 PTY 无关吗?如何在我的 SSH 会话中使用 sudo?

tel*_*coM 10

您的理解不正确:伪 TTY 被认为完全等同于“真实”TTY。

tty打印/dev/pts/0这意味着会话具有有效的TTY。

但是如果使用SSH默认设置连接VM并指定要运行的命令,情况就会有所不同:

$ ssh VM-user@VM-hostname "hostname; tty"
VM-hostname
not a tty
Run Code Online (Sandbox Code Playgroud)

是拒绝的情况sudorequiretty选项。

对 TTY 的要求允许 SSH 拒绝尝试通过标准输入对密码提示进行响应,就像许多其他 Unix 程序在请求密码时所做的那样。

它还允许您执行以下操作:

sudo -u some-user data_producing_command 2> error-log-file | data_consuming_command
Run Code Online (Sandbox Code Playgroud)

没有密码提示既不会混入传输到的数据中data_consuming_command,也不会混入error-log-file. (请注意,data_consuming_command这里是以你自己的身份运行的,而不是作为some-user!)

换句话说,使用requirettyset,您不能sudo在以下上下文中使用:

  • 除非您强制 TTY 分配,否则通过 SSH 远程命令,即ssh VM-user@VM-host sudo something会失败,但ssh -tt VM-user@VM-host sudo something会成功。
  • crontab 命令,或通过 crontabatbatch命令执行的脚本
  • 通过执行脚本 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...
Run Code Online (Sandbox Code Playgroud)

/dev/tty是一个“魔法”设备,如果会话有一个 TTY,它将始终充当会话实际 TTY 设备的别名。它正是为了这样的事情而存在:允许任何脚本或程序“逃避”管道或其他输入/输出重定向,并在必要时直接与用户交互。

如果requiretty设置并且/dev/tty不可用(即当进程没有与之关联的实际 TTY 时),则将其视为密码验证失败。