Automatische Cisco XR-Bereitstellung mit ZTP

Andrea Dainese
18 October 2023
Post cover

Dieser Artikel untersucht, wie die Bereitstellung von hundert Cisco XR-Geräten optimiert werden kann, damit sie mit minimalem menschlichem Eingriff konfiguriert werden. Je nach Kontext können die Geräte direkt ab Werk versandt und automatisch vor Ort konfiguriert werden, oder wahrscheinlicher ist es, dass sie automatisch in einer Laborumgebung konfiguriert, überprüft und dann für die Installation versandt werden. Wir werden uns auf das sogenannte ZTP oder Zero Touch Provisioning verlassen. Das ZTP-Protokoll ermöglicht die Konfiguration eines werkseitig gelieferten Geräts ohne menschliches Eingreifen. ZTP ist herstellerspezifisch und erfordert speziell für Cisco XR:

  • Einrichten eines DHCP-Servers zur Zuweisung einer IP-Adresse an die Geräte;
  • Einrichten eines Webservers, der Konfigurationen für jedes Gerät generiert;
  • Einschalten der Geräte, damit sie über DHCP eine IP-Adresse erhalten und den Webserver erreichen können.

Im Szenario, das wir uns vorstellen, richten wir eine Laborumgebung ein, in der die Geräte ausgepackt, automatisch konfiguriert, verpackt und an den endgültigen Bestimmungsort versandt werden, wo nichttechnisches Personal die physische Installation, die Netzwerkkabelverbindungen und das Einschalten durchführen wird. Wir nehmen an, dass an entfernten Standorten keine technischen Fähigkeiten vorhanden sind und kein technisches Personal entsandt werden kann.

Lassen Sie uns in die Details eintauchen.

Labor-Netzwerkkonfiguration

Wir richten eine Laborumgebung mit einem Linux-System und zwei Netzwerkschnittstellen ein: Die erste pnet0 verbindet das System mit dem Unternehmensnetzwerk, und die zweite pnet9 ist mit einem dedizierten und isolierten Netzwerk verbunden. Die zu konfigurierenden Geräte werden dann an einen dedizierten physischen Switch angeschlossen, dessen Gateway die Schnittstelle pnet9 des Linux-Systems ist.

Lab topology

Auf dem Linux-System verwenden wir Dnsmasq, konfiguriert wie folgt:

port=0
interface=pnet9
dhcp-range=169.254.1.0,169.254.1.253,30d
dhcp-option=67,http://169.254.1.1:8080/ztp
log-dhcp

Dnsmasq wird das Netzwerk 169.254.1.0/24 bedienen, indem es freie IPs an Clients vergibt und die Zuweisung für 30 Tage aufrechterhält. DHCP-Anforderungen enthalten die URL für die ZTP-Auto-Konfiguration. DHCP-Anforderungen werden über Syslog protokolliert, normalerweise in /var/log/syslog gespeichert.

Konfigurations-Setup

Der Webserver, erreichbar unter der konfigurierten Adresse im vorherigen Absatz, muss Folgendes bereitstellen:

  • Ein Bash-Skript für alle Geräte verfügbar machen;
  • Eine spezifische Konfiguration für jedes Gerät generieren;
  • Die richtige Konfiguration für jedes Gerät verfügbar machen.

Wir werden Flask verwenden, um eine kleine Webanwendung zu erstellen, die dynamisch Konfigurationen für jedes Gerät generieren kann. Die Anwendung wird auf zwei URLs reagieren:

  • /ztp (GET), das das Bash-Skript für Cisco XR-Geräte verfügbar macht;
  • /config (POST), das die spezifische Konfiguration für jedes Gerät verfügbar macht, das seine Seriennummer senden muss.

Sobald die Flask-Anwendung bereit ist, kann sie mit folgendem Befehl gestartet werden:

flask --app ztp run -p 8080 -h 169.254.1.1

Stellen Sie sicher, dass die Anwendung auf der richtigen Schnittstelle lauscht und dass beide URLs korrekt antworten:

wget -q -O- http://169.254.1.1:8080/ztp
wget -q -O- --post-data="serial=1234" http://169.254.1.1:8080/config

