Cisco Nexus 5k with Cisco UCS scripted FC-Zoning configuration

Infrastruktur

Seit ca einem Jahr haben wir im Datacenter-Bereich eine homogene Cisco-Infrastruktur. Im Rahmen eines Projektes sind Cisco UCS Systeme zusammen mit Cisco Nexus 5k Datacenter Switches beschafft worden.
Wir haben an zwei Standorten jeweiles zwei Nexus-Switches, an dem pro Seite jeweils ein Storage-System angeschlossen ist.
Zusätzlich haben wir an beiden Standorten Cisco-Ucs-Systeme aufgebaut.
Wir haben uns nun überlegt, wie wir unsere Server (und Blades) an die Nexus-Infrastruktur anbinden und haben uns dann für Fibre-Channel entschieden.
Dann stellte sich die Frage, wie man dann das Zoning über die Nexus-Switches löst. Klar ist, diese Aufgabe müssen wir Serveradmins übernehmen. Nachdem wir uns den Cisco Prime Datacenter Network Manager angeschaut hatten (Gui Lösung zum Managen von unter anderem auch Nexus-Switches) war uns klar, dass wir das lieber über die Konsole per Script machen wollen.
Natürlich ist bei vielen die Infrastruktur unterschiedlich und wir haben es bei uns auch bewusst relativ einfach gehalten.
Es wird also nur in einer Fabric ein Port des Storages auf einen Port des Servers gezont.

Skriptaufbau

Wir haben auf einem zentralen Linux-Server ein Skript gebaut, welches einen bestendenden Storage mit einem Server verbindet.
Was soll das Skript nun genau tun?
Das Skript soll sich zu den Fabric-Interconnects verbinden, sich von dort die Service-Profile holen und diese in einem Auswahlmenü präsentieren.
Dann soll die WWPN der vHBAs des ausgewählten Service-Profils besorgt werden und in ein Array geladen werden.
Schließlich soll der Device-Alias angelegt, die Zone gebaut und zum Zoneset hinzugefügt werden. Nach einer Sichtprüfung soll abgefragt werden ob die Zone jetzt aktiviert werden soll.
Das wars im Prinzip schon. Die eigentliche Konfiguration der Nexus-Switches wird per Shell-Funktion vorgenommen.
Hier das Skript.

