Nous avons un certain nombre de serveurs Linux Red Hat dans notre environnement informatique. Les membres de mon équipe me demandent d'écrire un script (de préférence un script Shell) pour changer le mot de passe d'un utilisateur sur chacun de ceux-ci en une seule fois, à l'aide de SSH.
J'ai essayé de trouver une solution, mais la plupart des scripts que j'ai trouvés utilisent Expect. Expect n’est pas installé sur nos serveurs et les administrateurs système ont refusé de nous laisser l’installer. De plus, les utilisateurs n'ont pas d'accès root, donc passwd --stdin
ou chpasswd
ne peuvent pas être utilisés.
Existe-t-il un moyen d'écrire un script pour qu'un utilisateur puisse l'exécuter et changer le mot de passe de son propre utilisateur uniquement sur tous les serveurs de la liste?
Les ordinateurs distants n’ont pas besoin d’être installés. Vous pouvez installer expect sur un poste de travail local ou sur VM (virtualbox) ou n’importe quelle boîte * nix, et écrire un wrapper qui appelle ce script .ex (expect) 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
Vous n'avez pas besoin d'un accès root pour utiliser passwd
.
Cela devrait bien fonctionner.
passwd <<EOF
old password
new password
new password
EOF
Vous devriez essayer pssh (ssh parallèle en même temps).
cat>~/ssh-hosts<<EOF
user100@Host-foo
user200@Host-bar
user848@Host-qux
EOF
pssh -h ~/pssh-hosts 'printf "%s\n" old_pass new_pass new_pass | passwd'
En me basant sur l'exemple de squashbuff, j'ai essayé les solutions suivantes, qui ont bien fonctionné pour moi:
#!/bin/bash pour le serveur dans `cat hostlist`; do echo $ server; ssh username @ $ server 'motdepasse & lt & ltEOF ancien_mot passe nouveau_mot de passe nouveau_mot de passe EOF';
En ce qui concerne la sécurité, pourrait être amélioré pour prendre des entrées sans afficher l’écho à l’écran OR lors de l’enregistrement du texte en clair sur le disque.
echo "name:password" | chpasswd
Une autre possibilité: changez-le manuellement sur un serveur. Extrayez le mot de passe crypté de/etc/shadow. Maintenant, faites quelque chose comme ça:
for Host in $Host_LIST; do
ssh $Host "passwd -p 'encrypted_passwd' user"
done
Bien sûr, 'encrypted_passwd "est ce que vous avez obtenu dans/etc/shadow où vous avez manuellement changé le mot de passe. Et $ Host_LIST est une liste d'hôtes sur lesquels vous souhaitez modifier le mot de passe. Vous pouvez le créer simplement avec:
export Host_LIST="server1 server2 server15 server67"
Ou peut-être avec un fichier (comme d'autres l'ont suggéré):
export Host_LIST=`cat Host_list.txt`
Où le fichier "Host_list.txt" contient une liste de tous les systèmes sur lesquels vous voulez changer le mot de passe.
Edit: si votre version de passwd ne prend pas en charge l'option -p, le programme 'usermod' est peut-être disponible. L'exemple ci-dessus reste le même, remplacez simplement «passwd» par «usermod».
En outre, vous pourriez envisager l’outil utile pdsh , qui simplifierait l’exemple ci-dessus pour donner à peu près la même chose:
echo $Host_LIST | pdsh -Rssh -w- "usermod -p 'encrypted_passwd' user"
Un dernier "piège" à rechercher: le mot de passe crypté contient probablement le caractère de signe dollar ("$") comme séparateur de champ. Vous devrez probablement échapper à ceux de votre boucle for ou de votre commande pdsh (c'est-à-dire que "$" devient "\ $").
Installez sshpass sur n’importe quel serveur sur lequel vous voulez exécuter le script.
yum -y install sshpass
Préparez un fichier texte dans lequel vous devez transmettre des informations telles que hôte, nom d'utilisateur, mot de passe et port. (Basé sur vos besoins).
192.168.1.2|sachin|dddddd|22
Préparez un fichier de script en utilisant les détails ci-dessous.
#!/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 $USR@$Host \
-T "echo 'sachin@patel' | passwd --stdin root" \
< /dev/null | tee -a output.log
done
exec 0<&3
Pouvez-vous utiliser Perl?
Ici il y a un script qui change le mot de passe dans un ensemble d'hôtes.
Si nécessite des modules Perl ( Net :: OpenSSH :: Parallel , Expect et leurs dépendances) installés sur la machine locale exécutant le script mais rien sur les serveurs distants pour lesquels le mot de passe doit être changé.
Une alternative que vous voudrez peut-être présenter à vos pairs serait de leur demander d'utiliser une authentification sans mot de passe. Ils généraient une paire de clés publique/privée et enregistraient leur clé publique dans le fichier ~/.ssh/registered_keys sur chacun des serveurs auxquels ils se connectent.
Le passmass script ( page de manuel ) fourni avec Expect ne nécessite pas l'installation d'Expect sur les ordinateurs distants.
Avez-vous essayé App :: Unix :: RPasswd
echo -e "wakka2\nwakka2\n" | passwd root
cat /tmp/passwords | ssh $server Sudo chpasswd -e
si le mot de passe est crypté, ou
cat /tmp/passwords | ssh $server Sudo chpasswd
si le mot de passe n'est pas crypté.
/ tmp/password devrait avoir le format "user: password"
Je pensais que je devrais mettre ma solution dans un champ de réponse - ne sachant pas si cela devrait faire partie de la question.
OK, j'ai mis au point une solution partiellement efficace en utilisant la suggestion de Dennis.
servers.txt ressemble à:
server1
server2
server3
.
.
.
J'utilise:
for server in `cat servers.txt`; do
ssh $server -l user 'passwd <<EOF
old_pass
new_pass
new_pass
EOF';
done
Cela produit:
user@server1'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.
user@server2'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.
Donc, ici, je dois encore taper mon ancien mot de passe une fois pour chaque serveur. Cela peut-il être évité?
Si vous avez ssh, pourquoi avoir des mots de passe en premier lieu? Poussez la clé ssh publique de l'utilisateur sur tous les serveurs qu'il est autorisé à utiliser et utilisez-la. Cela vous permet également d’accorder et de révoquer facilement tout ce que vous voulez.
Lors d'une précédente session $ day, où nous avions littéralement des dizaines de milliers de serveurs, ils avaient une base de données sur laquelle les ingénieurs étaient autorisés sur quels serveurs et l'installation des clés ssh était un processus automatisé. Presque personne n'avait un mot de passe sur N'IMPORTE QUELLE machine.