Die URL /ztp gibt Text zurück, der für alle Geräte identisch ist und wie folgt aussieht:

#!/bin/bash

export CONFIG_FILE="/tmp/config.txt"
source /pkg/bin/ztp_helper.sh

SN=$(dmidecode | grep -m 1 "Serial Number:" | awk '{print $NF}')
PN=$(xrcmd "show inventory location 0/RP" | grep -m1 "PID" | awk '{print $2}')
RESULT=$(wget -O- --post-data="serial=${SN}&model=${PN}" {{ url }} > $CONFIG_FILE)

xrapply_with_reason "Initial ZTP configuration" $CONFIG_FILE

Nachdem das Gerät über DHCP eine IP-Adresse erhalten hat, ruft es das beschriebene Skript ab. Dieses Skript ruft die Seriennummer (über dmidecode) und das Modell (über show inventory) ab. Anhand dieser Parameter fordert das Gerät die zweite URL an, um seine initiale Konfiguration zu verwenden.

Die URL /config gibt basierend auf den in POST übergebenen Parametern die minimale Konfiguration zurück, um das Gerät über SSH erreichbar zu machen:

username cisco
 group root-lr
 password 0 cisco
!
hostname device01
!
domain name example.com
!
vrf OOB address-family ipv4 unicast
!
router static vrf OOB address-family ipv4 unicast
    0.0.0.0/0 169.254.1.1
!
interface MgmtEth0/0/CPU0/0
 vrf OOB
 ipv4 address 169.254.1.11 255.255.255.0
 no shutdown
!
ssh server v2
ssh server vrf OOB
!
line default
 transport input ssh

Einschalten und ZTP-Prozessüberprüfung

Wir haben den letzten, aber wichtigsten Schritt erreicht: das Einschalten des Geräts und die Überprüfung, ob der ZTP-Prozess korrekt funktioniert. Wenn ein fabrikneues Cisco XR-Gerät gestartet wird, sollte der ZTP-Prozess sofort nach dem Hinweis auf kryptografische Funktionen beginnen:

This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply third-party
authority to import, export, distribute or use encryption. Importers,
exporters, distributors and users are responsible for compliance with
U.S. and local country laws. By using this product you agree to comply
with applicable laws and regulations. If you are unable to comply with
U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be
found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.



RP/0/RP0/CPU0:Oct 18 08:11:22.659 UTC: ifmgr[363]: %PKT_INFRA-LINK-3-UPDOWN : Interface MgmtEth0/RP0/CPU0/0, changed state to Down
RP/0/RP0/CPU0:Oct 18 08:11:22.661 UTC: ifmgr[363]: %PKT_INFRA-LINK-3-UPDOWN : Interface MgmtEth0/RP0/CPU0/0, changed state to Up
RP/0/RP0/CPU0:Oct 18 08:11:29.975 UTC: pyztp2[330]: %INFRA-ZTP-4-CONFIG_INITIATED : ZTP has initiated config load and commit operations
RP/0/RP0/CPU0:Oct 18 08:11:47.203 UTC: pyztp2[330]: %INFRA-ZTP-4-CONFIG_FINISHED : ZTP has finished config load and commit operations
RP/0/RP0/CPU0:Oct 18 08:11:53.034 UTC: pyztp2[330]: %INFRA-ZTP-4-PROVISIONING_COMPLETED : ZTP has successfully completed the provisioning
RP/0/RP0/CPU0:Oct 18 08:11:59.329 UTC: pyztp2[330]: %INFRA-ZTP-4-EXITED : ZTP exited

Wenn der ZTP-Prozess korrekt funktioniert hat, hat der DHCP-Server eine IP zugewiesen:

