usando su all'interno di uno script di shell


12

Sto automatizzando un processo di distribuzione e voglio essere in grado di chiamare un solo file .sh sul mio computer, farlo compilare e caricare il file .zip sul server, quindi fare un sacco di cose sul server. Una delle cose che devo fare richiede che io sia root. Quindi, quello che voglio fare è questo:

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

È possibile?


+1 buona domanda. problema comune.
gMale

Risposte:


15

Hai invece considerato un sudo senza password?


1
Questo è l'approccio che ho usato in passato. È possibile limitare sudo ai comandi richiesti (avvio / arresto del servizio), limitando i privilegi che l'utente ha esattamente ciò di cui hai bisogno. Sembra ancora goffo, ma funziona.
Mark,

Questo è quello che ho finito per fare ...
cmcculloh,

5

Invece di su, usa sudo con il set NOPASSWD in sudoers per i comandi appropriati. Ti consigliamo di rendere il set di comandi consentito il più limitato possibile. Avere chiamato eseguire uno script per i comandi di root può essere il modo più pulito e di gran lunga più semplice da rendere sicuro se non si ha familiarità con la sintassi del file sudoer. Per i comandi / script che richiedono il caricamento dell'ambiente completo, sudo su - -c commandfunziona anche se può essere eccessivo.



3

È possibile passare un comando come argomento a SSH per eseguire quel comando sul server e quindi uscire:

ssh user@host "command to run"

Questo funziona anche per un elenco di più comandi:

ssh user@host "command1; command2; command3"

O in alternativa:

ssh user@host "
        command1
        command2
        command3
"

Come altri utenti hanno sottolineato prima di me, l'esecuzione susul server avvierà una nuova shell invece di eseguire i comandi successivi nello script come root. Quello che devi fare è usare uno sudoo su -c, e forzare l'allocazione TTY a SSH con lo -tswitch (richiesto se devi inserire la password di root):

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

Per riassumere, un modo per realizzare ciò che vuoi fare sarebbe:

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

Dal momento che in sudogenere ricorda il livello di autorizzazione per alcuni minuti prima di richiedere nuovamente la password di root, è sufficiente anteporre sudoa tutti i comandi che è necessario eseguire come root è probabilmente il modo più semplice per eseguire i comandi come root sul server. L'aggiunta di una NOPASSWDregola per l'utente /etc/sudoersrenderebbe il processo ancora più fluido.

Spero che questo possa essere d'aiuto :-)


Se hai bisogno di maggiori informazioni sull'aggiunta di quella NOPASSWDregola, controlla gli esempi in fondo a man sudoers. Inoltre, ricordati di utilizzare visudodurante la modifica del sudoersfile per evitare rotture!
jabirali,

Non riesco a far funzionare il "comando" su - -c. Come fornirei la password per su?
cmcculloh,

Se si sceglie di utilizzare su -cinvece di sudo, è necessario eseguire SSH con il -tflag: verrà richiesta la password di root sul server quando viene eseguito il comando. Fornire una password direttamente sucome argomento della riga di comando non è supportato (per quanto ne so), né raccomandato - dal momento che un semplice ps -ef | grep surivela tutti gli argomenti passati su, inclusa qualsiasi password fornita dalla riga di comando ...
jabirali

Quanto a come invochi su -csu SSH: ssh -t user@host 'su -lc "<br /> echo this is a test <br /> echo this is another test<br /> "<br />'
jabirali,

Sostituisci quanto <br />sopra con le nuove righe nel tuo script. Fuori tema: puoi aggiungere nuove righe ai commenti di ServerFault? Sarebbe molto utile quando
pubblichiamo

2

No. Anche se ottieni la password su, dovrai comunque fare i conti con il fatto che suaprirà una nuova shell, il che significa che i tuoi ulteriori comandi non verranno passati ad essa. Dovrai scrivere uno script per le operazioni di root insieme a un eseguibile helper che possa invocarlo con i privilegi appropriati.


2
La maggior parte dei comandi su accetta l'opzione -c che prenderà come argomento i comandi da eseguire. Concordo sul fatto che uno script sul server stesso sia probabilmente il migliore rispetto all'invio di tutti i cmds su ssh.
Aaron Bush,

1

Scrivi uno script di attesa. So che hai già trovato una risposta per questo, ma questo potrebbe essere utile se devi accedere a un gruppo di server che richiedono l'immissione interattiva della password.

È un linguaggio basato su TCL, quindi potrebbe essere un po 'strano rispetto ai semplici vecchi script di shell. Ma gestisce l'automazione dell'input di testo e, avete indovinato, "si aspetta" determinati bit di output prima di entrare in qualsiasi tipo di immissione automatica della password o escalation di privilegi.

Ecco un buon link come guida: http://bash.cyberciti.biz/security/expect-ssh-login-script/

Nel caso in cui il sito non funzioni:

#!/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

So che è un po 'tardi, ma utilizzerei personalmente Net :: SSH :: Expect, disponibile da CPAN.

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


Aspettarsi è davvero bello in molti di questi casi se non si può usare il normale script ssh / bash. Tuttavia, diventa anche molto goffo rapidamente e ti fa assumere "qualunque cosa trovi" sul telecomando. Se puoi cambiare il sistema di destinazione o influenzare il modo in cui si comporta , ti consiglio di provare prima un percorso diverso. Buon punto per portarlo qui, però.
Theuni l'

0

Puoi usare 'ssh example.com su -lc "$ cmd"'.

Quando il comando contiene opzioni, è necessario citarlo, altrimenti "su" potrebbe mangiarle ("su: opzione non valida - 'A').

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.