[PYTHON] Versuchen Sie, SSH (Exscript) von der Software auf den Router einzustellen

Dies ist ein 12/2-minütiger Beitrag von NetOpsCoding AdventCalender.

Dieses Mal werde ich versuchen, die Router-Einstellungen, die das Dämonentor sein werden, zu automatisieren, während ich eine Netzwerkautomatisierungssoftware erstelle.

Was das Dämonentor betrifft, gibt es ab 2015 einige APIs, die nicht zum Einstellen / Steuern von Routern bereitgestellt werden, und selbst wenn sie bereitgestellt werden, handelt es sich häufig um herstellerspezifische APIs, und es handelt sich um eine Umgebung mit mehreren Anbietern. In diesem Netzwerk ist es einfach, ein Automatisierungsprogramm für jedes Routermodell / Betriebssystem zu implementieren.

Unter diesen Umständen werden Spezifikationen für Industriestandard-APIs wie NETCONF / YANG / RESTCONF / Telemetry entwickelt. Derzeit sind jedoch noch Probleme zu lösen, wenn es in einer Umgebung mit mehreren Anbietern verwendet wird, z. B. solche mit Herstellerunterschieden in den einstellbaren Beschreibungsinhalten, solche, die nur mit dem neuesten Betriebssystem funktionieren, und solche, die eingeschränkte Funktionen unterstützen. Ich werde.

Daher werde ich dieses Mal den Ablauf der Eingabe der Router-Einstellungen aus der Software mithilfe von SSH implementieren, der vielseitigsten Methode, ohne die bereitgestellte API zu verwenden. Mit anderen Worten, die Software ersetzt die Reihenfolge, in der sich der Netzbetreiber tatsächlich mit SSH beim Router anmeldet, und gibt die Einstellungen über die CLI ein.

Die Methode zur Automatisierung mit den für jede Programmiersprache bereitgestellten SSH- und Telnet-Paketen ist viel vielseitiger als mit NETCONF usw. (alles, was von Menschen über die CLI konfiguriert werden kann, ist in Ordnung). Andererseits muss die Software die Ausgabeergebnisse und Fehlermeldungen der Anzeigebefehle analysieren, die ursprünglich vom Menschen visuell bestätigt wurden. Insbesondere wird dies nicht empfohlen, da möglicherweise unbekannte Fehlermeldungen angezeigt werden oder die Software jedes Mal geändert wird, wenn sich das Anzeigeergebnis aufgrund des Versions-Upgrades des Router-Betriebssystems ändert. Derzeit wird dies jedoch nur empfohlen, wenn Telnet / SSH verwendet wird. Es gibt viele Fälle, in denen es nicht eingestellt werden kann, daher ist es eine gute Idee, sich daran als eines der Mittel zu erinnern.

Ausführungsumgebung

Das Paket Exscript wird verwendet, um Informationen per SSH für den Router abzurufen und festzulegen. Expect ist als SSH-Paket bekannt, aber Exscript unterstützt neben Linux / Unix auch IOS, IOS-XR, JunOS usw. Daher ist es beim Empfang des Ausgabeergebnisses vom Router sehr praktisch, da keine dem Router zugewiesene Analyseverarbeitung durchgeführt werden muss.

Dieses Mal erstellen wir ein SSH-Einstellungsprogramm am Beispiel des JUNOS-Routers. Wenn jedoch SSH / Telnet verwendet werden kann, kann es mit Routern anderer Hersteller im selben Ablauf eingestellt werden.

Vorbereitungen

Stellen Sie sicher, dass Sie mit Ihrem Benutzerkonto und Kennwort vom Zielserver aus SSH-Verbindungen zum Router herstellen können. Es sind keine besonderen Einstellungen außer SSH erforderlich.

Programm, das den Befehl show ausführt

Schreiben wir zunächst ein Programm, das einen Befehl ausführt, der den in der Schnittstelle festgelegten Inhalt durch SSH-Anmeldung am Router anzeigt.

show_junos.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

from Exscript.protocols import SSH2
from Exscript.Account import Account

username = 'user1'
password = 'pass1'
ipv4 = '192.168.0.1'

#Einrichten einer SSH-Sitzung
session = SSH2()
session.connect(ipv4)

#Melden Sie sich beim Router an
session.login(Account(name=username, password=password))

#Senden Sie einen Befehl an den Router und erhalten Sie das Ausgabeergebnis
print '='*40
print 'Step 1. run show command'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


#SSH-Sitzung trennen
if session:
    session.send('exit\r')
    session.close()
else:
    raise AttributeError('Cannot find a livied session')

Bei der Ausführung des Programms werden die in der Schnittstelle des JUNOS-Routers eingestellten Inhalte ausgegeben.

$ python show_junos.py

========================================
Step 1. run show command
========================================
show configuration interfaces xe-0/0/0 | no-more
disable;

user1@router>

Hier sehen Sie, dass für die Schnittstelle xe- / 0/0/0 nur "disable" eingestellt ist.