2023-10-18T11:32:42.306237+02:00 kali dnsmasq-dhcp[3818]: 548912439 vendor class: PXEClient:Arch:00009:UNDI:003010:PID:N540-ACC-SYS
2023-10-18T11:32:42.306699+02:00 kali dnsmasq-dhcp[3818]: 548912439 user class: xr-config
2023-10-18T11:32:42.306856+02:00 kali dnsmasq-dhcp[3818]: 548912439 DHCPDISCOVER(pnet9) 40:14:82:c1:11:11
2023-10-18T11:32:42.307036+02:00 kali dnsmasq-dhcp[3818]: 548912439 tags: pnet9
2023-10-18T11:32:42.307208+02:00 kali dnsmasq-dhcp[3818]: 548912439 DHCPOFFER(pnet9) 169.254.1.11 40:14:82:c1:11:11
2023-10-18T11:32:42.309068+02:00 kali dnsmasq-dhcp[3818]: 548912439 requested options: 1:netmask, 28:broadcast, 2:time-offset, 3:router,
2023-10-18T11:32:42.309925+02:00 kali dnsmasq-dhcp[3818]: 548912439 requested options: 15:domain-name, 6:dns-server, 12:hostname,
2023-10-18T11:32:42.310094+02:00 kali dnsmasq-dhcp[3818]: 548912439 requested options: 67:bootfile-name, 43:vendor-encap, 143
2023-10-18T11:32:42.310183+02:00 kali dnsmasq-dhcp[3818]: 548912439 next server: 169.254.1.1
2023-10-18T11:32:42.310289+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  1 option: 53 message-type  2
2023-10-18T11:32:42.310366+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option: 54 server-identifier  169.254.1.1
2023-10-18T11:32:42.310433+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option: 51 lease-time  30d
2023-10-18T11:32:42.310531+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option: 58 T1  15d
2023-10-18T11:32:42.311451+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option: 59 T2  26d6h
2023-10-18T11:32:42.311641+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option:  1 netmask  255.255.255.0
2023-10-18T11:32:42.311775+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option: 28 broadcast  169.254.1.255
2023-10-18T11:32:42.312018+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size:  4 option:  3 router  169.254.1.1
2023-10-18T11:32:42.312554+02:00 kali dnsmasq-dhcp[3818]: 548912439 sent size: 25 option: 67 bootfile-name  http://169.254.1.1:8080/ztp

Und der Webserver wird auf den beiden URLs kontaktiert worden sein:

 * Serving Flask app 'ztp'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://169.254.1.1:8080
Press CTRL+C to quit
169.254.1.11 - - [18/Oct/2023 14:47:06] "GET /ztp HTTP/1.1" 200 -
169.254.1.11 - - [18/Oct/2023 14:47:33] "POST /config HTTP/1.1" 200 -

An diesem Punkt ist das Gerät erreichbar und bereit, mit sekundären Automatisierungssystemen wie AnsAnsibleible konfiguriert zu werden.

Entwicklung und Fehlerbehebung

Der beschriebene ZTP-Prozess mag einfach und geradlinig erscheinen, er erforderte jedoch tatsächlich mehrere Stunden Testzeit, um zu verstehen, wo und wie der ZTP-Prozess stecken blieb. Schauen wir uns an, welche Tools wir für die Fehlerbehebung haben.

Der ZTP-Status kann mit dem Befehl show ztp status angezeigt werden:

State             : Terminated
Current Fetcher   : No active fetcher

Der ZTP-Prozess wird nur ausgeführt, wenn der Router werkseitige Einstellungen hat; andernfalls wird er übersprungen. Wenn unser Router nicht fabrikneu ist, haben wir zwei Optionen, die beide nützlich sind.

Wir können den ZTP-Prozess von der Befehlszeile aus erzwingen:

ztp initiate

Oder wir können, ebenfalls von der Befehlszeile aus, die Konfiguration löschen und ZTP zurücksetzen:

ztp clean
configure terminal
commit replace
reload

Die ZTP-Prozessprotokolle werden auf dem Gerät gespeichert und können mit show ztp logging angezeigt werden. Sich ausschließlich auf diese Protokolle zu verlassen, ist jedoch umständlich, da jeder Start mehrere Minuten dauert. Die beste Lösung, die ich gefunden habe, war die Verwendung der verfügbaren Bash auf Cisco XR-Geräten und das manuelle Aufrufen des Skripts:

wget -O- http://169.254.1.1:8080/ztp | bash -x

Die obigen Befehle, von der Konsole aus eingegeben, öffnen eine Bash-Instanz und führen das von unserer entwickelten Anwendung bereitgestellte Skript aus. Nach Abschluss sollte das Gerät wie erwartet konfiguriert sein.