2011-11-23 15 views
17

Abbiamo un numero di server Linux Red Hat nel nostro ambiente IT. I membri del mio team mi chiedono di scrivere uno script (preferibilmente script di shell) per cambiare la password di un utente su ognuno di quelli in un unico passaggio, usando SSH.Script per cambiare la password sui server linux su ssh

Ho cercato di trovare una soluzione ma molti degli script che ho trovato utilizzano Expect. Non abbiamo Expect installato sui nostri server e gli amministratori di sistema si sono rifiutati di consentirci di installarlo. Inoltre, gli utenti non dispongono dell'accesso root, pertanto non è possibile utilizzare passwd --stdin o chpasswd.

È possibile scrivere uno script in modo che un utente possa eseguirlo e modificare la password del proprio utente su tutti i server in un elenco?

+1

Modifica amministratori di sistema? – TLP

+0

purtroppo non un'opzione .. :) – squashbuff

risposta

16

Non è necessario installare le macchine remote. È possibile eseguire l'installazione su una workstation locale o VM (virtualbox) o qualsiasi altra casella * nix e scrivere un wrapper che chiama questo script .ex (expect) (potrebbero esserci piccoli cambiamenti da distro a distro, testati su CentOS 5/6):

#!/usr/bin/expect -f 
# wrapper to make passwd(1) be non-interactive 
# username is passed as 1st arg, passwd as 2nd 

set username [lindex $argv 0] 
set password [lindex $argv 1] 
set serverid [lindex $argv 2] 
set newpassword [lindex $argv 3] 

spawn ssh $serverid passwd 
expect "assword:" 
send "$password\r" 
expect "UNIX password:" 
send "$password\r" 
expect "password:" 
send "$newpassword\r" 
expect "password:" 
send "$newpassword\r" 
expect eof 
+0

Usando questo codice, si vorrebbe rendere questo codice qualcosa come ./passwdWrapper e poi nel file bash aggiungere ./passwdWrap $ user $ password $ server $ newpassword – Loren

11

Non è necessario l'accesso come root per utilizzare passwd.

Questo shoud funziona bene.

passwd <<EOF 
old password 
new password 
new password 
EOF 
+0

Grazie Dennis, come per il tuo post, passwd funziona bene una volta che l'utente è connesso al server desiderato. Tuttavia, ho un elenco di server memorizzati in un file servers.txt e vorrei eseguire uno script, fornire una vecchia password e una nuova password una volta, e quindi lo script dovrebbe cambiare la mia password su tutti i server in tale elenco. Qualche idea con quello? – squashbuff

+1

'ssh user @ server 'per cambiare la password'' fa proprio questo. – Dennis

+0

Grazie, Dennis, ho apportato una modifica alla mia domanda mostrando ciò che ho provato. Non è ancora arrivato, ma è un buon inizio. Grazie .. :) – squashbuff

1

Un'alternativa può essere utile per presentare ai vostri coetanei sarebbe averli utilizzano l'autenticazione senza password. Generano una coppia di chiavi pubblica/privata e registrano la loro chiave pubblica nel file ~/.ssh/authorized_keys su ciascuno dei server a cui accedono.

+0

Grazie, uso già le chiavi pubbliche/private per l'autenticazione ma anche con l'autenticazione senza password, quando la password scade dopo 2 mesi (nel mio caso), devo ancora accedere a ciascun server, usare 'passwd', digita la vecchia password e digita la nuova password due volte. Questo è un po 'inefficiente. Ecco perché sto cercando di mettere insieme questa soluzione. – squashbuff

+0

Eccellente. Ciò semplifica le cose. – phatfingers

+0

Probabilmente hai sudo su questi server, giusto? Se dai loro diritti sudo su uno script per cambiare la loro password, lo script potrebbe eseguire passwd per il proprio account con il parametro --stdin. – phatfingers

9

Si dovrebbe provare pssh (ssh parallelo allo stesso tempo).

cat>~/ssh-hosts<<EOF 
[email protected] 
[email protected] 
[email protected] 
EOF 

pssh -h ~/pssh-hosts 'printf "%s\n" old_pass new_pass new_pass | passwd' 
+0

Grazie, questa potrebbe essere una buona soluzione, ma ancora una volta, non abbiamo pssh sui nostri server .... :( – squashbuff

+0

Puoi eseguire questo comando su qualsiasi distribuzione come un dispositivo Android, un laptop, il tuo desktop. per installarlo sul lato client e avere solo ssh come lato server. Non vedo alcun problema;) Puoi anche iterare per un semplice bisogno con un ciclo for: for i in foo bar base; fai ssh "$ i" "riga di comando"; fatto –

