appunti di Adam - Installare e configurare un server …...Backup dispositivi di rete Installare e...

45
Backup dispositivi di rete Installare e configurare un server Rancid su CentOS 7 RANCID supporta hardware multiplo come di Cisco, HP, Dell, Juniper e altro ancora. Questo è un sistema open-source e permette di creare creare script personalizzati per creare u proprio questo un archivio personale degli apparati di rete. la modifica del client deve essere effettuata durante la fase di installazione, diversi pacchetti devono essere installati. Supponiamo che abbiate già installato CentOS 7 versione minima e collegata ad internet: Prima di iniziare dobbiamo eseguire l’aggiornamento di tutti i pacchetti di sistema, con i comandi: yum update yum upgrade Installiamo ora tutti i requisiti necessari per permettere a Rancid di funzionare: yum install nano wget ftp telnet mariadb-server mariadb perl tcl expect gcc cvs rcs httpd autoconf php-common php-gd php-pear php-pecl-memcache php-mysql php-xml mod_ssl MySQL-python Terminata l’installazione dei vari componenti avviamo Apache e consentiamo al suo servizio di avviarsi in automatico durante la fase di avvio: systemctl enable httpd.service systemctl start httpd.service Una volta che Apache è abilitato dovremmo vedere la pagina web di esempio da Apache quando digitiamo sul browser l'indirizzo IP del server. Ora abbiamo bisogno di aggiungere un gruppo per l'utente rancid groupadd netadm Successivamente creeremo un utente chiamato rancid e metteremo questo utente sotto il gruppo che abbiamo appena creato, che è netadm. Dovremo insereire l'utente nella home directory usando i seguenti comandi: useradd -g netadm -c "Networking Backups" -d /home/rancid rancid Creare una directory per inserire tutti i file di installazione. mkdir /home/rancid/tar Spostiamoci ora nel folder tar cd /home/rancid/tar Ed eseguiamo il download di Rancid scaricando l’ultima versione al momento disponibile 1

Transcript of appunti di Adam - Installare e configurare un server …...Backup dispositivi di rete Installare e...

Backup dispositivi di rete

Installare e configurare un server Rancid su CentOS 7

RANCID supporta hardware multiplo come di Cisco, HP, Dell, Juniper e altro ancora. Questo è un sistema open-source e permette di creare creare script personalizzati per creare u proprio questo un archivio personale degli apparati di rete.

la modifica del client deve essere effettuata durante la fase di installazione, diversi pacchetti devonoessere installati.

Supponiamo che abbiate già installato CentOS 7 versione minima e collegata ad internet: Prima di iniziare dobbiamo eseguire l’aggiornamento di tutti i pacchetti di sistema, con i comandi:

yum update yum upgrade

Installiamo ora tutti i requisiti necessari per permettere a Rancid di funzionare:

yum install nano wget ftp telnet mariadb-server mariadb perl tcl expect gcc cvs rcs httpd autoconf php-common php-gd php-pear php-pecl-memcache php-mysql php-xml mod_ssl MySQL-python

Terminata l’installazione dei vari componenti avviamo Apache e consentiamo al suo servizio di avviarsi in automatico durante la fase di avvio:

systemctl enable httpd.servicesystemctl start httpd.service

Una volta che Apache è abilitato dovremmo vedere la pagina web di esempio da Apache quando digitiamo sul browser l'indirizzo IP del server. Ora abbiamo bisogno di aggiungere un gruppo per l'utente rancid

groupadd netadm

Successivamente creeremo un utente chiamato rancid e metteremo questo utente sotto il gruppo cheabbiamo appena creato, che è netadm. Dovremo insereire l'utente nella home directory usando iseguenti comandi:

useradd -g netadm -c "Networking Backups" -d /home/rancid rancid

Creare una directory per inserire tutti i file di installazione.

mkdir /home/rancid/tar

Spostiamoci ora nel folder tar

cd /home/rancid/tar

Ed eseguiamo il download di Rancid scaricando l’ultima versione al momento disponibile

1

Backup dispositivi di rete

wget ftp://ftp.shrubbery.net/pub/rancid/rancid-3.6.2.tar.gz

Terminato il download estraiamo il tarballtar -zxvf rancid-3.6.2.tar.gz

entriamo nella cartella scompattata di rancid

cd rancid-3.6.2

Eseguiamo ora il seguente comando per preparare rancid all’installazione

./configure –prefix=/usr/local/rancid

Al termine della preparazione installiamolo con il comando

make install

Ora dobbiamo copiare e modificare alcuni permessi:

cp cloginrc.sample /home/rancid/.cloginrcchmod 0640 /home/rancid/.cloginrcchown -R rancid:netadm /home/rancid/.cloginrcchown -R rancid:netadm /usr/local/rancid/chmod 775 /usr/local/rancid/

Dobbiamo ora modificare il file di configurazione di rancid e mettere i nostri dispositivi all’interno di gruppi. Cerchiamo "elenco di gruppi di rancid" e rimuoviamo il simbolo cancelletto. Digitiamo poi i gruppi che si vorrebbero creare, per esempio (Router Switch)

nano /usr/local/rancid/etc/rancid.conf

...

# list of rancid groups

LIST_OF_GROUPS="Routers Switches"

# more groups...

#LIST_OF_GROUPS="$LIST_OF_GROUPS noc billybobisp"

#...

Switch su l’account Rancid con

su rancid

2

Backup dispositivi di rete

Eseguire il seguente comando, questo crea un repository CVS con i gruppi appena inseriti nella listadei gruppi.

/usr/local/rancid/bin/rancid-cvs

No conflicts created by this import

cvs checkout: Updating Routers

Directory /usr/local/rancid/var/CVS/Routers/configs added to the repository

cvs commit: Examining configs

cvs add: scheduling file `router.db' for addition

cvs add: use 'cvs commit' to add this file permanently

RCS file: /usr/local/rancid/var/CVS/Routers/router.db,v

done

Checking in router.db;

/usr/local/rancid/var/CVS/Routers/router.db,v <-- router.db

initial revision: 1.1

done

No conflicts created by this import

cvs checkout: Updating Switches

Directory /usr/local/rancid/var/CVS/Switches/configs added to the repository

cvs commit: Examining configs

cvs add: scheduling file `router.db' for addition

cvs add: use 'cvs commit' to add this file permanently

RCS file: /usr/local/rancid/var/CVS/Switches/router.db,v

done

Checking in router.db;

/usr/local/rancid/var/CVS/Switches/router.db,v <-- router.db

3

Backup dispositivi di rete

initial revision: 1.1

done

Dopo l'esecuzione del comando, se tutto va a buon fine, torneremo alla radice TAR.

exit

cd /home/rancid/tar/

Successivamente vorremo scaricare la versione ViewVC è 1.1.23. ViewVC (ex ViewCVS) è uno strumento open source per la visualizzazione dei contenuti del CVS e SVN repository utilizzando un browser web. Permette guardando revisioni specifiche di file così come side-by-side diff di diverse revisioni. E 'scritto in Python ed i parametri di visualizzazione possono essere modificati direttamente in un URL utilizzando un'interfaccia in stile REST.

wget http://viewvc.tigris.org/files/documents/3330/49392/viewvc-1.1.23.tar.gz

Estraiamo il tarball

tar -zxvf viewvc-1.1.23.tar.gz

Spostiamoci nella cartella ViewVC e lanciamo l’installazione

cd viewvc-1.1.23./viewvc-install

Ora abbiamo bisogno di modificare il file di configurazione ViewVC, fondamentalmente dicendo a ViewVC che il repository che deve visualizzare è in CVS.

nano /usr/local/viewvc-1.1.23/viewvc.conf

Modifichiamo come segue:

...

## Example:

## cvs_roots = cvsroot: /opt/cvs/repos1,

## anotherroot: /usr/local/cvs/repos2

##

#cvs_roots = cvs:

4

Backup dispositivi di rete

## svn_roots: Specifies each of the Subversion roots (repositories) on

## your system and assigns names to them. Each root should be given by

...

## Example:

## root_parents = /opt/svn: svn,

## /opt/cvs: cvs

##

root_parents = /usr/local/rancid/var/CVS : cvs

## default_root: This is the name of the default root. Valid names

...

## Example:

## rcs_dir = /usr/bin/

##

rcs_dir = /usr/local/bin

## cvsnt: Location of cvsnt program. ViewVC can use CVSNT (www.cvsnt.org)

...

## use_rcsparse: Use the rcsparse Python module to retrieve CVS

