據我了解,該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 時),則將其視為密碼驗證失敗。