#!/bin/bash
#
# Funktion zum Überprüfen ob ein (der Funktion mitgegebenes) Element im Array der Service-Profiles von FI-E12 existiert
function exists() {
element=${1}
for i in ${arraye12[@]}; 
do
if [ $i == $element ]; 
then
echo "1"
fi
done
return 0
}
# Wegschreiben der Daten in einen Ordner, der nach dem aktuellen Datum + Uhrzeit benannt ist
DATE=`date +%d%m%y-%H%M`
mkdir -p /home/vi-admin/Backup/Zoning/$DATE
FOLDER=/home/vi-admin/Backup/Zoning/$DATE
#
# Fest definierter Storage, mit dem gezont werden soll. Achtung: Diese Namen müssen als Device-Alias im jeweiligen Nexus existieren.
STORAGE1="VSTORE1"
STORAGE2="VSTORE2"
# Funktion zum Erstellen der Zone auf NX1
function createzonenx1 {
echo "conf t" > createzonenx1_$ziel.txt
echo "zone name $ziel"_Port1" vsan 1234" >> createzonenx1_$ziel.txt
echo "member device-alias $STORAGE1"_Port1"" >> createzonenx1_$ziel.txt
echo "member device-alias $ziel"_Port1"" >> createzonenx1_$ziel.txt
echo "sh zone" >> createzonenx1_$ziel.txt
ssh fczoning@nexus1 < createzonenx1_$ziel.txt 
mv createzonenx1_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen der Zone auf NX2 
function createzonenx2 { 
echo "conf t" > createzonenx2_$ziel.txt
echo "zone name $ziel"_Port2" vsan 4321" >> createzonenx2_$ziel.txt
echo "member device-alias $STORAGE1"_Port2"" >> createzonenx2_$ziel.txt
echo "member device-alias $ziel"_Port2"" >> createzonenx2_$ziel.txt
echo "sh zone" >> createzonenx2_$ziel.txt
ssh fczoning@nexus2 < createzonenx2_$ziel.txt 
mv createzonenx2_$ziel.txt $FOLDER/ 
}
# Funktion zum Erstellen der Zone auf NX3 
function createzonenx3 { 
echo "conf t" > createzonenx3_$ziel.txt
echo "zone name $ziel"_Port1" vsan 1234" >> createzonenx3_$ziel.txt
echo "member device-alias $STORAGE2"_Port1"" >> createzonenx3_$ziel.txt
echo "member device-alias $ziel"_Port1"" >> createzonenx3_$ziel.txt
echo "sh zone" >> createzonenx3_$ziel.txt
ssh fczoning@nexus3 < createzonenx3_$ziel.txt 
mv createzonenx3_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen der Zone auf NX4 
function createzonenx4 { 
echo "conf t" > createzonenx4_$ziel.txt
echo "zone name $ziel"_Port2" vsan 4321" >> createzonenx4_$ziel.txt
echo "member device-alias $STORAGE2"_Port2"" >> createzonenx4_$ziel.txt
echo "member device-alias $ziel"_Port2"" >> createzonenx4_$ziel.txt
echo "sh zone" >> createzonenx4_$ziel.txt
ssh fczoning@nexus4 < createzonenx4_$ziel.txt 
mv createzonenx4_$ziel.txt $FOLDER/ 
} 
# Funktion zum Hinzufügen der Zone zum Zoneset auf NX1 
function addzonesetnx1 {
echo "conf t" > addzonesetnx1_$ziel.txt
echo "zoneset name FABRICA_UCS1 vsan 1234" >> addzonesetnx1_$ziel.txt
echo "member $ziel"_Port1"" >> addzonesetnx1_$ziel.txt
echo "sh zoneset" >> addzonesetnx1_$ziel.txt
ssh fczoning@nexus1 < addzonesetnx1_$ziel.txt 
mv addzonesetnx1_$ziel.txt $FOLDER/ 
} 
# Funktion zum Hinzufügen der Zone zum Zoneset auf NX2 
function addzonesetnx2 { 
echo "conf t" > addzonesetnx2_$ziel.txt
echo "zoneset name FABRICB_UCS1 vsan 4321" >> addzonesetnx2_$ziel.txt
echo "member $ziel"_Port2"" >> addzonesetnx2_$ziel.txt
echo "sh zoneset" >> addzonesetnx2_$ziel.txt
ssh fczoning@nexus2 < addzonesetnx2_$ziel.txt 
mv addzonesetnx2_$ziel.txt $FOLDER/ 
} 
# Funktion zum Hinzufügen der Zone zum Zoneset auf NX3 
function addzonesetnx3 { 
echo "conf t" > addzonesetnx3_$ziel.txt
echo "zoneset name FABRICA_UCS1 vsan 1234" >> addzonesetnx3_$ziel.txt
echo "member $ziel"_Port1"" >> addzonesetnx3_$ziel.txt
echo "sh zoneset" >> addzonesetnx3_$ziel.txt
ssh fczoning@nexus3 < addzonesetnx3_$ziel.txt 
mv addzonesetnx3_$ziel.txt $FOLDER/ 
} 
# Funktion zum Hinzufügen der Zone zum Zoneset auf NX4 
function addzonesetnx4 { 
echo "conf t" > addzonesetnx4_$ziel.txt
echo "zoneset name FABRICB_UCS1 vsan 4321" >> addzonesetnx4_$ziel.txt
echo "member $ziel"_Port2"" >> addzonesetnx4_$ziel.txt
echo "sh zoneset" >> addzonesetnx4_$ziel.txt
ssh fczoning@nexus4 < addzonesetnx4_$ziel.txt 
mv addzonesetnx4_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX1 
function createdevicealiasnx1 { 
echo "conf t" > createdevicealiasnx1_$ziel.txt
echo "device-alias database" >> createdevicealiasnx1_$ziel.txt
echo "device-alias name $ziel"_Port1" pwwn $i" >> createdevicealiasnx1_$ziel.txt
echo "device-alias commit" >> createdevicealiasnx1_$ziel.txt
echo "sh device-alias database" >> createdevicealiasnx1_$ziel.txt
ssh fczoning@nexus1 < createdevicealiasnx1_$ziel.txt 
mv createdevicealiasnx1_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX2 
function createdevicealiasnx2 { 
echo "conf t" > createdevicealiasnx2_$ziel.txt
echo "device-alias database" >> createdevicealiasnx2_$ziel.txt
echo "device-alias name $ziel"_Port2" pwwn $i" >> createdevicealiasnx2_$ziel.txt
echo "device-alias commit" >> createdevicealiasnx2_$ziel.txt
echo "sh device-alias database" >> createdevicealiasnx2_$ziel.txt
ssh fczoning@nexus2 < createdevicealiasnx2_$ziel.txt 
mv createdevicealiasnx2_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX3 
function createdevicealiasnx3 { 
echo "conf t" > createdevicealiasnx3_$ziel.txt
echo "device-alias database" >> createdevicealiasnx3_$ziel.txt
echo "device-alias name $ziel"_Port1" pwwn $i" >> createdevicealiasnx3_$ziel.txt
echo "device-alias commit" >> createdevicealiasnx3_$ziel.txt
echo "sh device-alias database" >> createdevicealiasnx3_$ziel.txt
ssh fczoning@nexus3 < createdevicealiasnx3_$ziel.txt 
mv createdevicealiasnx3_$ziel.txt $FOLDER/ 
} 
# Funktion zum Erstellen des Device-Alias des Service-Profiles auf NX4 
function createdevicealiasnx4 { 
echo "conf t" > createdevicealiasnx4_$ziel.txt
echo "device-alias database" >> createdevicealiasnx4_$ziel.txt
echo "device-alias name $ziel"_Port2" pwwn $i" >> createdevicealiasnx4_$ziel.txt
echo "device-alias commit" >> createdevicealiasnx4_$ziel.txt
echo "sh device-alias database" >> createdevicealiasnx4_$ziel.txt
ssh fczoning@nexus4 < createdevicealiasnx4_$ziel.txt 
mv createdevicealiasnx4_$ziel.txt $FOLDER/ 
} 
# Funktion zum Aktivieren des Zonesets auf NX1 
function activatezonesetnx1 { 
echo "conf t" > activatezonesetnx1_$ziel.txt
echo "zoneset activate name FABRICA_UCS1 vsan 1234" >> activatezonesetnx1_$ziel.txt
echo "wr" >> activatezonesetnx1_$ziel.txt
ssh fczoning@nexus1 < activatezonesetnx1_$ziel.txt 
mv activatezonesetnx1_$ziel.txt $FOLDER/ 
} 
# Funktion zum Aktivieren des Zonesets auf NX2 
function activatezonesetnx2 { 
echo "conf t" > activatezonesetnx2_$ziel.txt
echo "zoneset activate name FABRICB_UCS1 vsan 4321" >> activatezonesetnx2_$ziel.txt
echo "wr" >> activatezonesetnx2_$ziel.txt
ssh fczoning@nexus2 < activatezonesetnx2_$ziel.txt 
mv activatezonesetnx2_$ziel.txt $FOLDER/ 
} 
# Funktion zum Aktivieren des Zonesets auf NX3 
function activatezonesetnx3 { 
echo "conf t" > activatezonesetnx3_$ziel.txt
echo "zoneset activate name FABRICA_UCS1 vsan 1234" >> activatezonesetnx3_$ziel.txt
echo "wr" >> activatezonesetnx3_$ziel.txt
ssh fczoning@nexus3 < activatezonesetnx3_$ziel.txt 
mv activatezonesetnx3_$ziel.txt $FOLDER/ 
} 
# Funktion zum Aktivieren des Zonesets auf NX4 
function activatezonesetnx4 { 
echo "conf t" > activatezonesetnx4_$ziel.txt
echo "zoneset activate name FABRICB_UCS1 vsan 4321" >> activatezonesetnx4_$ziel.txt
echo "wr" >> activatezonesetnx4_$ziel.txt
ssh fczoning@nexus4 < activatezonesetnx4_$ziel.txt 
mv activatezonesetnx4_$ziel.txt $FOLDER/ 
} 
# Alle Service-Profiles von fi1 und fi2 laden und in jeweils ein Array laden 
arraye12=(`ssh fczoning@fi1 "scope org AAA;show service-profile" |awk {'print $1'} |egrep -v "(Service|-)"| cut -c5-`) 
arraye21=(`ssh fczoning@fi2 "scope org AAA;show service-profile" |awk {'print $1'} |egrep -v "(Service|-)"| cut -c5-`) 
# Per Menü ein Service-Profile auswählen 
PS3="Auswahl: " echo "Bitte das Service Profil auswählen: " 
select ziel in "${arraye12[@]}" "${arraye21[@]}" "beenden"; 
do 
if [ $ziel == "beenden" ]; 
then 
break 
fi 
echo $ziel 
# Wenn das gewählte Service-Profile in Arraye12 existiert, dann Methoden für fi1 bzw nx1 und nx2 ausführen 
if [ "$(exists $ziel)" == "1" ]; 
then 
arrhbae12=(`ssh fczoning@fi1 "scope org AAA;scope service-profile \$ziel;show vhba" | awk {'print $3'} | tr '[:upper:]' '[:lower:]' |egrep -v "(id|-)" | tail -n +3`) 
# 3. Element des Arrays abfragen -> Entspricht dem 3.HBA des Service-Profiles
for i in "${arrhbae12[2]}"
do
# Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert
createdevicealiasnx1
createzonenx1
addzonesetnx1

# Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist.
read -p "zoneset jetzt aktivieren? j n: " activate
if [ $activate == "j" ];
then
activatezonesetnx1
fi

done
for i in "${arrhbae12[3]}"
do
# Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert
createdevicealiasnx2
createzonenx2
addzonesetnx2

# Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist.
read -p "zoneset jetzt aktivieren? j n: " activate
if [ $activate == "j" ];
then
activatezonesetnx2
fi
done
exit 0
else
arrhbae21=(`ssh fczoning@fi2 "scope org AAA;scope service-profile \$ziel;show vhba" | awk {'print $3'} | tr '[:upper:]' '[:lower:]' |egrep -v "(id|-)" | tail -n +3`)
# 4. Element des Arrays abfragen -> Entspricht dem 3.HBA des Service-Profiles
for i in "${arrhbae21[2]}"
do
# Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert
createdevicealiasnx3
createzonenx3
addzonesetnx3

# Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist.
read -p "zoneset jetzt aktivieren? j n: " activate
if [ $activate == "j" ];
then
activatezonesetnx3
fi
done
for i in "${arrhbae21[3]}"
do
# Funktionsaufruf. Hier wird der jeweilige Nexus konfiguriert
createdevicealiasnx4
createzonenx4
addzonesetnx4

# Abfrage ob die Zone nun aktiviert werden soll. Mit den Ausgaben der jeweiligen Funktionen kann man überprüfen ob das alles so korrekt ist.
read -p "zoneset jetzt aktivieren? j n: " activate
if [ $activate == "j" ];
then
activatezonesetnx4
fi
done
fi
break
done

Cisco Pix 501: Portfreigabe & ACL

Portfreigabe auf einer Pix einrichten:

Die Einrichtung einer einfachen Portfreigabe ist gar nicht so einfach wie man im ersten Moment vermuten mag.

Ich empfehle hier die Kommandozeile zu benutzen, da PDM grad bei statischen Routen und ACL’s häufig mist baut.

Lets start:

  1. Per Hyperterminal mit der Pix verbinden
  2. in enable Modus wechseln
  3. per conf t in Konfigurationsmodus wechseln
  4. Zunächst muss eine statische Route definiert werden: “static (inside, outside) <tcp/udp> <outside-ip-der-Pix> <gewünschter Port> <Ziel-Host-im-Inside-Interface> <gewünschter Port> netmask 255.255.255.255 0 0”
  5. Anschließend definiert man nun die ACL damit der Traffic auf dem entsprechenden Port auch durchgelassen wird: “access-list <acl-name> permit <tcp/udp> any host <outside-ip-der-Pix> eq <gewünschter Port>”
  6. Dann muss die ACL noch einer Access-Group zugeordnet werden: “access-group <acl-name> in interface outside”
  7. “wr mem” nicht vergessen 🙂

Its done!

Cisco Pix 501: Grundlagen ACL’s & Dhcp

Access Control List (ACL):

  • ACL=Firewallregel
  • Abarbeitung von oben nach unten bis ein
    passender Eintrag gefunden wird
  • Eine ACL wird mit „access-group“ einer
    Schnittstelle zugeordnet

Aufbau einer ACL:

access-list <name|nr> permit|deny
<protocol> <source> <destination>
[<parameter>]

Beispiel:

access-list 3 permit icmp any any echo-reply
access-list 7 permit tcp any any eq 22

Access-Group:

access-group <name|nr> in interface
<if-name>

Beispiel ACL’s:

access-list zentral permit icmp any any echo-reply
access-list zentral permit icmp any any unreachable
access-list zentral permit icmp any any time-exceeded
access-list zentral permit tcp host 192.189.51.100 62.199.66.16
255.255.255.240 eq 22
access-list zentral permit udp any host 62.199.66.23 eq 53
access-list zentral permit tcp any host 62.199.66.23 eq 53
access-list zentral permit tcp any host 62.199.66.24 eq 25
access-list zentral permit tcp any host 62.199.66.25 eq 80
access-group zentral in interface outside
Pix als Dhcp Server:
• dhcpd address <first>-<last> <if>
• dhcpd domain <dns-domain>
• dhcpd dns <dnsserverip1> [<ip2>]
• dhcpd wins <winserverip1> [<ip2>]
• dhcpd lease <lease-time>
• dhcpd enable <if>