SSH経由でsudoする適切な方法


150

sudoを使用してリモートサーバーでSSH経由で別のスクリプトを実行するスクリプトがあります。ただし、パスワードを入力すると、端末に表示されます。(それ以外の場合は正常に動作します)

ssh user@server "sudo script"

入力時にパスワードが表示されずにSSH経由でsudoのパスワードを入力できるようにするには、これを行う適切な方法は何ですか?


2
私の場合、sshを使用してsudoを実行する方法を探す理由ssh <user@server> sudo <script>は、エラーが発生したため、のようなものを試行したときに機能しなかったためですsudo: no tty present and no askpass program specified
knocte

回答:


244

もう1つの方法は、-tスイッチをssh次のように使用することです。

ssh -t user@server "sudo script"

を参照してくださいman ssh

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g., when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

2
-tオプションを知っていましたが、sudoプロンプトで機能することを知りませんでした。

3
-tオプションとは何ですか?
Vince

@Vinceはgo2linux.garron.me/linux/2010/11/を参照してください
givemesnacks

3
ここでは機能していません: ssh -t localhost <<< "sudo touch file;"EDITどうやら、コマンドをパラメーターとして提供することが重要です。これは、標準入力(後から考えると意味があります)ではありません。
限定的な贖罪2015

この-tメソッドは、通常そうするコマンドのカラー出力も表示します。
カルマカゼ2016年

24

次のコマンドで完全に自動化できました。

echo pass | ssh -tt user@server "sudo script"

利点:

  • パスワードプロンプトなし
  • リモートマシンのbash履歴にパスワードを表示しない

セキュリティについて:としてクルトは言った、このコマンドを実行すると、ローカルのbashの歴史上のパスワードを示し、それは別のファイルにパスワードを保存するか.SHファイル内のすべてのコマンドを保存し、それを実行する方が良いでしょうします。注:許可されたユーザーのみがファイルにアクセスできるように、ファイルには正しい権限が必要です。


8
パスワードを含むローカルシステムのbash履歴に表示されます。パスワードをファイルに保存し、ファイルをcatする方が良いでしょう。
カートフィッツナー、

4
ああ、私は知っ-tていましたが、マニュアルを十分に読んでいなかったため、2回渡せることを確認できませんでした。これは私が何ヶ月も探していたものです!セキュリティの追加として、で実行する前に単にパスワード変数を設定してから、を設定read -s -p "Password: " pwしましたecho "$pw" | ....。これを自分用の便利なスクリプトにまとめました:)。
-kael

私にとって魅力のように働いた!
MiKr13

実行する必要のある特定のユーザーとコマンドのために、パスワードなしのsudoをセットアップしないのはなぜですか?これはSSHの問題ではありません...
nomen

@nomenソリューションも有効ですが、追加の手順が必要です。パスワードなしのsudoユーザーがいない多くのデバイスがある場合、このソリューションを使用して自動化スクリプトを作成できます。自分が所有していないシステムで作業していて、変更したくない、または変更できない場合があります。他の考慮事項がある場合もあります。
ofirule

6

パスワードプロンプトが必要ない場合

ssh $HOST 'echo $PASSWORD | sudo -S $COMMMAND'

ssh me@localhost 'echo secret | sudo -S echo hi' # outputs 'hi'

14
プレーンテキストのパスワードはコマンドラインに入力されるため、これは/ very /危険です。コマンドラインは公開されており、システム上の他のすべてのユーザーとプロセスから見ることができます。たとえば、非特権ユーザーによる「ps auxwwwww」は、実行中のすべてのプロセスと、それらを実行したコマンドラインを表示します。
カートフィッツナー、

3
パスワード(プレーンテキスト)をbash_historyファイルに入れることは言うまでもありません。
レインベルナルド

4

パスワードを渡すSSH上のsudo、ttyは不要:

sudoにsshを強制的に使用せずに(sshの "-t"スイッチを使用せずに)sudoでsudoを使用して、対話型パスワードを要求せず、標準入力からパスワードを取得するようにsudoに指示することができます。これを行うには、sudoで「-S」スイッチを使用します。これにより、sudoはstdinでパスワードをリッスンし、改行が検出されたときにリッスンを停止します。

例1-単純なリモートコマンド

この例では、簡単なwhoamiコマンドを送信します。

$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root

プロンプトを出さずに、標準入力から入力を受け取るようにsudoに指示しています。これにより、sudoパスワードの通過が完全にサイレントになるため、返される唯一の応答はからの出力ですwhoami

この手法には、標準入力を必要とするsshを介してsudoを介してプログラムを実行できるという利点があります。これは、sudoがstdinの最初の行でパスワードを使用しているため、実行するすべてのプログラムにstdinを引き続き取得させるためです。

例2-独自のstdinを必要とするリモートコマンド

次の例では、リモートコマンド「cat」がsudoを介して実行され、リモートのcatを表示するためにstdinを介して追加の行をいくつか提供しています。

