original in en Erdal Mutlu
en to fr Georges Tarbouriech
Erdal est l'un des �diteurs Turcs de LF. Il travaille actuellement comme administrateur syst�me pour Linotype Library. En tant qu'inconditionnel de Linux depuis ses ann�es universitaires, il aime travailler et d�velopper dans cet environnement.
Afin de comprendre cet article vous devez avoir des connaissances de base sur la programmation shell. Pour plus ample information, lisez l'article de LinuxFocus Programmation du shell de Katja et Guido Socher. Vous devez aussi conna�tre les utilitaires ssh comme ssh-keygen, ssh-add, ssh, scp ou sftp. Une version libre du protocole SSH existe sous Linux OpenSSH et contient tous ces utilitaires. Des pages de manuel sont �galement disponibles.
scp /chemin/vers/le/fichier/fichier1 utilisateur@h�te_distant:/r�pertoire_distant/nouveau_fichier
Dans cet exemple le fichier nomm� fichier1 est copi� du r�pertoire local vers l'h�te distant (l'h�te distant peut �tre l'adresse IP ou le nom de la machine) dans /r�pertoire_distant sous le nom nouveau_fichier. Vous devez vous identifier en tant que 'utilisateur'. Si l'authentification est accept�e et que l'utilisateur distant poss�de les droits n�cessaires, le fichier sera copi�. Il est possible d'omettre le nom du fichier de destination. Dans ce cas, le fichier est copi� avec le m�me nom. C'est simplement pour indiquer la facult� de changer le nom pendant la copie.scp utilisateur@h�te_distant:/r�pertoire_distant/fichier /chemin/vers/r�pertoire_local/nouveau_fichier
La commande scp poss�de aussi une option tr�s pratique, '-r' permettant de copier des r�pertoires de mani�re r�cursive.scp -r utilisateur@h�te_distant:/r�pertoire_distant.
La commande ci-dessus copie le r�pertoire 'r�pertoire_distant' avec tous ses sous-r�pertoires et fichiers, de l'h�te distant vers le r�pertoire courant sous le m�me nom.Note: Le d�mon sshd doit bien s�r �tre actif sur l'h�te distant.
ssh [email protected] df -H
C'est pratiquement la syntaxe d'un rlogin. La seule diff�rence se situe apr�s le nom de l'h�te. La commande ('df -H' dans cet exemple) est destin�e � �tre ex�cut�e sur la machine distante. La sortie de la commande s'affiche sur votre terminal.ssh-keygen -b 1024 -t dsa
Le nom de la cl� priv�e doit �tre fourni. Normalement, le nom de la cl� publique est le m�me avec l'extension '.pub'. Ici, '-b 1024' est le nombre de bits de la cl� � cr�er. Si vous ne le sp�cifiez pas, la valeur par d�faut sera utilis�e. '-t dsa' indique le type de cl�. Les valeurs disponibles sont 'rsa1' pour la version 1 du protocole et 'rsa' ou 'dsa' pour la version 2. Il est recommand� d'utiliser la version 2 de SSH. Toutefois, si vous poss�dez d'anciens serveurs qui ne supportent que la version 1, vous devrez sp�cifier '-t rsa1' et cr�er une autre paire de cl�s. Vous pouvez forcer ssh � utiliser l'un des deux protocoles en pr�cisant '-1' ou '-2'.Afin de b�n�ficier de la cl�, vous devrez installer la cl� publique sur l'ordinateur distant. Le contenu du fichier de la cl� publique doit �tre copi� ou ajout� au fichier $HOME/.ssh/authorized_keys ou $HOME/.ssh/authorized_keys2. Attention, ne m�langez pas les cl�s pour des versions diff�rentes du protocole. authorized_keys est utilis� pour la version 1 du protocole et authorized_keys2 pour la version 2. Si votre cl� publique est correctement install�e, lors de la prochaine connexion � cette machine votre "passphrase" vous sera r�clam�e, sinon vous devrez fournir le mot de passe de l'utilisateur distant. Vous pouvez restreindre les connexions vers vos syst�mes en n'utilisant qu'une authentification par cl� publique en �ditant le fichier de configuration de sshd. Le fichier se nomme /etc/ssh/sshd_config et 'PasswordAuthentication' est le param�tre � modifier. Passez la valeur de ce param�tre � no (PasswordAuthentication no) et red�marrez sshd.
Jusque l�, tout va bien. Nous disposons d'un moyen s�curis� de copier et d'ex�cuter des commandes sur des syst�mes distants. Toutefois, pour automatiser certaines t�ches, nous ne devrions pas avoir � taper des mots de passe ou des "passphrases", sinon, point de salut. Une solution pourrait consister � �crire le mot de passe ou la "passphrase" dans chaque script, mais ce n'est vraiment pas une bonne id�e. Le meilleur moyen est d'utiliser ssh-agent puisqu'il est pr�vu pour g�rer les cl�s priv�es servant � l'authentification par cl�s publiques. D�marrez un agent :
ssh-agent $BASH
et ajoutez vos cl�s priv�es par les commandesssh-add .ssh/id_dsa
oussh-add .ssh/identity
id_dsa est le fichier de cl� priv�e DSA et identity est le fichier de cl�s priv�es RSA1. Ce sont les noms donn�s par d�faut lors de la g�n�ration de cl�s par ssh-keygen. Evidemment, votre "passphrase" sera r�clam�e avant que ssh-add n'ajoute votre cl� au ssh-agent. Vous pouvez lister les cl�s ajout�es avec la commande :ssh-add -l
Maintenant, si vous vous connectez � un serveur qui poss�de votre cl� dans le fichier correspondant, vous n'aurez rien � taper ! Le ssh-agent prend en charge le processus d'authentification.
Si vous utilisez ssh-agent comme d�crit ci-dessus, vous ne pouvez vous en servir que depuis le terminal qui l'a d�marr�. Pour pouvoir en b�n�ficier � partir de n'importe quel terminal, il reste encore un peu de travail. J'ai �crit le script suivant pour d�marrer l'agent :
#!/bin/sh # # Erdal mutlu # # Starting an ssh-agent for batch jobs usage. agent_info_file=~/.ssh/agent_info if [ -f $agent_info_file ]; then echo "Agent info file : $agent_info_file exists." echo "make sure that no ssh-agent is running and then delete this file." exit 1 fi ssh-agent | head -2 > $agent_info_file chmod 600 $agent_info_file exit 0
Ce script contr�le l'existence d'un fichier nomm� agent_info dans le r�pertoire home de l'utilisateur o� se trouvent habituellement les fichiers relatifs � ssh. Dans notre cas le r�pertoire se nomme '.ssh/'. Si le fichier existe, l'utilisateur en est averti et un bref message lui indique ce qui peut �tre fait. Si l'utilisateur n'a pas encore d�marr� le ssh-agent il doit effacer le fichier et relancer le script. Le script ex�cute le ssh-agent et capture les deux premi�res lignes du fichier agent_info. Cette information sera mise � profit ult�rieurement par les utilitaires ssh. Ensuite, le mode du fichier est chang� pour que seul son propri�taire poss�de les droits de lecture et d'�criture.
Lorsque l'agent est actif vous pouvez y ajouter vos cl�s. Mais auparavant vous devez localiser le fichier agent_info afin de permettre aux utilitaires ssh de savoir o� se trouve votre agent :
source ~/.ssh/agent_info ou . ~/.ssh/agent_info
Et ajoutez vos cl�s avec ssh-add. Vous pouvez ajouter aussi les lignes suivantes dans votre fichier .bashrc de mani�re � ce que le fichier agent_info soit localis� � chaque ouverture d'un terminal :
if [ -f .ssh/agent_info ]; then . .ssh/agent_info fi
ATTENTION: Vous devez s�curiser l'h�te � partir duquel vous ex�cutez ssh-agent et le script que je vais d�crire. Sinon, si quelqu'un acc�de � votre compte, il aura acc�s � tous les serveurs utilisant les cl�s ssh. Tout a un prix !
Il est temps maintenant d'expliquer comment nous allons automatiser quelques unes des t�ches d'un administrateur. L'id�e consiste � ex�cuter un ensemble de commandes sur un groupe d'h�tes donn� et de r�cup�rer ou d'envoyer des fichiers de ou vers ces h�tes. C'est le travail quotidien d'un sysadmin. Voici le script :
#!/bin/sh # Installing anything using Secure SHELL and SSH agent # Erdal MUTLU # 11.03.2001 ################################################################## # Functions # ################################################################## ### Copy files between hosts copy_files() { if [ $files_file != "files_empty.txt" ];then cat $files_file | grep -v "#" | while read -r line do direction=`echo ${line} | cut -d " " -f 1` file1=`echo ${line} | cut -d " " -f 2` file2=`echo ${line} | cut -d " " -f 3` case ${direction} in "l2r") : ### From localhost to remote host echo "$file1 --> ${host}:${file2}" scp $file1 root@${host}:${file2} ;; "r2l") : ### From remote host to localhost echo "${host}:${file2} --> localhost:${file2}" scp root@${host}:${file1} ${file2} ;; *) echo "Unknown direction of copy : ${direction}" echo "Must be either local or remote." ;; esac done fi } ### Execute commands on remote hosts execute_commands() { if [ $commands_file != "commands_empty.txt" ];then cat $commands_file | grep -v "#" | while read -r line do command_str="${line}" echo "Executing $command_str ..." ssh -x -a root@${host} ${command_str} & wait $! echo "Execute $command_str OK." done fi } ### Wrapper function to execute_commands and copy_files functions doit() { cat $host_file | grep -v "#" | while read -r host do echo "host=$host processing..." case "${mode}" in "1") copy_files execute_commands ;; "2") execute_commands copy_files ;; *) echo "$0 : Unknown mode : ${mode}" ;; esac echo "host=$host ok." echo "------------------------------------------------------------------" done } ################################################################## ### Program starts here ################################################################## if [ $# -ne 4 ]; then echo "Usage : $0 mode host_file files_file commands_file" echo "" echo "mode is 1 or 2 " echo " 1 : first copy files and then execute commands." echo " 2 : first execute commands and then copy files." echo "If the name of files.txt is files_empty.txt then it is not processed." echo "If the name of commands.txt is commands_empty.txt then it is echo "not processed." exit fi mode=$1 host_file=$2 files_file=$3 commands_file=$4 agent_info_file=~/.ssh/agent_info if [ -f $agent_info_file ]; then . $agent_info_file fi if [ ! -f $host_file ]; then echo "Hosts file : $host_file does not exist!" exit 1 fi if [ $files_file != "files_empty.txt" -a ! -f $files_file ]; then echo "Files file : $files_file does not exist!" exit 1 fi if [ $commands_file != "commands_empty.txt" -a ! -f $commands_file ]; then echo "Commands file : $commands_file does not exist!" exit 1 fi #### Do everything there doit
Sauvons le script sous le nom ainstall.sh (automated installation) et essayons de l'ex�cuter sans param�tres. Nous obtiendrons le message suivant :
./ainstall.sh
Usage : ./ainstall.sh mode host_file files_file commands_file mode is 1 or 2 1 : first copy files and then execute commands. 2 : first execute commands and then copy files. If the name of files.txt is files_empty.txt then it is not processed. If the name of commands.txt is commands_empty.txt then it is not processed. |
Comme le dit le message, si vous ne souhaitez pas ex�cuter de commande, donnez le nom commands_empty.txt � l'argument commands.txt et si vous ne voulez pas transf�rer de fichier, donnez le nom files_empty.txt � l'argument files_file. Parfois, vous devrez seulement ex�cuter des commandes et d'autres fois vous aurez seulement � transf�rer des fichiers.
Avant d'expliquer le script ligne � ligne, prenons un exemple d'utilisation :
supposons que vous ayiez ajout� un serveur DNS secondaire � votre r�seau et
vouliez l'inscrire dans le fichier /etc/resolv.conf. Pour des raisons de
simplicit�, admettons que tous les h�tes poss�dent le m�me fichier resolv.conf.
La seule chose � faire est donc de copier le nouveau fichier resolv.conf sur
tous les h�tes.
Il vous faut d'abord une liste de vos h�tes. Nous allons les inscrire dans un
fichier hosts.txt. Ce fichier contient un nom d'h�te ou une adresse IP par
ligne. Voici un exemple :
########################################################################## #### Every line contains one hostname or IP address of a host. Lines that #### begin with or contain # character are ignored. ########################################################################## helvetica.fonts.de optima.fonts.de zaphino vectora #10.10.10.162 10.10.10.106 193.103.125.43 10.53.103.120 |
Comme vous pouvez le voir dans l'exemple, il est possible d'inscrire des noms FQDN (Fully Qualified Domain Name) ou simplement la partie concernant l'h�te. Il vous faut ensuite un fichier dans lequel inscrire les fichiers � transf�rer. Il exite deux types de transfert :
Les fichiers � transf�rer sont list�s dans un autre fichier. Sauvons ce fichier sous le nom files_file.txt. Ce fichier est au format suivant : chaque ligne contient l'information de copie d'un seul fichier. Il existe deux directions de copie : l2r (local to remote - local vers distant) et r2l (remote to local - distant vers local). l2r correspond au cas d'un fichier copi� de l'h�te local vers un h�te distant. r2l correspond au cas d'un fichier copi� d'un h�te distant vers l'h�te local. Apr�s le sens de copie nous trouvons deux noms de fichiers. Les champs sont s�par�s par un espace ou une tabulation. Le premier fichier est copi� vers le second fichier selon la direction choisie. Le nom de fichier pour l'h�te distant doit correspondre au chemin complet, sinon il sera copi� dans le r�pertoire home de l'utilisateur root. Voici notre files_file.txt :
############################################################################ # The structure of this file is : # - The meaning of the fields are : is l2r (localhost to remote) and r2l # (remote computer to local). # r2l file1 file2 # means copy file1 from remote (hosts specified in the # hosts.txt file) computer to localhost as file2. # l2r file1 file2 # means copy file1 from localhost to # remote (hosts specified in the hosts.txt file) computer as file2 # file1 and file2 are files on the corresponding hosts. # # Note: the order of using local and remote specifies the direction # of the copy process. ############################################################################ l2r resolv.conf /etc/resolv.conf |
Comme vous le voyez, j'ai d�j� inclus la description de la structure du fichier. J'ajoute habituellement une description de tous les fichiers files_file.txt que j'utilise. C'est une solution simple mais efficace pour documenter. Dans notre exemple, nous voulons copier le fichier resolv.conf sur un h�te distant sous le nom /etc/resolv.conf. Dans un but didactique, apr�s avoir copi� le fichier sur ses destinataires j'ai ajout� des commandes permettant de modifier le propri�taire et le groupe et d'afficher le contenu du fichier transf�r�. Les commandes � ex�cuter sont plac�es dans un fichier s�par�. Appelons-le commands_file.txt. Le voici :
########################################################################### # The structure of this file is : Every line contains a command to be # executed. Every command is treated seperately. ########################################################################### chown root.root /etc/resolv.conf chmod 644 /etc/resolv.conf cat /etc/resolv.conf |
Le fichier des commandes contient les commandes qui seront ex�cut�es sur chaque h�te list� dans le fichier hosts.txt. Ces commandes sont ex�cut�es de fa�on s�quentielle, c'est-�-dire dans l'ordre du fichier.
Voil�, nous avons maintenant les fichiers requis par ce simple exemple. La seule chose qui reste � pr�ciser, c'est l'option 'mode', ce qui signifie : lequel des deux fichiers commands_file.txt ou files_file.txt doit �tre trait� le premier. Il est possible de transf�rer les fichiers list�s dans files_file.txt et d'ex�cuter ensuite les commandes sur l'h�te cible : c'est le mode = 1. Le contraire, ex�cuter les commandes et transf�rer ensuite les fichiers, correspond au mode = 2. Vous pouvez maintenant ex�cuter le script avec les arguments requis comme suit :
./ainstall.sh 1 hosts.txt files_file.txt commands_file.txt
Un petit "truc" : j'ajoute toujours un pr�fixe files_ � ces fichiers texte et je donne ensuite un nom descriptif court, comme files_resolvconf.txt. En fait, la m�me m�thode que celle employ�e pour hosts.txt et commands.txt
Il est temps maintenant de donner quelques explications sur le script proprement dit. Le programme commence par v�rifier le nombre d'arguments et si celui-ci n'est pas �gal � 4, un message de syntaxe est affich�. Si le nombre d'arguments est correct, ces derniers sont affect�s aux variables correspondantes. Ensuite, si le fichier '~/.ssh/agent_info' existe, il est "sourc�". Ce fichier contient les informations concernant l'agent ssh actif. Si vous n'utilisez pas d'agent, vous devrez taper un mot de passe ou une "passphrase", ce qui signifie : pas d'automatisation :) L'existence de chaque fichier (hosts, files, commands) est ensuite v�rifi�e. Un contr�le particulier est effectu� pour les fichiers files_empty.txt et commands_empty.txt. Si vous avez d�j� d�fini de tels noms, il n'est pas n�cessaire de v�rifier l'existence de ces fichiers. J'ai modifi� cette partie du script lors de l'�criture de l'article. Auparavant, il contenait seulement :
if [ -f $host_file -a -f $files_file -a -f $commands_file ]; then echo "$host_file $files_file $commands_file" doit else echo "$host_file or $files_file or $commands_file does not exist" exit fi
Dans ce cas, je devais avoir des fichiers nomm�s files_empty.txt et
commands_empty.txt. Ce n'�tait pas un probl�me dans la mesure o� je ne
travaillais que sur un seul r�pertoire.
A la fin, nous trouvons l'appel � la fonction 'doit'. Tout est contr�l� par
cette fonction. Elle poss�de une boucle bas�e sur 'cat' et 'while', qui pour
chaque h�te list� dans '$hosts_file' appelle copy_files et ex�cute les fonctions
_commands selon le 'mode'. Ainsi, le travail est effectu� pour chaque h�te. La
variable 'host' contient le nom d'h�te courant et son adresse IP.
Regardons la fonction copy_files. Cette fonction v�rifie d'abord si la valeur de
'files_file' est �gale � celle de 'files_empty.txt'. Si oui, rien n'est fait.
Dans le cas contraire, pour chaque ligne dans '$files_file', les variables
'direction', 'file1' et 'file2' contiennent le sens de copie, le premier et le
second noms de fichier. Selon la valeur de la variable 'direction', la copie est
ex�cut�e par scp.
Enfin, regardons ce qui est fait dans la fonction execute_commands.
La fonction v�rifie si la valeur de 'commands_file' est �gale � celle de
'commands_empty.txt'. Si oui, rien n'est fait. Si non, chaque commande dans
'$commands_file' est ex�cut�e en t�che de fond sur l'h�te distant par ssh.
Apr�s l'ex�cution de la commande ssh, nous trouvons un appel � la commande wait
avec le param�tre '$!'. Cette derni�re contr�le que les commandes sont bien
ex�cut�es l'une apr�s l'autre. '$!' incr�mente l'ID du processus de la derni�re
commande ex�cut�e en t�che de fond.
Et c'est tout. Simple, non ?
Voici un usage plus �labor� du script. L'id�e est de faire une sauvegarde des fichiers de configuration de vos h�tes ou serveurs. Dans ce but, j'ai �crit un petit script qui utilise ainstall.sh :
#!/bin/sh server_dir=${HOME}/erdal/sh/ServerBackups if [ ! -d $server_dir ]; then echo "Directory : $server_dir does not exists." exit 1 fi cd $server_dir servers=ll_servers.txt prog=${HOME}/erdal/sh/einstall_sa.sh cat $servers | grep -v "#" | while read -r host do echo $host > host.txt $prog 1 host.txt files_empty.txt servers/${host}/commands_make_backup.txt $prog 1 host.txt files_getbackup.txt commands_empty.txt mv -f backup.tgz servers/${host}/backup/`date +%Y%m%d`.tgz rm -f host.txt done exit 0
Il vous faut un r�pertoire particulier nomm� servers. Dans ce r�pertoire, vous devez avoir deux fichiers : files_getbackup.txt et ll_servers.txt. Voici le fichier 'files_getbackup.txt' :
r2l /root/backup.tgz backup.tgz
'll_servers.txt' contient les noms ou les adresses IP des h�tes � sauvegarder. Chaque h�te list� dans le fichier 'll_servers.txt' doit poss�der un r�pertoire avec le m�me nom contenant un fichier nomm� commands_make_backups.txt, qui lui-m�me contient une commande destin�e � cr�er une archive /root/backup.tgz des fichiers de configuration de cet h�te. Il faut aussi un r�pertoire nomm� backup. Toutes les sauvegardes de cet h�te seront stock�es dans ce r�pertoire. Si le fichier ll_servers.txt contient :
fileserver dbserver 10.10.10.1 appserver |
alors la structure de votre r�pertoire '$servers' doit �tre la suivante :
servers |-- files_getbackup.txt |-- ll_servers.txt |-- make_server_backups.sh |-- 10.10.10.1 | |-- backup | `-- commands_make_backup.txt |-- appserver | |-- backup | `-- commands_make_backup.txt |-- dbserver | |-- backup | `-- commands_make_backup.txt |-- fileserver |-- backup `-- commands_make_backup.txt |
Et voici quelques exemples de fichiers commands_make_backups.txt :
tar cfz /root/backup.tgz /etc/samba /etc/atalk /etc/named.conf /var/named/zones
Ce fichier commands_make_backup.txt est utilis� pour sauvegarder les configurations de samba, atalk ainsi que celles du serveur de nom et des fichiers de zone.
tar cfz /root/backup.tgz /etc/httpd /usr/local/apache
Ce fichier commands_make_backup.txt est utilis� pour sauvegarder la configuration et les fichiers d'un serveur apache.
tar cfz /root/backup.tgz /etc/squid /etc/named.conf
Ce fichier commands_make_backup.txt est utilis� pour sauvegarder les configurations du serveur proxy squid et du serveur DNS secondaire.
En utilisant le script ci-dessus avec des fichiers commands_make_backup.txt correspondant � vos besoins, vous pouvez sauvegarder les configurations de vos serveurs.