Programm zur Eingabe der Schnittstelleneinstellungen

Durch Entwickeln des Arguments der Funktion "session.execute ()" des obigen Programms werden die Einstellungen in den Router eingegeben.

Speichern Sie hier die Konfiguration, die Sie im Voraus eingeben möchten, als Textdatei und laden Sie die Konfigurationsdatei, wenn das Programm ausgeführt wird.

junos_config.txt


delete interfaces xe-0/0/0 disable
set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30

JUNOS bietet verschiedene Möglichkeiten, um die Konfiguration in den Router zu laden.

  1. Einstellen mit dem Befehl set über die CLI des Routers
  2. So übertragen Sie die Konfigurationsdatei, platzieren sie auf dem Router und laden sie mit dem Befehl load

Hier wird als Allzweckmethode, die auch auf einem Cisco-Router usw. ausgeführt werden kann, Folgendes unter "1. Festlegen mit dem Befehl set über die CLI des Routers" festgelegt.

Das erstellte Programm lautet wie folgt.

set_junos.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from Exscript.protocols import SSH2
from Exscript.Account import Account

username = 'user1'
password = 'pass1'
ipv4 = '192.168.0.1'

session = SSH2()
session.connect(ipv4)
session.login(Account(name=username, password=password))


print '='*40
print 'Step 1. run show command'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


print '='*40
print 'Step 2. read config file'
print '='*40
config_filename = sys.argv[1]
with open(config_filename, 'r') as config_file :
    config_lines = config_file.readlines()
    print config_filename
    print config_lines


print '='*40
print 'Step 3. run configure command'
print '='*40
session.execute('configure')
for config_line in config_lines :
    session.execute(config_line)
    print session.response


print '='*40
print 'Step 4. commit check'
print '='*40
session.execute('show | compare')
print session.response
session.execute('commi check')
print session.response


print '='*40
print 'Step 5. commit'
print '='*40
print 'Do you commit? y/n'
choice = raw_input().lower()
if choice == 'y':
    session.execute('commit')
    print session.response
else:
    session.execute('rollback')
    print session.response
session.execute('exit')
print session.response


print '='*40
print 'Step 6. run show command(again)'
print '='*40
session.execute('show configuration interfaces xe-0/0/0 | no-more')
print session.response


if session:
    session.send('exit\r')
    session.close()
else:

Um das Verfolgen des Ablaufs zu vereinfachen, habe ich es oben geschrieben, ohne mich um Details wie das Entwickeln der Anzeige, das Behandeln von Fehlern und das Überprüfen des Rückgabewerts vom Router zu kümmern. Tatsächlich ist es notwendig, Fehlerbehandlung, Timeout-Behandlung usw. gemäß der vom Router zurückgegebenen Zeichenfolge zu schreiben. Wenn die Anzahl der Fehlerbehandlungsanweisungen zunimmt, wird es schwierig, sie zu erkennen. Es wird daher empfohlen, sie nach Bedarf zu einer Funktion zu machen.

Und hier ist das Ergebnis der Ausführung des Programms.

python set_junos.py junos_config.txt

========================================
Step 1. run show command
========================================
show configuration interfaces xe-0/0/0 | no-more
disable;

user1@router>
========================================
Step 2. read config file
========================================
junos_config.txt
['delete interfaces xe-0/0/0 disable\n', 'set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30\n']
========================================
Step 3. run configure command
========================================
delete interfaces xe-0/0/0 disable

[edit]
user1@router#

[edit]
user1@router#
set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.1/30

[edit]
user1@router#

[edit]
user1@router#
========================================
Step 4. commit check
========================================
show | compare
[edit interfaces xe-0/0/0]
-   disable;
[edit interfaces xe-0/0/0]
+    unit 0 {
+        family inet {
+            address 10.0.0.1/30;
+        }
+    }

[edit]
user1@router#
commit check
configuration check succeeds

[edit]
user1@router#
========================================
Step 5. commit
========================================
Do you commit? y/n
y
commit
commit complete

[edit]
user1@router#
exit
Exiting configuration mode

user1@router>
========================================
Step 6. run show command(again)
========================================
show configuration interfaces xe-0/0/0 | no-more
unit 0 {
    family inet {
        address 10.0.0.1/30;
    }
}

user1@router>

Auf diese Weise können Sie ein Programm schreiben, um den Router mithilfe von SSH aus der Software zu konfigurieren.

Dies ist nicht das Ziel.

Wie in der Mitte erwähnt, werden beim tatsächlichen Festlegen der Einstellungen im Router "Verarbeitung, wenn die Konfiguration falsch ist", "Verarbeitung, wenn der Router einen Fehler zurückgibt", "Verarbeitung, wenn die SSH-Sitzung nicht hergestellt werden kann". Es ist notwendig, beispielsweise ein Programm zu implementieren.

Darüber hinaus wird dieses Mal das Programm unter der Voraussetzung erstellt, dass "Personen beurteilen", "den Befehl show bestätigen" und "ob ein Commit ausgeführt werden soll oder nicht", jedoch unter dem Gesichtspunkt der Automatisierung.

