sudo
パスワードなしで実行するように設定しましたが、実行しようとするssh 'sudo Foo'
と、エラーメッセージが表示されますsudo: sorry, you must have a tty to run sudo
。
なぜこれが起こり、どうすれば回避できますか?
sudo
パスワードなしで実行するように設定しましたが、実行しようとするssh 'sudo Foo'
と、エラーメッセージが表示されますsudo: sorry, you must have a tty to run sudo
。
なぜこれが起こり、どうすれば回避できますか?
回答:
これはおそらく、/etc/sudoers
ファイル(またはファイルに含まれるすべてのファイル)に以下が含まれているためです。
Defaults requiretty
...これによりsudo
TTY が必要になります。Red Hatシステム(RHEL、Fedora ...)は、デフォルトsudoers
ファイルでTTYを必要とすることが知られています。これは実際のセキュリティ上の利点を提供せず、安全に削除できます。
Red Hatはこの問題を認識しており、将来のリリースで削除される予定です。
サーバーの構成を変更することがオプションではない場合、その誤った構成の回避策として、リモート側で擬似端末を生成する-t
または-tt
オプションを使用できますssh
が、多くの側面があることに注意してくださいエフェクト。
-tt
インタラクティブな使用を目的としています。raw
リモート端末と対話できるように、ローカル端末をモードにします。つまり、ssh
I / Oが端末との間ではない場合、副作用が発生します。例えば、全ての入力がエコーバックされる、特殊端末文字(^?
、^C
、^U
)特別な処理が発生します。出力では、LF
sはCRLF
s ...に変換されます(詳細については、「このバイナリファイルが変更される理由」の回答を参照してください。
影響を最小限に抑えるには、次のように呼び出します。
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
これ< <(cat)
により、raw
モードでのローカル端末(存在する場合)の設定が回避されます。そしてstty raw -echo
、リモートターミナルのラインディシプリンをパススルーとして設定するために使用しています(事実上-tt
、コマンドの実行後にのみ適用されますが、疑似ターミナルなしの代わりに使用されるパイプのように動作します。それが起こるまで入力のために何かを送ることを遅らせるために)。
リモートコマンドの出力は端末に送信されるため、オンになっているため、バッファリング(多くのアプリケーションでは行ベースになる)と帯域幅効率に影響を与えることに注意してくださいTCP_NODELAY
。またと-tt
、ssh
へのIPQoSを設定しますlowdelay
と対照的にthroughput
。あなたは両方で回避することができます:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
また、リモートコマンドがそのstdinでファイルの終わりを検出できず、リモートコマンドのstdoutとstderrが単一のストリームにマージされることにも注意してください。
だから、結局のところあまり良い回避策ではありません。
あなたは、リモートホスト上の擬似端末を起動する方法持っていれば(と同じようにexpect
、zsh
、socat
、perl
のIO::Pty
...)、疑似端末付けて作成するためにそれを使用する方が良いでしょうsudo
(にしたがI / O用ではない)、およびssh
なしで使用し-t
ます。
たとえば、とexpect
:
ssh host 'expect -c "spawn -noecho sh -c {
exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'
またはscript
(ここではからの実装を想定していますutil-linux
):
ssh host 'SHELL=/bin/sh script -qec "
sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
" /dev/null 3<&0 4>&1 5>&2'
(リモートユーザーのログインシェルがBourneのようなものであると(両方に対して)仮定します)。
デフォルトでは、SUDOはTTYを要求するように設定されています。つまり、SUDOはログインシェルから実行されることが期待されています。-t
SSH呼び出しにスイッチを追加すると、この要件を無効にできます。
ssh -t someserver sudo somecommand
-t
仮想端末の力配分。
これをグローバルに実行する場合は、変更/etc/sudoers
して指定します!requiretty
。これは、ユーザーごと、グループごと、またはすべてを含むレベルで実行できます。
DockerとCentos 7を使用してこの問題に遭遇しました。結局、次のことを行いました。
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
このハッキングはhttps://hub.docker.com/r/liubin/fluentd-agent/~/dockerfileで見つけました
同じ問題がありました。私の場合、解決策は2行でした
myscript=$(cat ssh_test.sh)
ssh -t user@host "$myscript"
説明:
実行するコマンド(sudoコマンドを含む)をスクリプト(「ssh_test.sh」など)に配置します。
スクリプト全体を「myscript」という変数に読み込みます。
1つの-tでsshを呼び出し、コマンドの代わりに変数を指定します。
これに先立ち、stdinからの読み取りとheredocsの使用の組み合わせを使用して問題に遭遇しました
requiretty
デフォルトのsudoerに含まれていたのは、sudoのredhatディストリビューションのみです。これは、新しいリリースで修正される予定