## repository information instead of invoking rcs utilities [EXPERIMENTAL]

##

use_rcsparse = 1

Dobbiamo ora copiare alcuni file e modificare le autorizzazioni per ViewVC.

5

Backup dispositivi di rete

cp /usr/local/viewvc-1.1.23/bin/cgi/*.cgi /var/www/cgi-bin

chmod +x /var/www/cgi-bin/*.cgi

chown apache:apache /var/www/cgi-bin/*.cgi

Per questo esempio useremo HTTP per ViewVC, anche se si potrebbe utilizzare HTTPS basta modificare il file conf di Apache (file HTTPD)

nano /etc/httpd/conf/httpd.conf

Inseriamo la seguente modifica alla fine del file HTTPD

# Custom Rancid Config

<VirtualHost *:80>

DocumentRoot /var/www

ScriptAlias /cgi-bin/ "/var/www/cgi-bin"

ScriptAlias /viewvc /var/www/cgi-bin/viewvc.cgi

ScriptAlias /query /var/www/cgi-bin/query.cgi

<Directory "/var/www/cgi-bin">

AllowOverride None

Options None

Order allow,deny

Allow from all

</Directory>

</VirtualHost>

Abbiamo quasi finito, ora abbiamo bisogno di accendere al database MariaDB che ViewVC utilizza come base di dati, avviamo l'installazione sicura. (Accetta tutti i valori di default e digitare una password di root per MariaDB.)

systemctl enable mariadb

systemctl start mariadb

6

Backup dispositivi di rete

sudo mysql_secure_installation

Accediamo a MariaDB per creare un utente per ViewVC. Per accedere al db utilizziamo la password che abbiamo appena creato.

mysql -u root -p

Digitiamo quanto segue:

CREATE USER 'VIEWVC'@'localhost' IDENTIFIED BY 'YourPasswordHere';

GRANT ALL PRIVILEGES ON *.* TO 'VIEWVC'@'localhost' WITH GRANT OPTION;

FLUSH PRIVILEGES;

quit

Inserire nel file conf del database di ViewVC il nome utente e la password che abbiamo appena creato. (Accettare le impostazioni predefinite)

/usr/local/viewvc-1.1.23/bin/make-database

MySQL Hostname (leave blank for default):

MySQL Port (leave blank for default):

MySQL User: VIEWVC

MySQL Password: YourPasswordHere

ViewVC Database Name [default: ViewVC]:

Database created successfully. Don't forget to configure the

[cvsdb] section of your viewvc.conf file.

Torniamo a logarci in MariaDB come utente root

mysql -u root -p

Creiamo ora un utente in sola lettura per ViewVC

CREATE USER 'VIEWVCRO'@'localhost' IDENTIFIED BY 'YourROPasswordHere';

GRANT SELECT ON ViewVC.* TO 'VIEWVCRO'@'localhost' WITH GRANT OPTION;

FLUSH PRIVILEGES;

7

Backup dispositivi di rete

quit

Ora dobbiamo configurare il file di configurazione ViewVC con i nomo utente e le password a che abbiamo creato in MySQL.

nano /usr/local/viewvc-1.1.23/viewvc.conf

Cerchiamo cvsdb e modificarlo come per il seguito:

##---------------------------------------------------------------------------

[cvsdb]

## enabled: Enable database integration feature.

##

enabled = 1

## host: Database hostname. Leave unset to use a local Unix socket

## connection.

##

host = localhost

## post: Database listening port.

##

port = 3306

## database_name: ViewVC database name.

##

database_name = ViewVC

8

Backup dispositivi di rete

## user: Username of user with read/write privileges to the database

## specified by the 'database_name' configuration option.

##

user = VIEWVC

## passwd: Password of user with read/write privileges to the database

## specified by the 'database_name' configuration option.

##

passwd = YourPasswordHere

## readonly_user: Username of user with read privileges to the database

## specified by the 'database_name' configuration option.

##

readonly_user = VIEWVCRO

## readonly_passwd: Password of user with read privileges to the database

## specified by the 'database_name' configuration option.

##

readonly_passwd = YourROPasswordHere

Eseguire il seguente comando per creare il database.

/usr/local/viewvc-1.1.23/bin/cvsdbadmin rebuild /usr/local/rancid/var/CVS/CVSROOT/

Riavviare il server una volta on-line si dovrebbe i repository:

http://rancid-servicer-ip/viewvc

9

Backup dispositivi di rete

Se vedete i gruppi che abbiamo creato, vuoldire che fino ad ora tutto è andato come previsto. Percompletare questa installazione abbiamo bisogno di configurare Rancid per inviare messaggi diposta elettronica. Di solito si deve aggiungere a Rancid all'elenco dei mittenti consentiti sullainfrastruttura di posta elettronica. Rancid utilizza alias per inviare e-mail che dobbiamoopportunamente modificare

nano /etc/aliases

A seconda della vostra infrastruttura si potrebbe avere diversi gruppi di persone per le diverseapparecchiature che rancid sta monitorando. In questo esempio stiamo usando un solo indirizzo e-mail abbiamo creato un nuovo alias chiamato Rancid tutto va inserito alla del file alias.

# Custom Rancid Configuration (write your email below)

rancid: [email protected]

# Custom Rancid Configuration

rancidi-Admin-router: rancido (questa e-mail invia tutti i messaggi di errore: ad esempio, lamacchina di rete non è possibile contattarla per più di 24 ore)

rancidi-router: rancido (questa e-mail invia tutte le modifiche fatte sul file di configurazionedella macchina di rete)

rancidi-Admin-Switch: rancido

rancid-admin-Switches: rancid

rancid-Switches: rancid

A seconda di ciò che si può creare un vostro elenco di gruppi nel file di configurazione di rancid. (Inquesto esempio abbiamo appena creato router e switch). Dobbiamo specificare questi nelle file di

10

Backup dispositivi di rete

alias altrimenti Rancid non invia e-mail per questi gruppi. Una volta che abbiamo finito l'editingdobbiamo aggiornare i nuovi alias appena creati. Digitare il seguente comando per aggiornare.

Newaliases

In questo esempio postfix è già installato e quindi abbiamo solo bisogno di modificare il file diconfigurazione di Postfix.

nano /etc/postfix/main.cf

Cerchiamo "relayhost" rimuoviamo il commento e digitare il nome di dominio (se si dispone di record MX) l'indirizzo FQDN o IP del sistema di posta elettronica.

relayhost = mail.test.com

#relayhost = mycompanydomain.com

#relayhost = email.mycompanydomain.com

#relayhost = [mailserver.isp.tld]

#relayhost = uucphost

#relayhost = [an.ip.add.ress]

Avviare postfix e abilitarlo all’avvio automatico

systemctl start postfix

systemctl enable postfix

L'installazione iniziale del software RANCID è ormai compiuta. Abbiamo appena installato Rancidinsieme ad apportato alcune modifiche utili come ottenere una pagina web in anticipo pervisualizzare le configurazioni invece di una CLI così come la creazione di Rancid per contattarcivia email se qualcosa cambia o se ci sono problemi con il collegamento a qualsiasi apparecchiatura.

Prima di configurare rancid, diciamo subito che esso non dispone al suo interno i moduli per gliswitch di H3C di “HP” qui viene mostrato come trovare i moduli necessari e come configurarerancid per usarli.

Trovare i moduli per H3C andiamo sul sito https://sites.google.com/site/jrbinks/code/rancid/h3c escarichiamoli, i link si trovano infondo, oppure copiateli da qui sotto.

File h3clogin

#! /usr/local/bin/expect --#### $Id: $##

11

Backup dispositivi di rete

## @PACKAGE@ @VERSION@## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc.## All rights reserved.#### This code is derived from software contributed to and maintained by## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan,## Pete Whiting, Austin Schutz, and Andrew Fort.#### Redistribution and use in source and binary forms, with or without## modification, are permitted provided that the following conditions## are met:## 1. Redistributions of source code must retain the above copyright## notice, this list of conditions and the following disclaimer.## 2. Redistributions in binary form must reproduce the above copyright## notice, this list of conditions and the following disclaimer in the## documentation and/or other materials provided with the distribution.## 3. All advertising materials mentioning features or use of this software## must display the following acknowledgement:## This product includes software developed by Terrapin Communications,## Inc. and its contributors for RANCID.## 4. Neither the name of Terrapin Communications, Inc. nor the names of its## contributors may be used to endorse or promote products derived from## this software without specific prior written permission.## 5. It is requested that non-binding fixes and modifications be contributed## back to Terrapin Communications, Inc.#### THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE## POSSIBILITY OF SUCH DAMAGE.## The expect login scripts were based on Erik Sherk's gwtn, by permission.

## h3clogin## h3clogin/h3crancid covers the following product ranges:## * 3Com SuperStack 4 (post-joint venture with Huawei)# * H3C# * HP Networking ('A' & some 'E' portfolio, post 2010 3Com acquitision)## They may also work with some Huawei equipment.## https://sites.google.com/site/jrbinks/code/rancid/h3c#

# Set to 1 to enable some debugging, or pass "-d" on command lineexp_internal 0

# Usage lineset usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \\[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \\[-r passphrase\] \[-s script-file\] \[-t timeout\] \[-u username\] \\[-v vty-password\] \[-w enable-username\] \[-x command-file\] \\[-y ssh_cypher_type\] router \[router...\]\n"

12

Backup dispositivi di rete

# env(CLOGIN) may contain:# x == do not set xterm banner or name

# Password fileset password_file $env(HOME)/.cloginrc# Default is to login to the routerset do_command 0set do_script 0# The default is to automatically enableset avenable 1# The default is that you login non-enabled (tacacs can have you login already# enabled)set avautoenable 0# The default is to look in the password file to find the passwords. This# tracks if we receive them on the command line.set do_passwd 1set do_enapasswd 1# Save config, if promptedset do_saveconfig 0# Sometimes routers take awhile to answer (the default is 10 sec)set timeoutdflt 45#set send_human {.1 .3 .7 .05 2}# spawn tty optionsset spawnopts {}

# H3C: set the platform# Platform switching:# If we explcitly want to state the platform, then set default_platform.# If we want the script to do magic to try and work it out, then set it# to "".# We might also consider passing the platform as a command-line parameter,# or by reading it as a hint from .cloginrc.set default_platform "h3c"

# H3C: some models don't like "3des"; specify "aes128-cbc" in .cloginrcset default_cyphertype "3des"

# H3C: most H3C-derived models use "super" to elevate privileges# However MA5600 uses "enable"set enacmd "super"set enacmd_alt "enable"

# H3C: command to exit from deviceset exitcmd "quit"

# Find the user in the ENV, or use the unix userid.if {[info exists env(CISCO_USER)]} { set default_user $env(CISCO_USER)} elseif {[info exists env(USER)]} { set default_user $env(USER)} elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME)} else { # This uses "id" which I think is portable. At least it has existed # (without options) on all machines/OSes I've been on recently - # unlike whoami or id -nu. if [catch {exec id} reason] {

send_error "\nError: could not exec id: $reason\n"exit 1

} regexp {\(([^)]*)} "$reason" junk default_user}if {[info exists env(CLOGINRC)]} {

13

Backup dispositivi di rete

set password_file $env(CLOGINRC)}

# Process the command linefor {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i]

switch -glob -- $arg {# Expect debug mode-d* { exp_internal 1# Username} -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} {

incr iset username [lindex $argv $i]

}# VTY Password} -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} {

incr iset userpasswd [lindex $argv $i]

} set do_passwd 0# ssh passphrase} -r* { if {! [regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [lindex $argv $i] }# VTY Password} -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} {

incr iset passwd [lindex $argv $i]

} set do_passwd 0# Version string} -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0# Enable Username} -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} {

incr iset enausername [lindex $argv $i]

}# Environment variable to pass to -s scripts} -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {

set E$varname $varvalue } else {

send_user "\nError: invalid format for -E in $arg\n"exit 1

}# Enable Password} -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} {

incr iset enapasswd [lindex $argv $i]

} set do_enapasswd 0# Command to run.} -c* {

14

Backup dispositivi di rete

if {! [regexp .\[cC\](.+) $arg ignore command]} {incr iset command [lindex $argv $i]

} set do_command 1# Expect script to run.} -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} {

incr iset sfile [lindex $argv $i]

} if { ! [file readable $sfile] } {

send_user "\nError: Can't read $sfile\n"exit 1

} set do_script 1# save config on exit} -S* { set do_saveconfig 1# 'ssh -c' cypher type} -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} {

incr iset cypher [lindex $argv $i]

}# alternate cloginrc file} -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} {

incr iset password_file [lindex $argv $i]

}# Timeout} -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} {

incr i set timeoutdflt [lindex $argv $i] }# Command file} -x* { if {! [regexp .\[xX\](.+) $arg ignore cmd_file]} {

incr iset cmd_file [lindex $argv $i]

} if [catch {set cmd_fd [open $cmd_file r]} reason] {

send_user "\nError: $reason\n"exit 1

} set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] set do_command 1# Do we enable?} -noenable { set avenable 0# Does tacacs automatically enable us?} -autoenable { set avautoenable 1 set avenable 0} -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1} default { break

15

Backup dispositivi di rete

} }}# Process routers...no routers listed is an error.if { $i == $argc } { send_user "\nError: $usage"}

# Only be quiet if we are running a script (it can log its output# on its own)if { $do_script } { log_user 0} else { log_user 1}

## Done configuration/variable setting. Now run with it...#

# Sets Xterm title if interactive...if its an xterm and the user caresproc label { host } { global env # if CLOGIN has an 'x' in it, don't set the xterm name/banner if [info exists env(CLOGIN)] {

if {[string first "x" $env(CLOGIN)] != -1} { return } } # take host from ENV(TERM) if [info exists env(TERM)] {

if [regexp \^(xterm|vs) $env(TERM) ignore] { send_user "\033]1;[lindex [split $host "."] 0]\a" send_user "\033]2;$host\a"}

}}

# This is a helper function to make the password file easier to# maintain. Using this the password file has the form:# add password sl* pete cow# add password at*steve# add password * hanky-pieproc add {var args} { global int_$var ; lappend int_$var $args}proc include {args} { global env regsub -all "(^{|}$)" $args {} args if { [regexp "^/" $args ignore] == 0 } {

set args $env(HOME)/$args } source_password_file $args}

proc find {var router} { upvar int_$var list if { [info exists list] } {

foreach line $list { if { [string match [lindex $line 0] $router] } {

return [lrange $line 1 end] }}

} return {}}

# Loads the password file. Note that as this file is tcl, and that

16

Backup dispositivi di rete

# it is sourced, the user better know what to put in there, as it# could install more than just password info... I will assume however,# that a "bad guy" could just as easy put such code in the clogin# script, so I will leave .cloginrc as just an extention of that scriptproc source_password_file { password_file } { global env if { ! [file exists $password_file] } {

send_user "\nError: password file ($password_file) does not exist\n"exit 1

} file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } {

send_user "\nError: $password_file must not be world readable/writable\n"exit 1

} if [catch {source $password_file} reason] {

send_user "\nError: $reason\n"exit 1

}}

# Log into the router.# returns: 0 on success, 1 on failure, -1 if rsh was used successfullyproc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script platform passphrase global prompt prompt_match u_prompt p_prompt e_prompt sshcmd spawnopts set in_proc 1 set uprompt_seen 0

# try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] {

incr progs -1if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd suffix port if {"$port" == ""} {

#set retval [catch {spawn telnet $router} reason]set cmd "telnet $router"

} else {#set retval [catch {spawn telnet $router $port} reason]set cmd "telnet $router $port"

} set retval [catch {eval spawn $spawnopts [split $cmd { }]} reason] if { $retval } {

send_user "\nError: telnet failed: $reason\n"return 1

}} elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} {

set cmd "$cmd -p $port" } if {"$identfile" != ""} {

set cmd "$cmd -i $identfile" } set retval [catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason] if { $retval } {

send_user "\nError: $cmd failed: $reason\n"return 1

}} elseif ![string compare $prog "rsh"] { if { ! $do_command } {

17

Backup dispositivi di rete

if { [llength $cmethod] == 1 } { send_user "\nError: rsh is an invalid method for -x and " send_user "interactive logins\n"}if { $progs == 0 } { return 1}continue;

}

set commands [split $command \;] set num_commands [llength $commands] set rshfail 0 for {set i 0} {$i < $num_commands && !$rshfail} { incr i} {

log_user 0set retval [catch {spawn rsh $user@$router [lindex $commands $i] } reason]if { $retval } { send_user "\nError: rsh failed: $reason\n" log_user 1; return 1}send_user "$router# [lindex $commands $i]\n"

# rcmd does not get a pager and no prompts, so we just have to# look for failures & lines.expect { "Connection refused" { catch {close}; catch {wait};

send_user "\nError: Connection\ Refused ($prog): $router\n"

set rshfail 1}

-re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; send_user "\nError: Connection\

closed ($prog): $router\n" set rshfail 1}

"Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable:\

$router\n" set rshfail 1}

"No address associated with" { catch {close}; catch {wait}; send_user "\nError: Unknown host\

$router\n" set rshfail 1}

-re "\b+" { exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)"

exp_continue}

timeout { catch {close}; catch {wait}; send_user "\nError: TIMEOUT reached\n" set rshfail 1}

eof { catch {close}; catch {wait}; }}log_user 1

} if { $rshfail } {

if { !$progs } { return 1} else { continue

18

Backup dispositivi di rete

} } # fake the end of the session for rancid. send_user "$router# exit\n" # return rsh "success" return -1} else { send_user "\nError: unknown connection method: $prog\n" return 1}sleep 0.3

# This helps cleanup each expect clause.expect_after { timeout {

send_user "\nError: TIMEOUT reached\n"catch {close}; catch {wait};if { $in_proc} { return 1} else { continue}

} eof {send_user "\nError: EOF received\n"catch {close}; catch {wait};if { $in_proc} { return 1} else { continue}

}}

# Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect {

-re "^<-+ More -+>\[^\n\r]*" { # ASA will use the pager for long banners send " "; exp_continue}-re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs {

send_user "\nError: Connection Refused ($prog): $router\n"return 1

}}-re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs {

send_user "\nError: Connection closed ($prog): $router\n"return 1

}}eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 }-nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait};

19

Backup dispositivi di rete

return 1}"Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1}"No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1}-re "(Host key not found |The authenticity of host .* be established).* \\(yes\/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue}-re "HOST IDENTIFICATION HAS CHANGED.* \\(yes\/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1}-re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1}-re "Offending key for .* \\(yes\/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1}-re "(denied|Sorry)" {

send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1}

"Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1}

-re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1}

"Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue}

-re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue}

-re "Last login:" { exp_continue}

-re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue

20

Backup dispositivi di rete

}-re "Enter passphrase.*: " {

# sleep briefly to allow time for stty -echo sleep .3 send -- "$passphrase\r" exp_continue}

-re "$u_prompt" { send -- "$user\r" set uprompt_seen 1 exp_continue}

-re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} {

send -- "$userpswd\r" } else {

send -- "$passwd\r" } exp_continue}

-re "$prompt" { set prompt_match $expect_out(0,string); break;}

"Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1}

} }

set in_proc 0 return 0}

# Enableproc do_enable { enauser enapasswd } { global do_saveconfig in_proc global prompt u_prompt e_prompt global enacmd enacmd_alt set in_proc 1

# Try and determine a bit more about this device to modify behaviour. # We are careful to use "dis version " rather than the full length # "display version" to prevent h3crancid matching it. # (Thx Andrea Gabellini) send -h "dis version\r" expect { -re "\{ .* \}:" { send -h -- "\r"; exp_continue } "VERSION : MA5600" { set enacmd $enacmd_alt; exp_continue } -re $prompt {} }

send -h "$enacmd\r" expect { -re "Please input the password to change the privilege level, press CTRL_C to abort.\n" { exp_continue }

-re "$u_prompt" { send -h -- "$enauser\r"; exp_continue }-re "$e_prompt" { send -h -- "$enapasswd\r"; exp_continue }-re ">" { set prompt ">" }-re "#" { set prompt "#" } # MA5600"% Password is not set." { # H3C

21

Backup dispositivi di rete

send_user "\nError: No 'super' password set for device\n" return 1}

"% Authenticate failed." { # H3C send_user "\nError: Check your enable password for 'super'\n" return 1}

# ciscoisms:# "#" { set prompt "#" }# "(enable)" { set prompt "> \\(enable\\) " }# -re "(denied|Sorry|Incorrect)" {# # % Access denied - from local auth and poss. others# send_user "\nError: Check your Enable passwd\n";# return 1# }# "% Error in authentication" {# send_user "\nError: Check your Enable passwd\n"# return 1# }# "% Bad passwords" {# send_user "\nError: Check your Enable passwd\n"# return 1# } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0}

# Run commands given on the command line.proc run_commands { prompt command } { global do_saveconfig in_proc platform global exitcmd set in_proc 1

# clogin has this beast: #regsub -all {^(.{1,11}).*([#>])$} $prompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt # If platform H3C: # Note that if the "system-view" command is sent to go into configuration # mode, the prompt changes from <prompt> to [prompt], so we need to ensure # that $reprompt will handle either. send_user -- "Prompt: $prompt\n" # Strip inital and leading <> regsub -all {^<} $prompt {} prompt regsub -all {>\a?$} $prompt {} prompt #send_user -- "Prompt: $prompt\n" # Escape special characters to be treated as literals regsub -all {[][)(]} $prompt {\\&} prompt # Prefix and suffix with regexps to match the sets <[ and ]> set xlist [list {[<[]} $prompt {.*[]>]\a?}] set reprompt [join $xlist ""] send_user -- "REPrompt: $reprompt\n"

expect { -re ($reprompt|$prompt) { } -re "\[\n\r]+" { exp_continue } }

# this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0

set commands [split $command \;]

22

Backup dispositivi di rete

set num_commands [llength $commands] # The pager can not be turned off on some 3Com/H3C, so we have to look # for the "More" prompt. for {set i 0} {$i < $num_commands} { incr i} {

send -- "[subst -nocommands [lindex $commands $i]]\r"expect {

-re "\b+" { exp_continue }-re "^\[^\n\r *]*($reprompt|$prompt)" { send_user -- "$expect_out(buffer)"

}-re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)"

exp_continue }-re "\[\n\r]+" { send_user -- "$expect_out(buffer)"

exp_continue }-re "^ {0,2}-+ More .*-+.*\[^\n\r]*" {

# H3C pager prompt sleep 0.1 send " " exp_continue }

-re "^---- More ----\[^\n\r]*" { # Comware7 pager prompt sleep 0.1 send " " exp_continue }

}}

# clogin has introduced this change to the "\[\n\r]+" clause above in r2313# June2011:# "trying to make sure it pulls full lines each time."# -re "\[^\r\n]*\[\n\r]+"

log_user 1

send -h "$exitcmd\r"

expect {# -re "^\[^\n\r *]*$reprompt" {# # H3C:# # they return to non-enabled# # mode with "exit" from# # enabled mode.# send -h "$exitcmd\r"# exp_continue;# }# TODO: we will need to do this too:# "Do you wish to save your configuration changes" {# send -h "n\r"# exp_continue# }

-re "\[\n\r]+" { exp_continue }# variant from hwlogin:

-re "\[^\n\r *]Note:" { return 0 }timeout { catch {close}; catch {wait};

return 0}

eof { return 0 } } set in_proc 0}

## For each router... (this is main loop)#source_password_file $password_fileset in_proc 0

23

Backup dispositivi di rete

set exitval 0set prompt_match ""set enable 0# if we have dont have a tty, we need some additional terminal settingsif [catch {stty} reason] { # no tty, ie: cron set spawnopts "-nottycopy" set stty_init "cols 132"}foreach router [lrange $argv $i end] { set router [string tolower $router] # attempt at platform switching. set platform "" send_user -- "$router\n"

# device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt }

# Default prompt. #set prompt "(>|#| \\(enable\\))" # H3C: Could we be logged in already in a privilged ("super") mode, # with the "[....]" prompt? If so, then this might be: #set prompt "(>|])\a?" set prompt ">\a?"

# look for noenable option in .cloginrc if { [find noenable $router] == "1" } {

set enable 0 }

# Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } {

send_user -- "\nError: no password for $router in $password_file.\n"continue

} if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {

send_user -- "\nError: no enable password for $router in $password_file.\n"continue

} set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else {

set passwd $userpasswdset enapasswd $enapasswd

}

# Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [find user $router] ""] if { "$ruser" == "" } { set ruser $default_user } }

# Figure out username's password (if different from the vty password) if {[info exists userpasswd]} { # command line username set userpswd $userpasswd

24

Backup dispositivi di rete

} else { set userpswd [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } }

# Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } }

# Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } {

set u_prompt "(Username|Login|login|user name|User|User name):" } else {

set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } {

set p_prompt "(\[Pp]assword|passwd|Enter password for \[^ :]+):" } else {

set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } {

set e_prompt "\[Pp]assword:" } else {

set e_prompt [join [lindex $e_prompt 0] ""] }

# Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""]

# Figure out passphrase to use if {[info exists avpassphrase]} {

set passphrase $avpassphrase } else {

set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} {

set passphrase $passwd }

# Figure out cypher type if {[info exists cypher]} {

# command line cypher typeset cyphertype $cypher

} else {set cyphertype [find cyphertype $router]if { "$cyphertype" == "" } { set cyphertype "$default_cyphertype" }

}

# Figure out connection method set cmethod [find method $router] if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }

# Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} }

25

Backup dispositivi di rete

# Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} {

incr exitval# if login failed or rsh was unsuccessful, move on to the next devicecontinue

} # Figure out the prompt. # H3C: this is what we used to have, now should be obsolete:# # Since autoenable is off by default, if we have it defined, it# # was done on the command line. If it is not specifically set on the# # command line, check the password file.# if $avautoenable {# set autoenable 1# set enable 0## hwlogin:# #set prompt "(#| \\(enable\\))"# set prompt ">\a?"# } else {# set ae [find autoenable $router]# if { "$ae" == "1" } {# set autoenable 1# set enable 0## hwlogin:# set prompt ">\a?"# } else {# set autoenable 0# set enable $avenable# set prompt ">\a?"# }# }## # look for noenable option in .cloginrc# if { [find noenable $router] == "1" } {# set enable 0# }## clogin has:## # look for noenable option in .cloginrc## if | [find noenable $router] != "" | {## set enable 0## }

# !! H3C does not appear to have a different prompt between lower # privilege and higher privilege users, so the following test is # not applicable# if { [regexp -- "(#| \\(enable\\))" $prompt_match junk] == 1 } {# set enable 0# } else {

if { $avenable == 0 } { set enable 0} else { set ne [find noenable $router] set ae [find autoenable $router] if { "$ne" == "1" || "$ae" == "1" || $avautoenable } {

set enable 0 } else {

set enable 1 }}

# }

# Disable smart and interactive before send others commands # (MA5600) send -h "undo smart\r" expect -re $prompt {}

26

Backup dispositivi di rete

send -h "undo interactive\r" expect -re $prompt {}

if { $enable } {if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } {

incr exitvalcatch {close}; catch {wait};continue

}}

} # we are logged in, now figure out the full prompt send "\r" expect {

-re "\[\r\n]+" { exp_continue; }-re "^.+$prompt" { set junk $expect_out(0,string);

regsub -all "\[\]\[\(\)]" $junk {\\&} prompt;}

}

# H3C: # Disable log junk being sent to terminal: must be done before $enacmd # is run. It would be nice for this to be setable in .cloginrc send -h "undo terminal monitor\r" expect -re $prompt {}

# Turn session paging off # Comware 5 only. # Comware 3 models have a screen-length command that only works on # a vty basis # clogin does this only within the do_script clause below, but I can't # see why you wouldn't want it here, covering do_command too send -h "screen-length disable\r" #expect -re $prompt {}

if { $do_command } {if {[run_commands $prompt $command]} { incr exitval continue}

} elseif { $do_script } {expect -re $prompt {}source $sfilecatch {close};

} else {label $routerlog_user 1interact

}

# End of for each router catch {wait}; sleep 0.3}exit $exitval

Il seguente script deve essere posizionato in /usr/local/rancid/bin, modificare la prima riga da/usr/local/bin/expect - - a /usr/local/rancid/expect - - ora diamo i permessi necessari al file un belchmod 755 h3clogin e poi un chown rancid:netadm h3clogin

27

Backup dispositivi di rete

File h3crancid

#! /usr/bin/perl5#### $Id: $#### @PACKAGE@ @VERSION@## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc.## All rights reserved.#### This code is derived from software contributed to and maintained by## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan,## Pete Whiting, Austin Schutz, and Andrew Fort.#### Redistribution and use in source and binary forms, with or without## modification, are permitted provided that the following conditions## are met:## 1. Redistributions of source code must retain the above copyright## notice, this list of conditions and the following disclaimer.## 2. Redistributions in binary form must reproduce the above copyright## notice, this list of conditions and the following disclaimer in the## documentation and/or other materials provided with the distribution.## 3. All advertising materials mentioning features or use of this software## must display the following acknowledgement:## This product includes software developed by Terrapin Communications,## Inc. and its contributors for RANCID.## 4. Neither the name of Terrapin Communications, Inc. nor the names of its## contributors may be used to endorse or promote products derived from## this software without specific prior written permission.## 5. It is requested that non-binding fixes and modifications be contributed## back to Terrapin Communications, Inc.#### THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE## POSSIBILITY OF SUCH DAMAGE.## RANCID - Really Awesome New Cisco confIg Differ#

# h3crancid## h3clogin/h3crancid covers the following product ranges:## * 3Com SuperStack 4 (from 'joint venture' with Huawei)# * H3C# * HP Networking ('A' & some 'E' portfolio, post-2010 3Com acquitision)## They may also work with some Huawei equipment.## https://sites.google.com/site/jrbinks/code/rancid/h3c

## Usage: h3crancid [-dltCV] [-f filename | hostname]#

# You can modify the behaviour by changing the variables listed in

28

Backup dispositivi di rete

# 'END-USER TWEAKS', below.

# Notable changes from standard *rancid programs:## * abstracted path to the 'tail' utility# * altered "cisco_cmds" to be "device_cmds"# * define and use $logincmd# * abstracted $rancid_type

# TODO:## It may be useful to pull common subroutines like the sorting ones into# a library for use by all the *rancid programs.## abstract the comment-out char (i.e., '!' here and cisco, '#' on Juniper)# to a variable.

# NOTES:# # * the dir commands need a user greater than at least level 1 on some# platforms

############################################################################# END-USER TWEAKS

# The login program to use. If no path is given, $PATH is searched:my $logincmd = "h3clogin";#my $logincmd = "/usr/local/libexec/h3clogin";#my $TAIL = "/usr/bin/tail";## Enable display of the FIB:my $display_fib = 1;## Enable display of the routing table:my $display_iproutes = 1;## Enable display of the vlans:my $display_vlan_all = 1;## Enable display of STP root:my $display_stproot = 1;## Enable display of transceiver interface:my $display_xcvr_int = 0;

# END OF END-USER TWEAKS#############################################################################

my $rancid_type = 'h3c';

use Getopt::Std;getopts('dflt:CV');if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0);}$log = $opt_l;$debug = $opt_d;$file = $opt_f;$host = $ARGV[0];$clean_run = 0;$found_end = 0;#$timeo = 90; # login command timeout in seconds

29

Backup dispositivi di rete

$timeo = 20; # login command timeout in seconds

my(@commandtable, %commands, @commands);# command listsmy($aclsort) = ("ipsort"); # ACL sorting modemy($filter_commstr); # SNMP community string filteringmy($filter_pwds); # password filtering mode

# This routine is used to print out the router configurationsub ProcessHistory { my($new_hist_tag,$new_command,$command_string,@string)=(@_); if((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) && scalar %history) { print eval "$command \%history"; undef %history; } if (($new_hist_tag) && ($new_command) && ($command_string)) { if ($history{$command_string}) { $history{$command_string} = "$history{$command_string}@string"; } else { $history{$command_string} = "@string"; } } elsif (($new_hist_tag) && ($new_command)) { $history{++$#history} = "@string"; } else { print "@string"; } $hist_tag = $new_hist_tag; $command = $new_command; 1;}

sub numerically { $a <=> $b; }

# This is a sort routine that will sort numerically on the# keys of a hash as if it were a normal array.sub keynsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $key (sort numerically keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines;}

# This is a sort routine that will sort on the# keys of a hash as if it were a normal array.sub keysort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $key (sort keys(%lines)) { $sorted_lines[$i] = $lines{$key}; $i++; } @sorted_lines;}

# This is a sort routine that will sort on the# values of a hash as if it were a normal array.sub valsort{ local(%lines)=@_; local($i) = 0;

30

Backup dispositivi di rete

local(@sorted_lines); foreach $key (sort values %lines) { $sorted_lines[$i] = $key; $i++; } @sorted_lines;}

# This is a numerical sort routine (ascending).sub numsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $num (sort {$a <=> $b} keys %lines) { $sorted_lines[$i] = $lines{$num}; $i++; } @sorted_lines;}

# This is a sort routine that will sort on the# ip address when the ip address is anywhere in# the strings.sub ipsort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $addr (sort sortbyipaddr keys %lines) { $sorted_lines[$i] = $lines{$addr}; $i++; } @sorted_lines;}

# These two routines will sort based upon IP addressessub ipaddrval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); $a[3] + 256 * ($a[2] + 256 * ($a[1] + 256 * $a[0]));}sub sortbyipaddr { &ipaddrval($a) <=> &ipaddrval($b);}

# This is a sort routine that will sort on the# ip route when the ip route is anywhere in# the strings.sub iproutesort { local(%lines)=@_; local($i) = 0; local(@sorted_lines); foreach $iproute (sort sortbyiproute keys %lines) { $sorted_lines[$i] = $lines{$iproute}; $i++; } @sorted_lines;}

# These two routines will sort based upon IP routesub iprouteval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)$#); $a[4] + ($a[3] + 256 * ($a[2] + 256 * ($a[1] + 256 * $a[0])));}sub sortbyiproute { &iprouteval($a) <=> &iprouteval($b);

31

Backup dispositivi di rete

}

sub filter_lines { my ($l) = (@_);

# Filter out some ANSI crud as a result of us not being able to turn # off per-session terminal paging: #s/^\033\[42D +\033\[42D(.+)$/$1/; # hwlogin+mods: #s/\033\133\064\062\104\s*\033\133\064\062\104//g; $l =~ s/\033\133\064\062\104\s+\033\133\064\062\104//g; $l =~ s/\033\133\061\066\104\s+\033\133\061\066\104//g; $l =~ s/\033\133\064\062\104//g; $l =~ s/\033\133\061\062\104//g; $l =~ s/.*\[37D(.*)/$1/g; # MA5600 # Probably not needed: $l =~ s/\s*---- More ----\s*//; $l =~ s/^ //; # Comware7 $l =~ s/Synchronization is finished.//g; return $l;}

