쉘 스크립트 내부에서 su 사용


12

배포 프로세스를 자동화하고 있으며 내 컴퓨터에서 하나의 .sh 파일을 호출하고 빌드하고 서버에 .zip을 업로드 한 다음 서버에서 많은 작업을 수행 할 수 있기를 원합니다. 내가해야 할 일 중 하나는 뿌리가되어야합니다. 그래서 내가하고 싶은 것은 이것입니다 :

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를 필요한 명령으로 제한하고 (서비스 시작 / 중지) 사용자가 필요한 것을 정확하게 제한 할 수 있습니다. 여전히 울퉁불퉁하지만 느낌이 듭니다.
Mark

이것은 실제로 내가 한 일입니다 ...
cmcculloh

5

su 대신 sudo를 적절한 명령에 대해 설정된 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서버에서 실행하면 스크립트에서 루트로 후속 명령을 실행하는 대신 새 셸이 시작됩니다. 당신이해야 할 일은, 하나를 사용하는 sudosu -c, 그리고와 SSH에 힘 TTY 할당 -t(루트 암호를 입력해야하는 경우 필수) 스위치 :

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

당신이하고 싶은 일을 성취하는 한 가지 방법으로 모든 것을 요약하면 다음과 같습니다.

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

sudo일반적으로 루트 비밀번호를 다시 요청하기 전에 몇 분 동안 권한 부여 레벨을 기억 하므로 루트 sudo로 실행해야하는 모든 명령 앞에 추가 하는 것이 서버에서 루트로 명령을 실행하는 가장 쉬운 방법 일 수 있습니다. NOPASSWD사용자 규칙을 추가 /etc/sudoers하면 프로세스가 더 순조로워집니다.

이게 도움이 되길 바란다 :-)


해당 NOPASSWD규칙 추가에 대한 자세한 정보가 필요한 경우 의 하단에서 예를 확인하십시오 man sudoers. 또한 파일이 손상되지 않도록 파일을 visudo편집 할 때 사용 하십시오 sudoers.
jabirali

su--c "command"가 작동하지 않습니다. 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를 보내는 것이 가장 좋습니다.
Aaron Bush

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 스크립팅을 사용할 수없는 경우 많은 경우에 매우 유용합니다. 그러나, 그것은 또한 정말 어수선 해져서 ​​당신이 "무엇을 찾든지"원격 끝에서 가정하게합니다. 그것이 작동하는 방식을 사용하여 대상 시스템이나 영향을 변경할 수 있습니다 경우 모두에 내가 먼저 다른 경로를 시도하는 것이 좋습니다. 그래도 여기에 올릴 좋은 지적입니다.
Theuni

0

'ssh example.com su -lc "$ cmd"'를 사용할 수 있습니다.

command에 옵션이 포함되어 있으면 인용해야합니다. 그렇지 않으면 "su"가 먹을 수 있습니다 ( "su : invalid option- 'A').

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.