WikiMiNET

La documentation technique et administrative

Outils pour utilisateurs

Outils du site


wiki:services:backup_cfg_cisco

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

wiki:services:backup_cfg_cisco [2018/07/08 21:28]
no_pseudo restauration d'une ancienne conf
wiki:services:backup_cfg_cisco [2020/06/27 18:16]
Ligne 1: Ligne 1:
-====== Sauvegarder la configuration des commutateurs Cisco ====== 
- 
-« Sauvegarder la configuration des commutateurs c'est très important, parce qu'un jour vous allez faire de la merde et ça ne va plus marcher. » 
- --- //[[no_pseudo@minet.net|Captain Obvious]] 2018/07/07// 
- 
-<wrap lo>Et oui, je vais utiliser le mot « commutateur » tout le long de cet article.</wrap> 
- 
-===== Ce qui a été fait par le passé ===== 
- 
-Il y a très longtemps il semble qu'on utilisait un script qui analysait les logs des commutateurs sur la machine //serveurlog//<sup>1</sup>. Plus de détails sur la page [[wiki:services:confsvg|Sauvegarde des Confs]]. Je n'ai jamais vu le contenu du script mais je suppose que ça a du marcher pendant un moment si quelqu'un a pris la peine d'écrire un article dessus. 
- 
-Ensuite, on a la solution actuelle (qui date aussi) et qui marche... plus ou moins... C'est la tache nommée « Sauvegarde switchs »<sup>2</sup> qu'on peut trouver sur //jobs// et qui envoie les configurations sur GitLab [[https://gitlab.minet.net/divers/sauvegarde-des-switchs-svgs|sauvegarde-des-switchs-svgs]]. On peut constater que c'est un peu le bordel: certaines sauvegardes datent d'il y a 8 mois, d'autres d'il y a 2 ans et d'autres encore d'il y a 15 heures.  
- 
-<sup>1</sup> //serveurlog// c'était un serveur syslog, qui a été remplacé depuis par //logstash// et //elasticsearch//. 
- 
-<sup>2</sup> C'est en fait un script ruby (c'était encore à la mode à l'époque) qui en fait récupère la configuration des commutateurs en s'y connectant via SSH (avec bien sûr le mot de passe SSH<sup>3</sup> et //Enable// en clair dans le script). 
- 
-<sup>3</sup> En plus maintenant que les commutateurs utilisent les identifiants LDAP pour SSH, utiliser le mot de passe du compte SSH local risque de moins bien marcher. 
- 
-===== Ce qu'on voulait faire ===== 
- 
-Vu que la solution de la tâche « Sauvegarde switchs » ne marchait plus très très bien, on a décidé (entre septembre et décembre 2017) avec varens de trouver une solution alternative. Cette solution c'était un peu un mélange des 2 solutions précédentes à savoir: utiliser logstash avec le plugin //exec// pour lancer un script ou playbook ansible pour aller récupérer la configuration du commutateur via SSH lorsque celui-ci produit une certaine ligne de log. 
- 
-Bref, ayant surement des choses plus urgentes (ou pas) à gérer on a mis ce projet de côté. 
-Et puis on en a reparlé il y a pas longtemps et je me suis chauffé pour lire un peu la doc Cisco pour savoir comment s'y prendre pour implémenter tout le bordel. Et là <del>c'est le drame</del> je découvre qu'il y a déjà quelque chose prévu par Cisco pour faire des sauvegarde de configuration de manière très simple et pire encore c'était presque déjà configuré sur le commutateur du local (il manquait la partie la plus importante de la configuration). 
- 
-===== Ce qu'il faut faire ===== 
- 
-<WRAP center round important 60%> 
-Actuellement ce n'est qu'un proof-of-concept déployé en dev et sur le commutateur du local. Voir la partie « Démo ». 
-</WRAP> 
- 
-En fait il est possible de définir des « archives de configuration » sur les commutateurs. Ainsi pour définir une archive on doit donner au commutateur un chemin où stocker l'archive (ça peut être un chemin local ou sur le réseau) ainsi qu'une condition pour lancer le processus de création d'archive (un intervalle de temps ou une action). 
- 
-Ce qu'on veut faire c'est sauvegarder sur un serveur la configuration de notre commutateur lorsque quelqu'un fait une modification. 
-On a plusieurs protocole à notre disposition pour faire parler notre commutateur avec notre serveur: FTP, TFTP,  HTTP(S), RCP, SCP. 
- 
-Ici j'ai choisi d'utiliser SCP pour 2 raisons principales: 
-1) Éviter d'envoyer des configurations de commutateur en clair sur le réseau. (Alors oui, on va me dire « c'est sur un réseau privé » mais c'est pas une raison). 
- 
-2) Vu que SCP est basé sur SSH, on a pas grand chose à installer sur notre serveur: //openssh-server//, //openssh-client// et //rssh// (cf infra). 
- 
-==== Côté commutateur ==== 
-<code> 
-sw> enable 
-sw# configure terminal 
-sw(config)# archive 
-</code> 
- 
-<code> 
-sw(archive-config)# path scp://utilisateur:motdepassesuperduratrouver@192.168.103.178/archives/$h_$t 
-</code> 
-C.f. : Note sur le nom du fichier <sup>1</sup> 
- 
-<code> 
-sw(archive-config)# write-memory 
-</code> 
-<code> 
-sw(archive-config)# time-period 1440 
-</code> 
-On va lancer le processus d'archivage lorsqu'on fait un « write mem » ou toutes les 1440 minutes (toutes les 24h). 
- 
-<sup>1</sup>** Note sur le nom du fichier: « $h_$t » ** 
- 
- Le « $h » correspond au nom d'hote du commutateur, « $t » correspond à l'horodatage et un numéro de révision est ajouté automatiquement à la fin. Dans notre exemple « $h_$t » correspond à <hostname>_<timestamp>-<revision>, soit quelque chose comme « switch-local_Jul–8-2018-09-13-39.196-2 » 
- 
-Ici le timestamp est sous la forme «mois–numéro du jour-année-heure-minute-seconde-milliseconde», pour cela il faut s'assurer que notre commutateur génère bien son timestamp de cette façon: 
-<code> 
-sw(config)# service timestamp log datetime msec year 
-</code> 
- 
-<WRAP center round important 60%> 
-Il est important de garder des noms de fichier uniformes, ça nous sera utile ensuite pour la partie versioning. 
-</WRAP> 
- 
- 
- 
- 
- 
- 
-==== Côté serveur ==== 
- 
-La configuration __minimale__ du serveur est très simple: **openssh-server**, **openssh-client**<sup>1</sup> et un utilisateur pour le commutateur. 
- 
-On commence par créer un utilisateur et définir son mot de passe:  
-<code>root@confsw:/# useradd -d /var/confsw toto && passwd toto </code> 
- 
-Il nous faudra faire aussi 2 petites modifications de la configuration de notre serveur SSH: 
- 
-Nos commutateurs utilisent une veille version de SSH qui utilise des algorithmes d'échange de clé et de chiffrement qui ne sont plus activé par défaut dans la configuration du démon SSH sur Debian Stretch. 
-Pour déterminer les algos à ajouter à notre sshd on va essayer de se connecter en SSH depuis le commutateur sur notre serveur, normalement ça foire. Il ne nous reste plus qu'a retrouver les algos proposés par le commutateur dans ///var/log/auth.log//. 
- 
-Easy: 
-<code> 
-root@confsw:/# grep -E 'no matching key exchange method found|no matching cipher found' /var/log/auth.log 
-Jul  7 13:11:49 confsw sshd[1537]: Unable to negotiate with 192.168.103.219 port 25650: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1 [preauth] 
-Jul  7 13:13:53 confsw sshd[1212]: Unable to negotiate with 192.168.103.219 port 50277: no matching cipher found. Their offer: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc [preauth] 
- 
-</code> 
- 
-On ajoute donc ces algos à notre ///etc/ssh/sshd_config//: 
-<code> 
-KexAlgorithms +diffie-hellman-group1-sha1 
-Ciphers +aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc 
-</code> 
- 
-<sup>1</sup> Le binaire « scp » se trouve dans le paquet **openssh-client** et on a besoin de ce binaire. [[https://superuser.com/questions/577911/scp-lost-connection-but-ssh-works-fine|superuser.com]] 
- 
-=== SCP oui, SSH non ! === 
- 
-Pour éviter que le commutateur ait un accès shell à notre machine on va utiliser un petit programme qui s'appelle **rssh** qui va nous permettre de limiter ce qu'il est possible de faire via SSH. 
- 
-<code> apt install rssh </code> 
- 
-On change le login shell de notre utilisateur par rssh:  
-<code>usermod -s /usr/bin/rssh toto</code> 
- 
-Dans le fichier ///etc/rssh.conf// on ajoute: 
-<code> user=toto:022:000010:"/var/confsw/chroot" </code> 
- 
-Ce qui veut dire: « Pour l'utilisateur toto, on utilise 022 comme umask (celui par défaut normalement), on autorise la commande scp, on chroot l'utilisateur dans /var/confsw »  
- 
-Extrait de //man 5 rssh.conf//: 
-<code> 
- The user keyword's argument consists of a group of fields separated by a colon (':'), as shown below.  The fields are, in order: 
- 
-    username 
-        The username of the user for whom the entry provides options 
-    umask 
-        The umask for this user, in octal, just as it would be specified to the shell 
-    access bits 
-        Six binary digits, which indicate whether the user is allowed to use rsync,  rdist,  cvs,  sftp,  scp  and svnserve, in that order.  One means the command is allowed, zero means it is not. 
-    path 
-        The  directory to which this user should be chrooted (this is not a command, it is a directory name).  See chroot_path above for complete details. 
- 
-</code> 
- 
- 
-Il nous reste plus qu'a créer le chroot: 
-<code> 
-root@confsw:/# chmod u+s /usr/lib/rssh/rssh_chroot_helper 
-root@confsw:/# mkdir -p /var/confsw/chroot/archives 
-root@confsw:/# chown toto:toto /var/confsw/chroot/archives 
-root@confsw:/# /usr/share/doc/rssh/examples/mkchroot.sh /var/confsw/chroot/ 
-</code> 
- 
- 
-<WRAP center round important 60%> 
-TODO: Comment tester rapidement la configuration de rssh 
-</WRAP> 
- 
- 
-=== Gestion des versions === 
- 
-On commence par créer un utilisateur qui va « gitter » nos configurations. 
-On crée également le dossier qui va être le dossier de travail de notre utilisateur, par ex:///var/confsw/versions///. 
-<WRAP center round important 60%> 
-Il faut bien faire en sorte que notre nouvel utilisateur ait les droits de lecture au moins dans ///var/confsw/chroot/archives/// et les droits d'écriture dans ///var/confsw/versions/// 
-</WRAP> 
-  
-On utilise **inotify** via **incron** pour monitorer les fichiers dans ///var/confsw/chroot/archives///. 
- 
-<code> root@confsw:/# apt install incron 
-root@confsw:/# echo "jhondoe" >> /etc/incron.allow #on autorise notre nouvel utilisateur à utiliser incron 
-</code> 
- 
-Il faudra ensuite éditer la incrontab de jhondoe: 
-<code> 
-root@confsw:/# su johndoe -c 'incrontab -e' 
-</code> 
-Pour y ajouter notre tâche: 
-<code> 
-/var/confsw/chroot/archives/ IN_CREATE /opt/git_swconfig/git_swconfig.sh $@$# 
-</code> 
-Qui peut se traduire par: « Lorsqu'un fichier est crée dans ///var/confsw/chroot/archives/// lance le script  
-///opt/git_swconfig/git_swconfig.sh// avec pour argument le chemin absolu du nouveau fichier ». 
- 
-Le script « git_swconfig.sh » va alors traiter notre fichier de configuration fraîchement uploadé par le commutateur afin de le copier dans un dépôt git (tout en générant des logs dans syslog): 
-<code bash> 
-#!/bin/bash 
- 
-INPUT_FILE=$1 
-LOGGER="/usr/bin/logger id=${$} ${0} ' '" 
-GIT_BIN="/usr/bin/git" 
-GIT_USER="-c user.name='Confsw' -c user.email='confsw@minet.net'" 
-OUTPUT_DIR="/var/confsw/versions/" 
-GIT_WORK_TREE="--git-dir=${OUTPUT_DIR}/.git/ --work-tree=${OUTPUT_DIR}" 
- 
-#Expected filename format: <hostname>_<MMM>--<d>-<yyyy>-<hh>-<mm>-<ss>.<ms>-<revision> 
-FILENAME=$(basename $INPUT_FILE) 
- 
-HOSTNAME=$(echo $FILENAME | awk -F'_' '{print $1}') 
-REVISION=$(echo $FILENAME | awk -F'-' '{print $NF}') 
- 
-TIMESTAMP_RAW=$(echo $FILENAME | awk -F'_' '{print $2}' | awk -F'-' '{$NF=""; print $0}') 
-MONTH=$(echo $TIMESTAMP_RAW | awk '{print $1}') 
-DAY=$(echo $TIMESTAMP_RAW | awk '{print $2}') 
-YEAR=$(echo $TIMESTAMP_RAW | awk '{print $3}') 
-HOUR=$(echo $TIMESTAMP_RAW | awk '{print $4}') 
-MIN=$(echo $TIMESTAMP_RAW | awk '{print $5}') 
-SEC=$(echo $TIMESTAMP_RAW | awk '{print $6}' | awk -F'.' '{print $1}') 
-MSEC=$(echo $TIMESTAMP_RAW | awk '{print $6}' | awk -F'.' '{print $2}') 
- 
-OUTPUT_FILE="${OUTPUT_DIR}/${HOSTNAME}.conf" 
-DATE=$(date -d"${MONTH} ${DAY} ${YEAR} ${HOUR}:${MIN}:${SEC}.${MSEC}" --rfc-3339='ns') 
- 
-function versioning { 
- ACTION=$1 
- $GIT_BIN $GIT_WORK_TREE init $OUTPUT_DIR 
- cp $INPUT_FILE $OUTPUT_FILE 
- if [ $ACTION = "added" ]; then 
- $GIT_BIN $GIT_WORK_TREE add ${HOSTNAME}.conf 
- ADD_STATUS=$? 
- $LOGGER "$GIT_BIN $GIT_WORK_TREE add $OUTPUT_FILE: exit code $ADD_STATUS." 
- fi 
- COMMIT_MSG="${HOSTNAME} configuration ${ACTION} on ${DATE} (rev ${REVISION})." 
- $GIT_BIN $GIT_WORK_TREE $GIT_USER commit -am "$COMMIT_MSG" 
- COMMIT_STATUS=$? 
-        $LOGGER "$GIT_BIN $GIT_WORK_TREE $GIT_USER commit -am ${COMMIT_MSG}: exit code $COMMIT_STATUS." 
- #$GIT_BIN $GIT_WORK_TREE push -u origin master 
- #PUSH_STATUS=$? 
-        #$LOGGER "$GIT_BIN $GIT_WORK_TREE -u origin master: exit code $PUSH_STATUS." 
-} 
- 
-if [ -e $OUTPUT_FILE ]; then 
- diff -q $INPUT_FILE $OUTPUT_FILE 
- DIFF=$? 
- if [ $DIFF -eq 1 ]; then 
- $LOGGER "DEST: ${OUTPUT_FILE} differs from SRC: ${INPUT_FILE}. Updating DEST." 
- versioning "modified" 
- else 
- $LOGGER "No change detected between ${INPUT_FILE} and ${OUTPUT_FILE}. Nothing to do." 
- fi 
-else 
- $LOGGER "DEST: ${OUTPUT_FILE} does not exist. Adding DEST." 
- versioning "added" 
-fi 
- 
-</code> 
- 
-Notre dossier ///var/confsw/versions/// contiendra alors un joli dépôt git avec un commit à chaque « write mem ». 
- 
-===== Démo ===== 
- 
-Un container tourne en dev 
-<code> 
-ct: 105  
-hostname: confsw 
-ip: 192.168.103.178 
-</code> 
- 
- 
-On peut faire un « git log » dans ///var/confsw/versions/// pour voir les commits pendant qu'on fait des « write mem » sur le commutateur du local. 
- 
-Les choses intéressantes sur le CT: 
-<code> 
-/etc/passwd 
-/etc/rssh.conf 
-/etc/ssh/sshd_config 
-/etc/incron.allow 
-/opt/git_swconfig/git_swconfig.sh 
-/var/spool/incron/johndoe 
-/var/confsw/chroot/ 
-/var/confsw/versions/ 
-/var/log/syslog 
-</code> 
- 
-Les choses intéressantes sur le commutateur du local (en mode privilégié): 
-<code> 
-Le bloc de configuration « archive ». 
-La configuration de « service timestamp log ». 
-Le résultat de « show archive ». 
-</code> 
- 
-===== Restaurer une configuration ===== 
- 
-Pour restaurer une ancienne configuration il suffit en théorie de faire: 
-<code> 
-sw> enable 
-sw# copy scp://utilisateur:motdepassesuperduratrouver@192.168.103.178/archives/nom-du-fichier-de-conf startup-config: 
-</code> 
-Il est possible de voir les dernières archives via 
-<code> 
-sw# show archive 
-</code> 
- 
-===== Autre fonctionnalité des archives Cisco ===== 
- 
- 
- 
-Il est possible de journaliser toutes les commandes entrées sur le commutateur par un utilisateur. Combiné avec l'authentification via le service [[wiki:services:radius-switch|Radius-Switch]] ça peut être utile pour savoir //« qui a fait de la merde ? »//. 
-Tout est expliqué dans [[https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/config-mgmt/configuration/15-sy/config-mgmt-15-sy-book/cm-config-logger.pdf|ce pdf]]. 
- 
-Exemple de log: 
-{{:wiki:services:logcmdcisco.png?600|}} 
- 
-===== FIN ===== 
- 
- 
- --- //[[no_pseudo@minet.net|Kevin Cazal]] 2018/07/07 16:45// 
  
wiki/services/backup_cfg_cisco.txt · Dernière modification: 2020/06/27 18:16 (modification externe)