「requiretty」が動作しないのはなぜですか?

「requiretty」が動作しないのはなぜですか?

私の理解では、この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 が関連付けられていない場合)、パスワード認証の失敗と同じように扱われます。

関連情報