Das Programm selbst
(1)Überprüfen Sie das Ergebnis des Befehls show und der Fehlerausgabe
(2)Geben Sie die Konfiguration ein
(3)Nach der Beurteilung, dass es kein Problem gibt
(4)Festschreiben und ausführen
(5)Testen Sie, ob die Netzwerkeinstellungen wie erwartet sind

Prozess ist erforderlich.

Wenn Sie versuchen, den obigen Prozess zu implementieren, müssen Sie die Ausgabe mit dem Befehl show analysieren, was zwangsläufig zu einem komplizierten Programm führt.

Um die Komplexität einer solchen Programmierung zu verringern, werden einfache Mechanismen für Software wie NETCONF und Telemetrie vorbereitet. NETCONF und RESTCONF erleichtern jedoch nur die Einstellungen und die Informationserfassung auf dem Router, und die anderen Prozesse müssen noch von den Entwicklern selbst implementiert werden, sodass die Automatisierung immer noch einige Herausforderungen mit sich bringt. Ich bin.

Schließlich

Die Probleme haben kein Ende, aber der Trend zur Automatisierung des Netzwerkbetriebs besteht darin, Dinge, die sich nach und nach durch Versuch und Irrtum stetig bewegen, zu entwickeln und das Programm weiterzuentwickeln, während wir gleichzeitig unsere eigene Arbeit reduzieren. Ich denke, dass es eine Abkürzung ist. Lassen Sie uns zunächst Schritt für Schritt gemeinsam unser Bestes geben, weil wir es selbst tun können. Und wenn Sie noch einen Schritt weiter gehen, prahlen Sie in Blogs und NetOps Coding-Ereignissen damit. Was Sie in Schwierigkeiten sind, ist, dass jeder in Schwierigkeiten ist. Wir freuen uns auf Ihren Stolz.

Recommended Posts

Versuchen Sie, SSH (Exscript) von der Software auf den Router einzustellen
Versuchen Sie, NETCONF (ncclient) von der Software zum Router einzustellen
Einstellungen zur Angabe der für die SSH-Verbindung zulässigen IP-Adressen
[Postgresql] SSH-Verbindung zum externen DB-Server vom Client
Versuchen Sie, das Thema Pelican vorzustellen
SSH-Verbindung von Windows zu GCP
Probieren Sie Cython in kürzester Zeit aus
Der schnellste Weg, EfficientNet auszuprobieren
Vom "Zeichnen" zum "Schreiben" des Konfigurationsdiagramms: Zeichnen Sie das AWS-Konfigurationsdiagramm mit Diagrammen
Der einfachste Weg, PyQtGraph auszuprobieren
Versuchen Sie es mit Pythons Webframework Django (1) - Von der Installation bis zum Serverstart
Versuchen Sie, sich der Teilsumme zu stellen
So bedienen Sie Linux von der Konsole aus
Python Amateur versucht die Liste zusammenzufassen ①
So greifen Sie von außen auf den Datenspeicher zu
Versuchen Sie, Code aus 1 mit dem Framework Chainer für maschinelles Lernen (Mnist Edition) zu schreiben.
SSH-Anmeldung am Zielserver von Windows mit einem Klick auf eine Verknüpfung
Versuchen wir das TensorFlow-Musikgenerierungsprojekt "Magenta" von der Entwicklungsumgebung bis zur Songgenerierung.
Versuchen Sie, das Fizzbuzz-Problem mit Keras zu lösen
Melden Sie sich mit SSH bei einem Remote-Server an
Versuchen Sie, dem Bild die Verzerrung des Fischaugenobjektivs hinzuzufügen
Versuchen Sie, die Daimyo-Prozession in Tucker zu zerlegen
Versuchen Sie, das Problem der Python-Klassenvererbung zu lösen
Einstellung zur Ausgabe des Protokolls zur Ausführung von cron
Versuchen Sie, das Mensch-Maschine-Diagramm mit Python zu lösen
So testen Sie den Friends-of-Friends-Algorithmus mit pyfof
Ändern Sie den Dezimalpunkt der Protokollierung von, nach.
So bedienen Sie Linux von außen Vorgehensweise
POST-Images von ESP32-CAM (MicroPython) an den Server
So messen Sie die Leitungsgeschwindigkeit vom Terminal aus
Von der Einführung von Pyethapp bis zur Vertragsabwicklung
Versuchen Sie, direkt von Python 3 aus auf die YQL-API zuzugreifen
Versuchen Sie, die Bewegung des Sonnensystems zu simulieren
Die Geschichte vom Umzug von Pipenv zur Poesie
Versuchen Sie zum ersten Mal, in Qiita zu posten
Versuchen Sie, mit matplotlib aus den Daten von "Schedule-kun" eine Kampfaufzeichnungstabelle zu erstellen.
Geben Sie Breiten- und Längengradpunktsequenzdaten an und versuchen Sie, die Straße anhand von OpenStreetMap-Daten zu identifizieren