sub DisplayFib {

print STDERR " In DisplayFib: $_" if ($debug);

chomp;

# Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; ProcessHistory("FIB","","","!\n! '$cmd':\n!\n");

while (<INPUT>) { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ );

next if /^$/; next if /^Destination count: \d+ FIB entry count: \d+/;

# Chop out some detail that changes over time (Comware 3): s/(\s+)TimeStamp\s+/$1/; # TimeStamp column heading

ProcessHistory("FIB","","","! $_\n");

if ( m,Destination/Mask, ) { while (<INPUT>) { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_);

# Chop out some detail that changes over time (Comware 3): s/(\s+)t\[\d+\]\s+/$1/; # TimeStamp data

32

Backup dispositivi di rete

# "display fib" on comware7 shows host entries for things # learned via arp too. For a distribution router, that's all # the devices on subnets routed by it! # If we filter out all "UH" entries that are NOT InLoop, we # get acceptable output. # # So we want to keep: # # 0.0.0.0/32 127.0.0.1 UH InLoop0 Null # # but reject: # # 130.159.44.161/32 130.159.44.161 UH Vlan44 Null # # However I've a feeling that this is a problematic # solution, and some object to the notion that rancid # should be representing such potentially dynamic data in # the first place, which is why we created the # $display_fib flag.

($dest, $nexthop, $flag, $outint, $label) = split; next if ( $flag eq 'UH' && $outint !~ /InLoop/ ); ProcessHistory("FIB", "iproutesort", "$dest", "! $_\n"); }

ProcessHistory("FIB", "", "", "!\n");

# return here to ensure that we don't keep swallowing the # next command's output by returning to the surrounding # while loop return(0); } } return(0);}

sub DisplayIPRoutes { print STDERR " In DisplayIPRoutes: $_" if ($debug);

chomp;

# Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; ProcessHistory("IPR","","","!\n! '$cmd':\n!\n");

while (<INPUT>) { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_); return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ );

ProcessHistory("IPR","","","! $_\n");

if ( m,Destination/Mask, ) { my $lastkey = ""; my $lastspaces = "";

33

Backup dispositivi di rete

while (<INPUT>) { tr/\015//d; last if(/^\s*$prompt/); chomp; $_ = filter_lines($_);

# If the key is blank, indicating multiple nexthops for # a particular route, then we use the previous one if ( m/^\s+(.+)/ ) { $key = $lastkey; $line = $key . $lastspaces . $1; ProcessHistory("IPR", "iproutesort", "$key", "! $line\n"); # $lastkey and $lastspaces are retained in case # they are needed for an additional line } if ( m/^(\S+)(\s+).+/ ) { $key = $1; $line = $_; $spaces = $2; ProcessHistory("IPR", "iproutesort", "$key", "! $line\n"); $lastkey = $key; $lastspaces = $spaces; } }

# This isn't quite right; for example, it messes up oddities like this:# ...# 130.159.2.84/30 OSPF 10 1010 10.159.2.53 Vlan3660# 130.159.2.88/30 OSPF 10 1100 10.159.2.53 Vlan3660# OSPF 10 1100 10.159.2.49 Vlan3661# 130.159.2.92/30 OSPF 10 1015 10.159.2.53 Vlan3660# ...

ProcessHistory("IPR", "", "", "!\n");

# return here to ensure that we don't keep swallowing the # next command's output by returning to the surrounding # while loop return(0); } } return(0);}

#sub DisplayTransInt {# print STDERR " In DisplayTransInt: $_" if ($debug);## chomp;## # Display the command we're processing in the output:# s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g;# ProcessHistory("TRINT","","","! $_\n!\n");## while (<INPUT>) {# tr/\015//d;# last if(/^\s*$prompt/);# chomp;# $_ = filter_lines($_);# return(1) if (# /^\s+\^$/ ||# /% Too many parameters found at '\^' position/ ||# /% Unrecognized command found at '\^' position/ ||# /(% )?Wrong parameter found at '\^' position/ ||# /% Wrong device .+/ ||

34

Backup dispositivi di rete

# /Permission denied\./# );### ProcessHistory("TRINT","","","! $_\n");# }# ProcessHistory("TRINT","","","!\n");# return(0);#}

#sub DisplayNTPStatus {# print STDERR " In DisplayNTPStatus: $_" if ($debug);## chomp;## # Display the command we're processing in the output:# s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g;# ProcessHistory("NTP","","","! $_\n!\n");## while (<INPUT>) {# tr/\015//d;# last if(/^\s*$prompt/);# chomp;# $_ = filter_lines($_);# return(1) if (# /^\s+\^$/ ||# /% Too many parameters found at '\^' position/ ||# /% Unrecognized command found at '\^' position/ ||# /(% ?)Wrong parameter found at '\^' position/ ||# /% Wrong device .+/ ||# /Permission denied\./# );## next unless m/(Clock status|Clock stratum|Reference clock ID)/;## ProcessHistory("NTP","","","! $_\n");# }# ProcessHistory("NTP","","","!\n");# return(0);#}

## This routine processes general output of "display" commandssub CommentOutput { print STDERR " In CommentOutput: $_" if ($debug);

chomp;

# Display the command we're processing in the output: #s/^[\[<].*?[\]>]\a?\s?(.*)/\'$1\':/g; #ProcessHistory("COMMENTS", "", "", "! $_\n!\n"); #(my $cmd = $_) =~ s/^[\[<].*?[\]>]\a?\s?(.*)/$1/g; ProcessHistory("COMMENTS", "", "", "!\n! '$cmd':\n!\n");

while (<INPUT>) { tr/\015//d;

# If we find the prompt, we're done # Ordinarily this matches from the start of the line, however # we've seen circumstances at least in Comware7 where the # prompt is preceded by whitespace, like so: # ^M^M ^M<router>display boot-loader^M last if(/^\s*$prompt/); chomp;

35

Backup dispositivi di rete

# filter out some junk $_ = filter_lines($_);

# Some commands are not supported on some models or versions # of code. These lines simply remove the associated error # messages: return(1) if ( /^\s+\^$/ || /% Too many parameters found at '\^' position/ || /% Unrecognized command found at '\^' position/ || /(% )?Wrong parameter found at '\^' position/ || /% Wrong device .+/ || /Permission denied\./ );

# Now we skip or modify some lines from various commands to # remove irrelevant content, or to avoid insignificant diffs

# 'display local-user': s/\s+Current AccessNum:.+$//;

# 'display version': next if (/^(Uptime is \d|.+ [Uu]ptime is \d).+$/); # No longer necessary since skipping the whole Uptime line: # Mangle these lines: #s/(.*)[Uu]ptime.*.weeks.*.days*.*hours*.*minutes*(.*)/$1 $2/; #s/(.*)[Uu]ptime.*days*.*hours*.*minutes*(.*)/$1 $2/;

# MSRs display a 'last reboot' time, but sometimes the seconds # vary by one or two (presumably internal rounding), so simply make # the last digit a fixed '0'. It would probably be safer to make # the last two digits a fixed '00'. # (Thx Alexander Belokopytov) s/(^Last reboot.+)\d$/${1}0/;

# 'dir ' commands if ( $cmd =~ /^dir / ) { # First field is just an index number, chop it out s/^\s+\d+\s+(.+)/ $1/; # Remove filenames that are updated frequently next if ( /logfile\.log$/ || /lauth\.dat$/ || /ifindex\.dat$/ || /startup\.mdb$/ || /private-data\.txt$/ || /.+ KB total \(.+ KB free/ || /.+ KB total \(.+ KB free/ || /\.trash/ ); }

# 'display ospf brief'/'display ospf' if ( $cmd =~ 'display ospf( brief)?' ) { #next if (/^(Ospf is not enabled yet|Info: OSPF routing process is not enabled|The feature OSPF has not been enabled.).+$/); next if (/^\s+SPF (Computation|Scheduled|calculation) Count:.+$/i); }

if ( $cmd eq 'display power' ) { next if (/^(\s+Input Power).+$/); }

if ( $cmd eq 'display poe powersupply' ) { next if (/^(PSE Total Power Consumption|PSE Available Power|PSE Peak Value|PSE Average Value).+$/);

36

Backup dispositivi di rete

}

if ( $cmd eq 'display ntp-service status' ) { next unless m/(Clock status|Clock stratum|Reference clock ID)/i; }

if ( $cmd eq 'display transceiver interface' ) { s/^(\S+ transceiver information:).+$/$1/; # filter random garbage s/^Error: The transceiver is absent.$/ No transceiver present./; s/^Error: The combo port is inactive.$/ Inactive combo port./; }

# Add the processed lines to the output buffer: ProcessHistory("COMMENTS","","","! $_\n"); }

# Add a blank comment line to the output buffer ProcessHistory("COMMENTS", "", "", "!\n"); return(0);}

## This routine processes a "display current"sub DisplayCurrent { print STDERR " In DisplayCurrent: $_" if ($debug);

# We aren't chomping these lines

while (<INPUT>) { tr/\015//d; last if(/^\s*$prompt/);

$_ = filter_lines($_); return(0) if ($found_end);

# Filter out some sensitive data: if ( $filter_commstr && /^ ?(snmp-agent (usm-user|community (read|write)) )(\S+)/ ) { ProcessHistory("","","","! $1<removed>$'"); next; } if ( $filter_pwds >= 1 && /^ ?(password (?:simple|cipher) )(\S+)/ || /^ ?(super password( level \d)? (cipher|simple)) (\S+)/ || /^ ?(set authentication password (cipher|simple)) (\S+)/ || /^ ?(key (?:authentication|accounting) )(\S+)/ ) { ProcessHistory("","","","! $1<removed>$'"); next; }

# Filter mac addresses dynamically added to confignext if (/^ ?mac-address security.+$/);

ProcessHistory("", "", "", "$_");

# end of config

if (/^return/) { $found_end = 1; return(0); } } return(0);

37

Backup dispositivi di rete

}

# dummy functionsub DoNothing {print STDOUT;}

# Main## Not all commands are supported on all models and code versions## Not all of these should necessarily be included@commandtable = (# Commands relating to the operating system/version: {'display version' => 'CommentOutput'}, {'display boot-loader' => 'CommentOutput'}, {'display startup' => 'CommentOutput'}, {'dir /all' => 'CommentOutput'}, {'dir /all unit2>flash:/' => 'CommentOutput'}, {'dir /all slot2#flash:/' => 'CommentOutput'}, {'dir /all unit3>flash:/' => 'CommentOutput'}, {'dir /all slot3#flash:/' => 'CommentOutput'}, {'dir /all unit4>flash:/' => 'CommentOutput'}, {'dir /all slot4#flash:/' => 'CommentOutput'}, {'dir /all unit5>flash:/' => 'CommentOutput'}, {'dir /all slot5#flash:/' => 'CommentOutput'}, {'dir /all unit6>flash:/' => 'CommentOutput'}, {'dir /all slot6#flash:/' => 'CommentOutput'}, {'dir /all unit7>flash:/' => 'CommentOutput'}, {'dir /all slot7#flash:/' => 'CommentOutput'}, {'dir /all unit8>flash:/' => 'CommentOutput'}, {'dir /all slot8#flash:/' => 'CommentOutput'},# Commands relating to the hardware: {'display device' => 'CommentOutput'}, {'display device manuinfo' => 'CommentOutput'}, {'display fan' => 'CommentOutput'}, {'display power' => 'CommentOutput'}, {'display poe powersupply' => 'CommentOutput'}, {'display poe temperature-protection' => 'CommentOutput'}, {'display transceiver interface' => 'CommentOutput'},# Commands relating to authentication: {'display cluster' => 'CommentOutput'}, {'display domain' => 'CommentOutput'}, {'display local-user' => 'CommentOutput'}, {'display password-control' => 'CommentOutput'}, {'display password-control super' => 'CommentOutput'}, {'display ssh server status' => 'CommentOutput'},# Commands relating to system state: {'display irf' => 'CommentOutput'}, {'display xrn-fabric' => 'CommentOutput'}, {'display ftm topology-database' => 'CommentOutput'}, {'display fib' => 'DisplayFib'}, {'display ip routing-table' => 'DisplayIPRoutes'}, {'display ospf' => 'CommentOutput'}, {'display ospf brief' => 'CommentOutput'}, {'display vlan all' => 'CommentOutput'}, {'display lacp sys' => 'CommentOutput'}, {'display link-aggregation summary' => 'CommentOutput'}, {'display link-aggregation verbose' => 'CommentOutput'}, {'display mirror all' => 'CommentOutput'}, {'display ntp-service status' => 'CommentOutput'}, {'display stp root' => 'CommentOutput'},# And the system config itself: {'display current-configuration' => 'DisplayCurrent'},);

# Remove some commands from the comman table if the user has toggled the# options not to execute them

38

Backup dispositivi di rete

if ($display_fib == 0) { grep(delete $$_{'display fib'} , @commandtable) };if ($display_iproutes == 0) { grep(delete $$_{'display ip routing-table'} , @commandtable) };if ($display_vlan_all == 0) { grep(delete $$_{'display vlan all'} , @commandtable) };if ($display_stproot == 0) { grep(delete $$_{'display stp root'} , @commandtable) };if ($display_xcvr_int == 0) { grep(delete $$_{'display transceiver interface'} , @commandtable) };

# Use an array to preserve the order of the commands and a hash for mapping# commands to the subroutine and track commands that have been completed.@commands = map(keys(%$_), @commandtable);%commands = map(%$_, @commandtable);$commandcnt = scalar(keys %commands);

$device_cmds=join(";",@commands);$cmds_regexp=join("|", map quotemeta($_), @commands);

if (length($host) == 0) { if ($file) { print(STDERR "Too few arguments: file name required\n"); exit(1); } else { print(STDERR "Too few arguments: host name required\n"); exit(1); }}if ($opt_C) { print "$logincmd -t $timeo -c\'$commandstr\' $host\n"; exit(0);}open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";select(OUTPUT);# make OUTPUT unbuffered if debuggingif ($debug) { $| = 1; }

if ($file) { print STDERR "opening file $host\n" if ($debug); print STDOUT "opening file $host\n" if ($log); open(INPUT,"<$host") || die "open failed for $host: $!\n";} else { print STDERR "executing $logincmd -t $timeo -c\"$device_cmds\" $host\n" if ($debug); print STDOUT "executing $logincmd -t $timeo -c\"$device_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) {# system "$logincmd -noenable -t $timeo -c \"$device_cmds\" $host </dev/null > $host.raw 2>&1" || die "$logincmd failedfor $host: $!\n";# system "$logincmd -t $timeo -c \"$device_cmds\" $host </dev/null > $host.raw 2>&1" || die "$logincmd failed for $host: $!\n"; system "$logincmd -t $timeo -c \"$device_cmds\" $host </dev/null > $host.raw 2>&1" || die "$logincmd failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "$logincmd failed for $host: $!\n"; } else {# open(INPUT,"$logincmd -noenable -t $timeo -c \"$device_cmds\" $host </dev/null |") || die "$logincmd failed for $host:$!\n"; open(INPUT,"$logincmd -t $timeo -c \"$device_cmds\" $host </dev/null |") || die "$logincmd failed for $host: $!\n"; }}

# determine ACL sorting modeif ($ENV{"ACLSORT"} =~ /no/i) { $aclsort = "";}# determine community string filtering modeif (defined($ENV{"NOCOMMSTR"}) &&

39

Backup dispositivi di rete

($ENV{"NOCOMMSTR"} =~ /yes/i || $ENV{"NOCOMMSTR"} =~ /^$/)) { $filter_commstr = 1;} else { $filter_commstr = 0;}# determine password filtering modeif ($ENV{"FILTER_PWDS"} =~ /no/i) { $filter_pwds = 0;} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) { $filter_pwds = 2;} else { $filter_pwds = 1;}

ProcessHistory("","","","!RANCID-CONTENT-TYPE: $rancid_type\n!\n");#ProcessHistory("COMMENTS","keysort","B0","!\n");#ProcessHistory("COMMENTS","keysort","D0","!\n");#ProcessHistory("COMMENTS","keysort","F0","!\n");#ProcessHistory("COMMENTS","keysort","G0","!\n");TOP: while(<INPUT>) { tr/\015//d;# h3c:# Look for the command at the end of the output# if (/\#exit$/) {# if (/\#quit$/) {# h3c: if (/[\]>#]\a?\s*quit/) {# if (/^[\[<].*[\]>]\a?\s?quit/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host $logincmd error: $_"); print STDERR ("$host $logincmd error: $_") if ($debug); $clean_run=0; last; }# while (/#\s*($cmds_regexp)\s*$/) {# h3c: while (/[\]>#]\a?\s*($cmds_regexp)\s*$/) {# while (/^[\[<].*[\]>]\a?\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { # h3c: # Extract the prompt: look for something not [ or < at the start # of the line, until either ] or > or # is reached: #$prompt = ($_ =~ /^([^#]+#)/)[0]; #$prompt =~ s/([][}{)(\\])/\\$1/g; #$prompt = ($_ =~ /^([^\]>]+[\]>]\007?)/)[0]; $prompt = ($_ =~ /^([^\]>#]+[\]>]\a?)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g;

print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); }

print STDERR ("HIT COMMAND:$_") if ($debug); if (! defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; $clean_run = 0; last TOP; } $rval = &{$commands{$cmd}}(*INPUT, *OUTPUT, $cmd); delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0;

40

Backup dispositivi di rete

last TOP; } }}print STDOUT "Done $logincmd: $_\n" if ($log);# Flush HistoryProcessHistory("","","","");# Cleanupclose(INPUT);close(OUTPUT);

