21 septembre 2012

Maintenant que vous connaissez mon obsession pour le scripting avec : Scripting 101 – F5 / Sauvegarde automatique de vos loadbalancers, nous allons voir comment backuper des firewalls PaloAlto.

Sur PANOS on a une superbe API REST XML qui permet à des automates distants d’interagir avec l’équipement, mais à l’ordre du jour nous allons réviser un des outils les plus basiques d’un système UNIX : expect.

1 – Expect c’est quoi ?

Expect est un outil d’automatisation de tests, basé sur une extension du langage Tcl, permettant de valider des programmes interactifs comme : ftp / telnet / ssh et bien d’autres. Il est utilisé par le projet RANCID (outil d’automatisation de sauvegardes).

Son fonctionnement est assez simple : il lance une commande interactive (type ssh) et ensuite il exécute une série de commandes de send/expect pour envoyer des données et valider le retour.

Dans les commandes usuelles nous retrouvons :

  • spawn : qui permet de lancer un programme
  • send : qui envoi des instructions comme si nous les avions tapées manuellement dans un terminal
  • expect : qui valide le retour du programme = sortie texte que nous aurions vu sur le terminal
  • et toute la librairie de fonctions Tcl utilisée aussi dans les iRules F5 😉

2 – Script d’automatisation

Comme vous vous en doutez, si nous programmons un expect script qui se connecte en SSH à un équipement et lance une commande type « get configuration« , il sera très facile de le mettre en tâche planifiée (crontab) pour disposer d’un backup quotidien de nos équipements.

Vous trouverez ci-joint un exemple d’implémentation pour les firewalls PaloAlto, que vous pourrez modifier à votre guise et l’adapter à d’autres équipements !

Il ne vous reste plus qu’a le déployer sur votre UNIX/LINUX préféré, la commande s’utilise comme ceci :

romio@whitehat ~/Desktop $ ./backup_paloalto.sh <host> <user> <pass> [<output_file>]
# Exemple
romio@whitehat ~/Desktop $ ./backup-paloalto.sh 172.16.1.51 admin admin
# Fichier de sortie par défaut : backup-pan-<host>-<date>.conf
romio@whitehat ~/Desktop $ head -3 backup-pan-172.16.1.51-2012-09-21.conf
config {
  mgt-config {
    users {
[...]

Code source :

#!/usr/bin/expect
# Romain MOREL
# romain.morel@nomios.fr
# Usage : backup_paloalto host user pass [output_file]
# Version 1.0

##############################################################################
#
#   CONFIGURATION
#
##############################################################################

# Global Variables (Ajust value regarding your hostname/cluster)
set prompt "@*> $"
# Output Buffer
match_max -d 1000000
# Disable terminal output
log_user 0

##############################################################################
#
#   ARGUMENTS
#
##############################################################################
set host [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]
set file [lindex $argv 3]

# Check arguments
if { $user == "" || $pass == "" || $host == ""}  {
  puts "Usage: backup_paloalto <host> <user> <pass> \[<output_file>\]"
  exit 1
}
# Default output file
if { $file == "" } {
    # Suffix for output file
    set suffix [clock format [clock seconds] -format %Y-%m-%d]
    set file "backup-pan-$host-$suffix.conf"
}

##############################################################################
#
#   LIBRARY
#
##############################################################################

# SSH connection
proc ssh_connect { pass prompt } {
    expect {
        "assword: " { 
            send "$pass\r"
            expect {
                   "$prompt" {
                    return 0
                }  
            }
         }
  }
  # timed out
  return 1
}

# Backup routine
proc backup_conf { file prompt } {
    # Check for file opening with write access
    set fh [open $file w]
    # Set scripting-mode on
    send "set cli scripting-mode on\r"
    expect -- $prompt {
        # Disable pager (| more-like output)
        send "set cli pager off\r"
        expect -- $prompt {
            # Get configuration
            send "show config running\r"
            expect -- $prompt {
                    set output $expect_out(buffer)
                    # Convert \r\n to \n
                    regsub -all "\r" $output "" output
                    # Strip first line
                    regsub "^.*show config running\n\n" $output "" output
                    # Strip last line
                    regsub  "\n\n.+$" $output "" output
                    # Write content to <ouput_file>
                    puts $fh $output 
                    close $fh
                     return 0
            }
        }
    }
    # Problem during cli commands
    return 1
}

##############################################################################
#
#   SCRIPT LOGIC
#
##############################################################################

spawn ssh -o "StrictHostKeyChecking no" $user@$host
set ret [ssh_connect $pass $prompt] 
if { $ret == 1 } {
    puts "Error connecting to PAN-FW: $user@$host"
    exit 1
}

set ret [backup_conf $file $prompt]
if { $ret == 1 } {
    puts "Error while fetching configuration"
    exit 1
}

exit 0

Easy ?

Romio

Partager :

Auteurs