私の理解では、このrequiretty
オプションでは PTY 上で sudo は許可されません。
私のVM 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 のデフォルト設定で VM に接続し、実行するコマンドを指定すると、状況は異なります。
$ ssh VM-user@VM-hostname "hostname; tty"
VM-hostname
not a tty
そしてそれsudo
のオプションによって拒否される状況ですrequiretty
。
TTY の要件により、他の多くの Unix プログラムがパスワードを要求するときに行うように、SSH は標準入力を介してパスワード プロンプトへの応答をパイプする試みを拒否できます。
また、次のようなことも可能になります:
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
。)
つまり、set では次のようなコンテキストではrequiretty
使用できません。sudo
- TTY の割り当てを強制しない限り、SSH 経由のリモート コマンドは
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 が関連付けられていない場合)、パスワード認証の失敗と同じように扱われます。