$ ssh user@server cat \| sudo --prompt="" -S -- "cat" << EOF
> <remote_sudo_password>
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

出力は、 <remote_sudo_password>行がsudoによって消費されていること、およびリモートで実行されたcatが追加の行を表示していることを示しています。

コマンドラインを使用せずにsshを使用して特権コマンドにパスワードを渡したい場合は、これが有益な例です。たとえば、sshを介してリモートの暗号化されたコンテナをマウントする場合は、

例3-リモートVeraCryptコンテナーのマウント

このサンプルスクリプトでは、追加のプロンプトテキストなしで、sudoを介してVeraCryptコンテナーをリモートでマウントしています。

#!/bin/sh
ssh user@server cat \| sudo --prompt="" -S -- "veracrypt --non-interactive --stdin --keyfiles=/path/to/test.key /path/to/test.img /mnt/mountpoint" << EOF
SudoPassword
VeraCryptContainerPassword
EOF

上記のすべてのコマンドラインの例(スクリプトを除くすべて)では<< EOF、コマンドラインの構成によって、入力したすべてのものが(パスワードを含めて)ローカルマシンの.bash_historyに記録されることに注意してください。したがって、実際に使用する場合は、上記のveracryptの例のようにスクリプト全体を使用するか、コマンドラインでパスワードをファイルに入力し、sshを介してそのファイルをリダイレクトすることを強くお勧めします。

例1a-ローカルコマンドラインパスワードを使用しない例1

したがって、最初の例は次のようになります。

$ cat text_file_with_sudo_password | ssh user@server cat \| sudo --prompt="" -S -- whoami
root

例2a-ローカルコマンドラインパスワードを使用しない例2

2番目の例は次のようになります。

$ cat text_file_with_sudo_password - << EOF | ssh va1der.net cat \| sudo --prompt="" -S -- cat
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

スクリプトの内容を履歴に残さないため、スクリプトにすべてを入れる場合は、パスワードを別のファイルに入れる必要はありません。ただし、パスワードを表示してはいけないユーザーにスクリプトの実行を許可する場合は、この方法が役立つ場合があります。


sshリモートコマンドでcat、結果を実行してsudoにパイプする必要があるのはなぜですか?sudoメインのsshリモートコマンドとして使用できますか?
joanpau

@joanpauイニシャルcatは、反対側のsudoにユーザーのパスワードをパイプするために使用されます。ユーザーがパスワードなしでsudoを実行できる場合、それは必須ではありませんが、この構成はお勧めしません。パイプされるのは、リモートシステムのコマンドラインにパスワードが表示されないようにするためです。コマンドラインは安全ではなく、すべてのユーザーがですべてのコマンドラインを見ることができますps auxwww
カートフィッツナー、

catsshコマンドでを要求していますcat \| sudo --prompt="" -S...-S強制的sudoに標準入力からパスワードを読み取る場合、猫とパイプはまったく必要ですか?sshコマンドは単にsudo --prompt="" -S...でしょうか?
joanpau

@jonpauそのcatコマンドは、sdinパスワードを渡すためにstdinを取得し、sudoを介してパイプします。これは、sdinパスワードをstdin経由でsshを介して安全にパイプする方法を示しています。
カートフィッツナー、

1

最良の方法はssh -t user@server "sudo <scriptname>"、例えばssh -t user@server "sudo reboot"です。最初にユーザーのパスワードを入力し、次にrootの入力を求めます(root権限でスクリプトまたはコマンドを実行しているため)。

私はそれがあなたの疑いを助けてクリアしたことを願っています。




-1

私は問題に直面しました、

user1@server1$ ssh -q user1@server2 sudo -u user2 rm -f /some/file/location.txt

Output:
sudo: no tty present and no askpass program specified

それから私は試してみました

#1
vim /etc/sudoers
Defaults:user1    !requiretty

うまくいきませんでした

#2
user1   ALL=(user2)         NOPASSWD: ALL

それは正しく機能しました!


これは、求められていることを実際に達成するものではありません。まだパスワードが必要ですが、sshを介して入力できるようにするという考え方です。これで、パスワードなしでuser1にuser2への完全なsudoアクセスが付与されました。これは特定のアプリケーションでは問題ありませんが、一般的な解決策としては最適ではありません。
ポッサム

-7

あなたの使い方にもよりますが、私は次のことで成功しました:

ssh root@server "script"

これにより、rootパスワードの入力が求められ、コマンドが正しく実行されます。


26
いいね、SSHでroot?いろいろな理由でそれは悪い考えです。
darkfeline 2013

12
sshはtelnetではないことに注意してください。rootとしてsshを実行することは、別のユーザーとしてsshを実行してsudoを実行するよりも危険ではありません。パスワードは、ssh接続を介して同じ方法で暗号化されます。
ステファン

22
パスワードのセキュリティに関しては、ステファンは完全に正しいです。ただし、sudoの代わりにrootを使用すると、sudoに伴う監査証跡が失われます。また、ルートアクセスが利用できない場合があります。
djeikyb 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.