+0

Interessante, lo esaminerò sicuramente. Grazie :) – squashbuff

1

È possibile utilizzare il Perl?

Here c'è uno script che modifica la password in un set di host.

Se sono necessari alcuni moduli Perl (Net::OpenSSH::Parallel, Expect e le relative dipendenze) installati sul computer locale che esegue lo script ma nulla sui server remoti in cui la password deve essere modificata.

+0

Questo potrebbe essere utile per alcune persone. È il modo particolare in cui viene impostato l'ambiente che mi impedisce di utilizzare questa soluzione. Non riesco ad accedere a questi server direttamente dal mio computer client. Devo accedere a un jumphost che ha il port forwarding disabilitato. Quindi lo script deve essere eseguito su quel jumphost, che ha tutte queste restrizioni in atto. Grazie per le informazioni però. – squashbuff

+0

@squashbuff: attualmente sto lavorando su un altro modulo Perl [Net :: OpenSSH :: Gateway] (https: // github.com/salva/p5-Net-OpenSSH-Gateway) che consente a [Net :: OpenSSH] (http://search.cpan.org/perldoc?Net::penSSH) di passare oltre i gateway in modo trasparente, ma è comunque un lavoro in corso. – salva

0

pensato che avrei dovuto mettere la mia soluzione in un campo risposta - non so se questo dovrebbe essere una parte della questione ..

OK, ho messo insieme una soluzione parziale di lavoro usando il suggerimento di Dennis.

servers.txt assomiglia:

server1 
server2 
server3 
. 
. 
. 

sto usando:

for server in `cat servers.txt`; do 
ssh $server -l user 'passwd <<EOF 
old_pass 
new_pass 
new_pass 
EOF'; 
done 

Questo produce:

[email protected]'s password: **<Type password manually>** 
(current) UNIX password: New UNIX password: Retype new UNIX password: Changing password for user user. 
Changing password for user 
passwd: all authentication tokens updated successfully. 
[email protected]'s password: **<Type password manually>** 
(current) UNIX password: New UNIX password: Retype new UNIX password: Changing password for user user. 
Changing password for user 
passwd: all authentication tokens updated successfully. 

Così qui, ho ancora bisogno di digitare la mia vecchia password una volta per ogni server. Questo può essere evitato?

+0

Hai mai trovato un modo per evitare di digitare la tua vecchia password una volta per ogni server? – Lizz

+1

@Lizz Ho finito con l'aspettativa. Non la soluzione ideale in termini di sicurezza, ma qualcosa doveva essere fatto rapidamente. Dai un'occhiata alla risposta accettata di Randy Katz. – squashbuff

3

Un'altra possibilità: modificarlo manualmente su un server. Ottieni la password crittografata da/etc/shadow. Ora, fare qualcosa di simile:

for host in $HOST_LIST; do 
    ssh $host "passwd -p 'encrypted_passwd' user" 
done 

Naturalmente, 'encrypted_passwd" è che cosa avete ottenuto di/etc/shadow in cui è stata modificata la password manualmente e $ HOST_LIST è un elenco di host in cui si desidera la password. cambiato.Che potrebbero essere creati semplicemente con:

export HOST_LIST="server1 server2 server15 server67" 

O magari con un file (come altri hanno suggerito):

export HOST_LIST=`cat host_list.txt` 

Dove il file "host_list.txt" ha un elenco di tutti i sistemi in cui si vuoi cambiare la password.

Modifica: se la versione di passwd non supporta l'opzione -p, è possibile che sia disponibile il programma 'usermod'. L'esempio sopra rimane lo stesso, basta sostituire 'passwd' con 'usermod'.

Inoltre, si potrebbe considerare l'useful tool pdsh, che semplificherebbe l'esempio precedente a qualcosa del genere:

echo $HOST_LIST | pdsh -Rssh -w- "usermod -p 'encrypted_passwd' user" 

Un'ultima "Beccato" per guardare fuori per: la password crittografata contiene probabilmente il simbolo del dollaro ('$') come separatore di campo. Probabilmente dovrai sfuggire a quelli nel tuo ciclo for o comando pdsh (ad esempio "$" diventa "\ $").

+1

Non esiste l'opzione '-p' per passwd-0.77-4.el6 (Enterprise Linux 6) o passwd-0.79-2.fc20 (Fedora 20). –

+1

Dai un'occhiata al programma 'usermod' ... su CentOS (clone di RHEL) 5.xe 6.x, supporta l'opzione -p. Ho modificato la mia risposta per includere più dettagli. – Matt

+0

ha funzionato benissimo per me. Giusto per chiarire: devi sfuggire TUTTI i caratteri $ nel tuo encrypted_passwd, non solo il primo. – lobi

5

Sulla base l'esempio di squashbuff, ho provato quanto segue, che ha funzionato bene per me:

#!/bin/bash 
for server in `cat hostlist`; do 
echo $server; 
ssh [email protected]$server 'passwd <&ltEOF 
old_password 
new_password 
new_password 
EOF'; 
done

Sicurezza saggio, potrebbe essere migliorata a prendere input senza eco alla schermata o salvare il testo in chiaro su disco.

0

Se si dispone di ssh, perché le password sono in primo luogo? Spingi la chiave ssh pubblica dell'utente su tutti i server che sono autorizzati a utilizzare e con cui farla. Ciò consente anche di concedere e revocare facilmente l'accesso tutto ciò che si desidera.

In un precedente $ dayjob, dove avevamo letteralmente decine di migliaia di server, disponevano di un database di cui erano autorizzati i tecnici su quali server e l'installazione delle chiavi ssh era un processo automatico. Quasi NESSUNO ha avuto una password su QUALSIASI macchina.

+1

Grazie a Edward, tuttavia la gestione dell'infrastruttura è stata esternalizzata e non ho voce in capitolo nel prendere tali decisioni. Devo fare questo lavoro senza apportare grossi cambiamenti alle infrastrutture. Questa non è un'opzione. – squashbuff

4
echo "name:password" | chpasswd 
+2

La domanda menziona che 'chpasswd' non può essere usato. –

2
  1. Installare sshpass su uno dei server da cui si desidera eseguire lo script.

    yum -y install sshpass 
    
  2. preparare un file di testo in cui si deve passare dettagli come Host, Nome utente, password e Port. (In base alle vostre esigenze).

    192.168.1.2|sachin|dddddd|22 
    
  3. Preparare un file di script utilizzando sotto i particolari.

    #!/bin/bash 
    
    FILE=/tmp/ipaddress.txt 
    
    MyServer="" 
    MyUser="" 
    MyPassword="" 
    MyPort="" 
    
    exec 3<&0 
    exec 0<$FILE 
    
    while read line 
    do 
        MyServer=$(echo $line | cut -d'|' -f1) 
        MyUser=$(echo $line | cut -d'|' -f2) 
        MyPassword=$(echo $line | cut -d'|' -f3) 
        MyPort=$(echo $line | cut -d'|' -f4) 
    
        HOST=$MyServer 
        USR=$MyUser 
        PASS=$MyPassword 
    
        sshpass -p $PASS ssh -p $MyPort -o StrictHostKeychecking=no [email protected]$HOST \ 
          -T "echo '[email protected]' | passwd --stdin root"     \ 
          < /dev/null | tee -a output.log 
    done 
    
    exec 0<&3 
    
+0

Le password non saranno visibili se qualcuno esegue 'ps'? –

0

echo -e "wakka2 \ nwakka2 \ n" | passwd root

1

Lo script passmass (man page) fornito con Expect non richiede l'installazione di Expect sulle macchine remote.

-2

La vera domanda è perché non stavano usando una sorta di servizi di denominazione? NIS/Pagine gialle o LDAP e non devi modificare manualmente le password su un gruppo di server. Un utente cambia la sua password una volta e viene eseguita attraverso il dominio master.

+0

Sto lavorando nell'ambiente attuale con restrizioni già in vigore. Non sono un amministratore di dominio e non ho voce in capitolo sulle modifiche architettoniche richieste per far funzionare la soluzione. Sto mettendo insieme una soluzione per gli utenti finali come me che lavorano nello stesso ambiente restrittivo. – squashbuff

0
cat /tmp/passwords | ssh $server sudo chpasswd -e 

se la password è criptata, o

cat /tmp/passwords | ssh $server sudo chpasswd 

se la password non è criptata.

/tmp/password dovrebbero avere formato "user: password"

+0

Come accennato nella domanda, gli utenti non hanno accesso root. Quindi 'sudo chpasswd' non può essere usato. Per essere onesti, se il sysadmin consente agli utenti di eseguire "sudo chpasswd", a mio parere è un grosso problema di sicurezza. – squashbuff

Problemi correlati