if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug);}

printf(STDOUT "$host: clean_run=$clean_run found_end=$found_end\n") if ($debug);

# check for completenessif (scalar(%commands) || !$clean_run || !$found_end) { if (scalar(keys %commands) eq $commandcnt) { printf(STDERR "$host: missed cmd(s): all commands\n"); } elsif (scalar(%commands)) { printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands))); printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug); } if (!$clean_run || !$found_end) { print STDOUT "$host: End of run not found\n"; print STDERR "$host: End of run not found\n" if ($debug); system("$TAIL -1 $host.new"); } unlink "$host.new" if (! $debug);}

Anche in questo script deve essere posizionato in /usr/local/rancid/bin, modificare la prima rigada /usr/bin/perl5 a /usr/bin/perl ora diamo i permessi necessari al file un bel chmod 755 h3crancide poi un chown rancid:netadm h3crancid.

Ora possiamo utilizzare nei file di configurazione h3c per gli switch di HP “H3C”.

Configurare Rancid

Rancid ha un paio di zone che devono essere modificate per farlo funzionare, la prima area latroviamo all'interno di ogni repository creato è il file router.db. Nel nostro esempio abbiamo igruppi router e switch. All'interno di router.db possiamo inserire i nostri dispositivi o usando ilnome DNS o l'indirizzo IP eccone di seguito un esempio:

Per accedere al file router.db di ogni device creato, il path è il seguente /usr/local/rancid/var/tipo didevice/router.db:

nano /usr/local/rancid/var/switch/router.db

aprendo il file esso ci risulta vuoto, seguiamo questo esempio per inserire i parametri del device, quicome esempio abbiamo un cisco:

# This is an example of a router.db fle in Rancid.

41

Backup dispositivi di rete

# Location of File /usr/local/rancid/var/Routers/router.db

# Type the Router name or IP followed by the type of device. (Rancid supports more than justCisco)

# Personally I think it looks better with DNS names.

Router01.example.com;cisco;up; (qui usiamo il DNS)

# You can also mark a device as down. This will cause Rancid to skip it.

192.168.0.1;cisco;up (qui invece l'IP)

Router03.example.com;cisco;up;

# Of course you can also comments throughout this file or alongside devices for notes.

# Edge Switches for Computers at HQ

Switch-HQ-Edge14.example.com;cisco;up; LOCATION: Server Rack A

Switch-HQ-Edge07.example.com;cisco;up; LOCATION: Room 101

Switch-HQ-Edge21.example.com;cisco;down; LOCATION: Building A (Under Construction)

42

Backup dispositivi di rete

In questi ultimi tre esempi è possibile anche inserire una description della locazione dello switchche però non apparirà nella descrizione in rancid , inutile dire che per un dispositivo, va utilizzatouno solo di questi metodi.

Una volta inserito il dispositivo o i dispositivi in ogni router.db, dobbiamo spostarci nel file cloginrcper inserire i parametri necessari a rancid per connettersi allo switch per eseguire il backup dellaconfigurazione, questo file lo troviamo in /home/rancid/.cloginrc, qui detro inseriremo il nomeutente e le password del dispositivo:

# Custom Configuration at the bottom of .cloginrc

# No Enable Prompts

add noenable Swich-E-Edge05.example.com 1

# Connect to All CORES (Notice the wildcard, remember you still need to add the full name tothe router.db file.)

add user 192.168.0.20 user

add password 192.168.0.20 pass

add method 192.168.0.20 telnet

add user 192.168.0.21 user

add password 192.168.0.21 pass

add method 192.168.0.21 ssh telnet

add autoenable 192.168.0.21 1

questi sono parametri validi per i sistemi cisco o altri dispositivi, per i sistemi HP o H3C i parametrisono i seguenti:

# Core1add user core1.mio.local admin

43

Backup dispositivi di rete

add password core1.mio.local {password}add method core1.mio.local sshadd autoenable core1.mio.local {1}add cryptertype core1.mio.local {aes128-cbc}

Cosi ora abbiamo tutto pronto per testare rancid possiamo testare il tutto eseguendo rancid una solavolta, per farlo usiamo il seguente comando:

/usr/local/rancid/bin/rancid-run

Ora possiamo visualizzare i file di log per vedere se tutto è andato come previsto, per visualizzare laregistrazione, possiamo utilizzare l'editor nano

nano /usr/local/rancid/var/logs/{Type of Device/Group}

In questo esempio, vediamo che tutto è andato bene, rancid ci avvisa quando trova un problema

starting: Sun May 8 18:01:56 MST 2016

Trying to get all of the configs.

All routers sucessfully completed.

cvs diff: Diffing .

cvs diff: Diffing configs

cvs commit: Examining .

cvs commit: Examining configs

ending: Sun May 8 18:02:45 MST 2016

Dopo l'acquisizione, è possibile visualizzare la configurazione dei dispositivi utilizzandohttp://server-rancid/viewvc qui vediamo i due dispositivi con due revisioni e del Cisco 192.168.0.20e del NetScreen 192.168.0.21

44

Backup dispositivi di rete

Ora non resta che un ultima cosa da fare, impostare un job con cron in modo che esegua un backupgiornaliero dei dispositivi ad una determinata ora del giorno.

Per farlo ci bastano pochi minuti, accediamo come utente rancid digitando su rancid, quindidigitiamo contrab -e da notare che l'editor che verrà utilizzato è VI, per scrivere in VI premiamo iltasto “i” una volta terminato per uscire e salvare il file premiamo il tasto esc per uscire dallamodalità scrittura e successivamente digitiamo :wq che salverà e uscirà dal programma.

#

# Rancid User Crontab File

#

# Begin Hourly Router Dump

1 * * * * /usr/local/rancid/bin/rancid-run

# Begin Cleanup of Differ Logs Every 5 Days

50 23 * * * /usr/bin/find /usr/local/rancid/var/logs -type f -mtime +5 -exec rm -rf {} \;

Ora il sistema è pronto per eseguire i backup dei nostri device automaticamente.

45