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


12

私は展開プロセスを自動化しており、マシン上の.shファイルを1つだけ呼び出して、ビルドを行い、サーバーに.zipをアップロードしてから、サーバー上で多くのことを実行できるようにしたいと考えています。私がしなければならないことの1つは、私がrootになることです。だから、私がやりたいのはこれです:

ssh user@172.1.1.101 <<END_SCRIPT
su - 
#password... somehow...
#stop jboss
service server_instance stop
#a bunch of stuff here
#all done!
exit
END_SCRIPT

これも可能ですか?


+1の良い質問。一般的な問題。
-gMale

回答:


15

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


1
これは私が過去に使用したアプローチです。sudoを必要なコマンド(サービスの開始/停止)に限定し、ユーザーが必要とする特権をユーザーが正確に制限できます。まだ不格好に感じますが、動作します。
マーク

これは実際に私がやったことです
...-cmcculloh

5

suの代わりに、適切なコマンドのsudoersでNOPASSWDを設定してsudoを使用します。許可されたコマンドセットをできるだけ制限する必要があります。sudoerファイルの構文に慣れていない場合は、ルートコマンド用のスクリプトを実行するのが最もクリーンな方法であり、安全にするのがはるかに簡単です。完全な環境をロードする必要があるコマンド/スクリプトのsudo su - -c command場合、機能しすぎますが機能します。



3

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

ssh user@host "command to run"

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

ssh user@host "command1; command2; command3"

または、代わりに:

ssh user@host "
        command1
        command2
        command3
"

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

ssh -t user@host 'su - -c "command"'
ssh -t user@host 'sudo command'

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

#!/bin/bash
ssh -t user@172.1.1.101 "
        sudo some_command
        sudo service server_instance stop
        sudo some_other_command
"

以来 sudo、通常再度rootのパスワードを尋ねる前に数分間許可レベルを覚えて、ちょうど先頭に追加sudorootとして実行する必要があるすべてのコマンドにすることは可能性の高いサーバー上でrootとしてコマンドを実行する最も簡単な方法です。NOPASSWDユーザーにルールを追加/etc/sudoersすると、プロセスがさらにスムーズになります。

これが役立つことを願っています:-)


そのNOPASSWDルールの追加に関する詳細が必要な場合は、の下部にある例を確認してくださいman sudoers。また、破損を避けるためにファイルをvisudo編集するときに使用することを忘れないでくださいsudoers
jabirali

su--c "コマンド"が動作しません。suのパスワードはどのように指定しますか?
cmcculloh

su -c代わりに使用することを選択した場合sudoは、-tフラグを指定してSSHを実行する必要があります。コマンドを実行すると、サーバーのルートパスワードの入力が求められます。suコマンドライン引数として直接パスワードを提供することはサポートされていません(私が知る限り)、推奨されません- コマンドラインから提供されたパスワードを含むにps -ef | grep su渡されるすべての引数を単純に明らかにするためsu
...-jabirali

su -cSSH を介して呼び出す方法については、次のとおりです。ssh -t user@host 'su -lc "<br /> echo this is a test <br /> echo this is another test<br /> "<br />'
jabirali

<br />上記をスクリプトの改行で置き換えます。トピック外: ServerFaultコメントに改行を追加できますか?これは、コードスニペットを投稿するときに非常に役立ちます...
jabirali

2

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


2
ほとんどのsuコマンドは、実行するコマンドを引数として取る-cオプションを受け入れます。サーバー自体のスクリプトは、おそらくssh経由ですべてのcmdを送信するのに比べて最高だと思います。
アーロンブッシュ

1

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

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

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


通常のssh / bashスクリプトを使用できない場合、これらのケースの多くでExpectは本当に便利です。ただし、それはすぐに非常に不格好になり、リモートエンドで「見つけたものは何でも」と仮定します。ターゲットシステムを変更したり、動作に影響を与えることができる場合は最初に別のルートを試すことをお勧めします。ただし、ここで取り上げるのは良いことです。
Theuni

0

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

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

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.