web-dev-qa-db-ja.com

シェルスクリプト内でsuを使用する

私はデプロイプロセスを自動化しています。マシンで1つの.shファイルを呼び出し、ビルドして.Zipをサーバーにアップロードしてから、サーバー上で一連の処理を実行できるようにしたいと考えています。私がしなければならないことの1つは、私がrootになることを必要とします。だから、私がしたいのはこれです:

ssh [email protected] <<END_SCRIPT
su - 
#password... somehow...
#stop jboss
service server_instance stop
#a bunch of stuff here
#all done!
exit
END_SCRIPT

これは可能ですか?

12
cmcculloh

代わりにパスワードなしのSudoを検討しましたか?

15
medina

Suの代わりに、適切なコマンドのためにsudoersでNOPASSWDを設定してSudoを使用します。許可されるコマンドセットを可能な限り制限する必要があります。 sudoerファイルの構文に慣れていない場合は、それを呼び出してrootコマンドのスクリプトを実行するのが最もクリーンな方法であり、安全を確保するのがはるかに簡単です。完全な環境をロードする必要があるコマンド/スクリプトの場合、Sudo su - -c commandはやり過ぎかもしれませんが動作します。

5
Jeremy M

あなたが説明していることは expect で可能かもしれません。

コマンドを引数としてSSHに渡し、そのコマンドをサーバーで実行して終了することができます。

ssh user@Host "command to run"

これは、複数のコマンドのリストでも機能します。

ssh user@Host "command1; command2; command3"

または代わりに:

ssh user@Host "
command1
command2
command3
"

他のユーザーが私の前に指摘したように、サーバーでsuを実行すると、スクリプトで後続のコマンドをrootとして実行する代わりに、新しいシェルが起動します。 Sudoまたはsu -cを使用し、-tスイッチを使用してSSHにTTY割り当てを強制する必要があります(ルートパスワードを入力する必要がある場合に必要)。

ssh -t user@Host 'su - -c "command"'
ssh -t user@Host 'Sudo command'

まとめると、やりたいことを達成する1つの方法は次のようになります。

#!/bin/bash
ssh -t [email protected] "
Sudo some_command
Sudo service server_instance stop
Sudo some_other_command
"

Sudoは通常、rootレベルのパスワードを再度要求する前に数分間認証レベルを記憶するため、rootとして実行する必要があるすべてのコマンドの前にSudoを付加するだけが、コマンドを実行する最も簡単な方法ですサーバー上のルート。 /etc/sudoersでユーザーのNOPASSWDルールを追加すると、プロセスがさらにスムーズになります。

これがお役に立てば幸いです:-)

3
jabirali

いいえ、できません。suのパスワードを取得しても、suが新しいシェルを開くという事実に対処する必要があります。つまり、その後のコマンドは渡されません。ルート操作用のスクリプトと、適切な権限でそれを呼び出すことができるヘルパー実行可能ファイルを作成する必要があります。

私はこれが少し遅いことを知っていますが、個人的にはCPANから入手可能なNet :: SSH :: Expectを使用します。

http://search.cpan.org/~bnegrao/Net-SSH-Expect-1.09/lib/Net/SSH/Expect.pod

1
misconfig

Expectスクリプトを記述します。あなたはすでにこれに対する答えを見つけたと思いますが、インタラクティブなパスワード入力を必要とする多数のサーバーにログインする必要がある場合、これは役立つかもしれません。

これはTCLに基づいた言語であるため、従来の単純なシェルスクリプトと比較すると少し奇妙かもしれません。しかし、それはテキスト入力の自動化を処理し、ご想像通り、何らかの自動化されたパスワード入力や特権の昇格を入力する前に、出力の特定のビットを「期待」します。

これがガイドとしての良いリンクです: http://bash.cyberciti.biz/security/expect-ssh-login-script/

サイトがダウンした場合に備えて:

#!/usr/bin/expect -f
# Expect script to supply root/admin password for remote ssh server
# and execute command.
# This script needs three argument to(s) connect to remote server:
# password = Password of remote UNIX server, for root user.
# ipaddr = IP Addreess of remote UNIX server, no hostname
# scriptname = Path to remote script which will execute on remote server
# For example:
#  ./sshlogin.exp password 192.168.1.11 who
# ------------------------------------------------------------------------
# Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft Shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# ----------------------------------------------------------------------
# set Variables
set password [lrange $argv 0 0]
set ipaddr [lrange $argv 1 1]
set scriptname [lrange $argv 2 2]
set arg1 [lrange $argv 3 3]
set timeout -1
# now connect to remote UNIX box (ipaddr) with given script to execute
spawn ssh root@$ipaddr $scriptname $arg1
match_max 100000
# Look for passwod Prompt
expect "*?assword:*"
# Send password aka $password
send -- "$password\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof
1

「ssh example.com su -lc "$ cmd"」を使用できます。

コマンドにオプションが含まれている場合は、引用符で囲む必要があります。そうしないと、「su」でオプションが使用される可能性があります(「su:無効なオプション-'A')。

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
0
blueyed