Cisco IOS: Vorbereitung einer DAI (Dynamic ARP Inspection) Implementierung

switchDynamic ARP Inspection (DAI) ist ein Mechanismus in Cisco-Switchen (ab Catalyst 2960), der ARP-Pakete auf Fälschungen untersucht. Dadurch sollen beispielsweise ARP-Spoofing-Attacken verhindert werden, bei denen ein Angreifer ARP-Antworten sendet, in denen er eine fremde IP mit der eigenen MAC-Adresse verbindet, um sich in die Kommunikation einzuklinken.

Wenn DAI auf einem Cisco-Switch aktiviert wird, vergleicht der Switch bei den ARP-Paketen, ob die MAC-Adresse auch zu der IP-Adresse passt. Für diesen Vergleich muss der Switch natürlich die korrekte Zuordnung kennen. Diese lernt er normalerweise über DHCP-Snooping, bei dem die DHCP-Kommunikation beobachtet wird und der Switch “sieht”, welche IP einem Gerät mit einer bestimmten MAC-Adresse zugeordnet wurde.

Weitere Erklärungen zu DAI:

Cisco.com: Configuring Dynamic ARP Inspection
LAN Switch Security: What Hackers Know About Your Switches

Am einfachsten ist DAI zu implementieren, wenn alle Geräte in einem VLAN ihre IP per DHCP bekommen. In diesem Fall kann der Switch die IP-zu-MAC-Datenbank alleine aufbauen und benötigt keine statischen Einträge. Bei meinen letzten Implementierungen hat sich aber gezeigt, dass die Aussage der PC-Admins, dass in diesem Netz nur DHCP-Clients seien, nicht unbedingt heißen muss, dass nicht manche Geräte doch eine statische Konfiguration haben … ;-)
Deshalb ist es sinnvoll, vorher ein paar Checks durchzuführen, um diese Geräte aufzuspüren. Eine Möglichkeit ist, die Einträge in der ARP-Tabelle des L3-Switches mit den Einträgen in der DHCP-Snooping-Tabelle zu vergleichen. Wenn in der ARP-Tabelle ein Eintrag vorhanden ist (und dies ist nicht das Gateway), es aber zu dieser IP keinen Eintrag in der DHCP-Tabelle gibt, dann besteht die Chance, dass dieser PC doch eine statische IP-Konfiguration hat.
Um diesen Vergleich zu erleichern, habe ich das folgende –sehr simpel gehaltene– Python-Script geschrieben.

dai-check.py

Ein Beispiel zur Benutzung des Scriptes. Für das Vlan63 soll die ARP-Tabelle mit der DHCP-Snooping-Tabelle verglichen werden:

  1. Sicherstellen, dass die ARP-Tabelle des L3-Switches aktuell ist
  2. Wenn Geräte dabei sind, die häufiger für ein paar Stunden inaktiv sind, dann könnte es sein, dass für diese kein Eintrag in der ARP-Tabelle enthalten sind. Deshalb pinge ich alle Geräte in dem Vlan einmal an:

    karstens-macbook-pro:~ karsten$ nmap -sP 192.168.63.0/24
    
    Starting Nmap 4.76 ( http://nmap.org ) at 2009-08-28 18:09 CEST
    ...
    Host 192.168.63.201 appears to be up.
    Host 192.168.63.254 appears to be up.
    Nmap done: 256 IP addresses (174 hosts up) scanned in 48.12 seconds
    karstens-macbook-pro:~ karsten$
    
  3. Ausgeben der ARP-Tabelle des Cisco-L3-Switches:
  4. L3-Switch>term len 0
    L3-Switch>sh arp | i Vlan63
    Internet  192.168.63.254           -   001a.b1f3.9ab2  ARPA   Vlan63
    Internet  192.168.63.201         137   001c.79a5.ad41  ARPA   Vlan63
    Internet  192.168.63.79          213   0022.63a9.6384  ARPA   Vlan63
    ...
    

    Diese Liste wird abgespeichert; z.B. als dai-arp.txt

  5. Ausgeben der DHCP-Snooping-Tabelle des Cisco-Access-Switches, auf dem DAI konfiguriert werden soll:
  6. Access-Switch>term len 0
    Access-Switch>sh ip dhcp snooping binding vlan 63 | i dhcp-snooping
    00:0F:FE:5C:E0:CF   192.168.63.83     223101      dhcp-snooping  63    FastEthernet2/0/28
    00:1C:79:A5:AD:41   192.168.63.201    233322      dhcp-snooping  63    FastEthernet1/0/28
    ...
    

    Auch diese Liste wird abgespeichert; z.B. als dai-dhcp.txt. Das “| i dhcp-snooping” ist deshalb wichtig, weil das Script nur die reine Tabelle ohne Header erwartet. Das könnte/sollte ich sicher einmal verbessern. Wenn das Vlan sich über mehrere Switche erstreckt, werden diese show-Ausgaben einfach in einer Datei gesammelt.

  7. Auswerten der beiden Dateien mit dai-check.py:
  8. karstens-macbook-pro:~ karsten$ ./dai-check.py dai-arp.txt dai-dhcp.txt
    ['Internet', '192.168.63.254', '-', '001a.b1f3.9ab2', 'ARPA', 'Vlan63']
    ['Internet', '192.168.63.206', '137', '001c.79a4.af26', 'ARPA', 'Vlan63']
    

    Das Script dai-check.py sucht jetzt zu jeder IP aus der ARP-Tabelle, ob es diese IP auch in der DHCP-Tabelle gibt. Am Ende wird eine Liste der Einträge aus der ARP-Tabelle ausgegeben, zu denen es keine Entsprechung in der DHCP-Tabelle gibt. Im obigen Beispiel war das die 192.168.63.254 (das Default-Gateway) und die 192.168.63.206, die tatsächlich eine statische Konfiguration hat.

    Das Script ist sehr rudimentär, so gibt es beispielsweise keinerlei Checks, ob die Tabellen auch wirklich die richtigen Daten beinhalten. Wer falsche Daten eingibt, wird vermutlich auch ein falsches Ergebnis erhalten! ;-)

Per Tunnel ins IPv6-Internet

Da bei vielen DSL-Anbietern IPv6 ein Fremdwort ist, muss man sich oft mit einem Tunnel behelfen. Die Erweiterung einer IOS-Umgebung (Router und Switch) um IPv6 ist zwar nicht sehr aufwendig, umfasst aber doch etliche Schritte, die ich hier beispielhaft zusammenfasse.
Dabei gehe ich von der folgenden Umgebung aus:

Beispiel-Netzwerk

Beispiel-Netzwerk

Die notwendigen Schritte:

  1. Registrieren eines IPv6-Tunnels bei einem Tunnel-Broker:
  2. Sehr leicht hat man die Einrichtung bei dem (kostenlosen) Anbieter Hurricane Electric: http://tunnelbroker.net/
    Dort muss man sich registrieren und bekommt seine Zugangsdaten per Mail zugesendet. Nachdem man sich angemeldet hat, kann man einen neuen Tunnel konfigurieren:
    tunnelbroker-1
    In dem dann folgenden Dialog wird die eigene IPv4-Adresse eingetragen. Weiterhin wird angegeben, wo der Tunnel im Internet terminiert werden soll. In Deutschland bietet sich evtl. Frankfurt an.
    tunnelbroker-2
    Um den Tunnel einrichten zu können, muss der Router, über den man sich ins Internet verbindet, anpingbar sein! Wenn das gewährleistet ist, kann der Dialog mit “Submit” abgeschlossen werden.
    In der dann folgenden Bestätigung wählt man die “Tunnel Details” aus, wo man sich noch Beispielkonfigurationen für verschiedene Systeme ausgeben lassen kann. Standardmäßig bekommt man ein /64er Netz. Wenn man hinter dem Router noch mehr Infrastruktur hat (wie in diesem Beispiel), muss man noch das “Routed /48″ aktivieren:
    Tunnelbroker3

  3. Tunnelkonfiguration auf dem IOS-Router
  4. Die grundsätzliche Router-Konfiguration ist recht simpel und kann als Vorlage von der obigen Webseite generiert werden:

    
    interface Tunnel0
     description Hurricane Electric IPv6 Tunnel Broker
     no ip address
     ipv6 address [die zugewiesene /64-Adresse ]
     ipv6 enable
     tunnel source Dialer0        !!! <<-----
     tunnel destination [Der ausgewählte Tunnelserver]
     tunnel mode ipv6ip
    end
    !
    ipv6 route ::/0 Tunnel0
    

    Abweichend von der vorgeschlagenen Konfiguration habe ich die "tunnel source" auf das verwendete Dialer-Interface geändert. Damit ist die Konfig unabhängig von der konfigurierten oder dynamisch empfangenen IP-Adresse.

    IPv6 muss auch noch global eingeschaltet werden:

    
    ipv6 unicast-routing
    ipv6 cef
    

    Die Access-Liste auf dem Public-Interface (Dialer0 bei mir) muss wie oben beschrieben anpingbar sein. Das lässt sich auch auf die richtige Source-IP (66.220.2.74) eingrenzen. Weiterhin muss das IP-Protokoll 41 für den Tunnel erlaubt sein:

    
    gw#sh ip access-lists interface Dialer 0 | i 41|icmp
        40 permit icmp any any echo (12 matches)
        50 permit 41 any any (3252 matches)
    
  5. Anpassungen bei der Verwendung dynamischer IP-Adressen
  6. Wenn man eine dynamsiche IP-Adresse hat, dann muss der Tunnel für jede neue IP neu registriert werden. Sehr einfach geht das mit einem EEM-Script von der Cisco EEM Scripting Community (danke an meinen Blogger-Kollegen Jens Link für den Tip):

    ipv6-tunnel-update

    Dieses Script wird heruntergeladen und muss um die eigenen Tunnel-Parameter ergänzt werden:

    set user    "USER_ID"
    set md5pass "MD5-PASSWORD"
    set tid     "TUNNEL-ID"
    

    Die User-ID ist nicht der Login sondern die Zeichenkette, die nach dem Login auf der Tunnelbroker.net-Seite zu sehen ist (32 Stellen).
    Die Tunnel-ID ist die "Global Tunnel ID" aus den Tunnel-Details der Tunnelbroker.net-Seite.
    Das MD5-Password ist das eigene Password, das mit MD5 gehashed wird. Auf dem Mac kann dafür das Programm "md5" verwendet werden, jedes andere anständige Betriebssystem bringt sicher ein entsprechendes Tool mit:

    karstens-macbook-pro:~ karsten$ md5 -s "Mein Password"
    MD5 ("Mein Password") = 4d3b73493102972e8b989fa5b563b150
    karstens-macbook-pro:~ karsten$
    

    Dieses Script wird ins Flash des Routers geladen und muss für den Embedded Event-Manager (EEM) aktiviert werden:

    event manager directory user policy "flash:/"
    event manager policy ipv6-tunnel-update.tcl type user
    

    Der erste Befehl gibt an, wo die Scripte liegen, der zweite meldet das gerade hochgeladene Script im System an.
    Als Nächstes steuert man, wann man die Aktualisierung der IP vornehmen möchte. Dafür habe ich das Script so modifiziert, dass es die Syslog-Ausgaben überwacht und immer dann aktiv wird, wenn der Dialer an das Ausgangs-Interface gebunden wird (ich habe nur einen Dialer im System, daher kann ich das recht einfach halten):

    ::cisco::eem::event_register_syslog pattern "%DIALER-6-BIND" priority all
    namespace import ::cisco::eem::*
    namespace import ::cisco::lib::*
    
    set url     "http://ipv4.tunnelbroker.net"
    set php     "ipv4_end.php"
    set ip      "ipv4b=AUTO"
    set user    "USER"
    set md5pass "PASS"
    set tid     "TUNNEL-ID"
    
    append url "\/$php\?$ip\&pass=$md5pass\&user_id=$user\&tunnel_id=$tid"
    
    after 5000
    
    if {[catch {http::geturl $url -queryblocksize 50 -type "text/plain" } token]} {
      action_syslog priority info msg "http request failed"
    } else {
      action_syslog priority info msg "Response: [http::data $token]"
    }
    
    exit 0
    

    Damit wird die neue IP-Adresse auch bei einem Router-Neustart registriert, was das Original-Script nicht macht.

  7. Konfigurieren der Firewall
  8. Natürlich wird man auch für IPv6 eine Firewall aktivieren. Hier offenbart sich dann leider das Grauen bei Cisco. Zum einen unterstützt die Zone-Based-Firewall kein IPv6, und auch die traditionelle IOS-Firewall (CBAC) unterstützt nur TCP, UDP, ICMP und FTP. Keine weiteren Protokolle und auch keine Erweiterungen, wie das Inspizieren von Router-eigenem Traffic.
    Als erstes wird die FW-Policy angelegt und im Tunnel aktiviert:

    ipv6 inspect name FW tcp
    ipv6 inspect name FW udp
    ipv6 inspect name FW icmp
    ipv6 inspect name FW ftp
    !
    interface Tunnel0
     ipv6 inspect FW out
    

    Als Nächstes muss der eingehende Traffic gefiltert werden. Dabei muss man aufpassen, kein einfaches "deny ipv6 any any" zu konfigurieren, da dann das Neighbor-Discovery nicht mehr funktioniert. So könnte es aber aussehen:

    ipv6 access-list OUTSIDE-IN-v6
     permit icmp any any nd-na
     permit icmp any any nd-ns
     deny ipv6 any any
    !
    interface Tunnel0
     ipv6 traffic-filter OUTSIDE-IN-v6 in
    
  9. Konfigurieren der weiteren Router-Interfaces
  10. Aus dem zugewiesenen /48er Netz wird jedem Netz ein Subnet zugewiesen. Welche Subnet-Adressen man nehmen könnte, habe ich hier schon mal angedeutet. Da alle diese Netze die ersten 48 Bit gemeinsam haben, kann man sich die Konfiguration mit Hilfe der "General-Prefixes" erleichtern. Diese haben einen Namen (hier HE1) und beinhalten die ersten 48 Bit der IP-Adresse.

    ipv6 general-prefix HE1 2001:aaaa:bbbb::/48
    

    Auf den Interfaces kann bei der Konfiguration der IP-Adressen dieser Prefix referenziert werden:

    interface Vlan250
     ipv6 address HE1 ::250:0:0:0:1/64
     ipv6 enable
    

    Mit dieser Konfig kündigt sich der Router automatisch an, und der PC sollte sich mit einer IPv6-Adresse selbst konfigurieren. Die Funktion kann per Ping ("ping6 ipv6.google.com") oder per Webbrowser ("http://ip6.me") überprüft werden.

  11. Einbinden des internen Switches
  12. Um auf dem verwendeten Cisco Catalyst 3560 IPv6 konfigurieren zu können, muss der Switch erst vorbereitet werden. Das Default-"Switch Database Management-Template" unterstützt kein IPv6:

    
    c3560(config)#sdm prefer dual-ipv4-and-ipv6 default 

    Je nachdem, was man mit seinem Catalyst alles machen möchte, ist evtl. auch ein anderes Template nötig. Diese sind im Configuration-Guide beschrieben. Dieser Befehl taucht später nicht in der Konfiguration auf, kann aber mit "sh sdm prefer" kontrolliert werden.

    Der Rest der Konfiguration ist dann dem Router sehr ähnlich. IPv6 aktivieren, General-Prefix konfigurieren und Interfaces mit einer IPv6-Adresse versehen:

    
    ipv6 general-prefix HE1 2001:aaaa:bbbb::/48
    ipv6 unicast-routing
    !
    interface Vlan250
     ipv6 address HE1 ::250:0:0:0:2/64
    !
    interface Vlan255
     ipv6 address HE1 ::255:0:0:0:1/64
    

    Der Router muss jetzt natürlich noch die internen Netze lernen und der Switch eine Default-Route bekommen. In einem kleinen Netz reichen dafür ohne weiteres statische Routen, die mit "ipv6 route" anstelle "ip route" konfiguriert werden. Bei Bedarf kann man natürlich auch RIP, OSPF, EIGRP oder IS-IS benutzen.

VPNs zwischen Standorten mit überlappenden Adressen

Gerade habe ich eine Anfrage bekommen, wie man denn Netze verbinden kann, wenn auf beiden Seiten der gleiche Adress-Bereich verwendet wird. Als Lösung gibt es verschiedene Ansätze:

  1. Readressierung
  2. Je nachdem wie gut das Netz gepflegt ist, muss das nicht ein zu großer Aufwand sein. Spätestens jetzt könnte das ein Grund sein, um DHCP und DNS konsequent umzusetzen. Wenn die überlappenden Adress-Bereiche durch einen Firmen-Zusammenschluss zustande gekommen sind, dann wird es wohl hierauf hinauslaufen.

  3. Erweiterung des Netzes um IPv6
  4. Wenn man sich noch nicht mit IPv6 beschäftigt hat, wird dies sicher am längsten dauern um implementiert zu werden. Aber dann sollte die Wahrscheinlichkeit für überlappende Netze relativ klein sein. ;-)

  5. Double-NAT zwischen den Netzen
  6. Hierbei werden die mehrfach verwendeten Netze per NAT verborgen. Je nachdem wie viele Standorte den gleichen Adress-Bereich verwenden, kann die Konfiguration und auch das Management dieser Lösung etwas “eklig” werden. Aber gerade wenn unterschiedliche Firmen verbunden werden sollen, ist dies oft die verwendete Lösung.

    Dieser Artikel beschreibt die Konfiguration dieses Ansatzes in Verbindung mit VPN-Tunneln.

Das Ausgangs-Szenario:
2router
An beiden Standorten wird das selbe IP-Netz verwendet. Die Lösung beinhaltet, dass beide Standorte ihre IP-Netze per NAT hinter einem anderen Netz “verbergen”. Dieses neue Netz wird dann verwendet, um auf die Geräte der anderen Seite zuzugreifen.
Um die Kombination von NAT und IPSec zu verstehen, muss man sich einfach bewusst sein, in welcher Reihenfolge im IOS die verschiedenen Funktionen abgearbeitet werden: NAT Order of Operation
nat-order-of-operation
Wie man sieht, werden die Daten genatted, bevor sie verschlüsselt werden und auf der anderen Seite entschlüsselt, bevor NAT angewendet wird.

Für jede Seite wird jetzt ein freies Netz gewählt (hier 10.111.111.0/24 und 10.222.222.0/24):
2routernat
Die Source-Adressen des linken Netzes werden in 10.111.111.x übersetzt, die Source-Adressen des rechten Netzes in 10.222.222.x.

Die (relevante) Konfiguration der zwei Router sieht folgendermaßen aus:


hostname R1
crypto isakmp policy 1
 encr aes 256
 authentication pre-share
 group 5
crypto isakmp key Yes,ThisKeyIsNotReallySecret,LongAndRandom address 192.168.2.2
!
crypto ipsec transform-set ESP-AES256-SHA esp-aes 256 esp-sha-hmac
!
crypto map VPN 1 ipsec-isakmp
 set peer 192.168.2.2
 set transform-set ESP-AES256-SHA
 match address CRYPTO-TO-SITE-2
!
interface FastEthernet0/0
 description LAN
 ip address 10.10.10.1 255.255.255.0
 ip nat inside
!
interface Serial1/0
 description Connection to Internet
 ip address 192.168.1.2 255.255.255.0
 ip nat outside
 crypto map VPN
!
ip route 0.0.0.0 0.0.0.0 192.168.1.1
!
ip nat inside source static network 10.10.10.0 10.111.111.0 /24
!
ip access-list extended CRYPTO-TO-SITE-2
 permit ip 10.111.111.0 0.0.0.255 10.222.222.0 0.0.0.255

hostname R2
!
crypto isakmp policy 1
 encr aes 256
 authentication pre-share
 group 5
crypto isakmp key Yes,ThisKeyIsNotReallySecret,LongAndRandom address 192.168.1.2
!
crypto ipsec transform-set ESP-AES256-SHA esp-aes 256 esp-sha-hmac
!
crypto map VPN 1 ipsec-isakmp
 set peer 192.168.1.2
 set transform-set ESP-AES256-SHA
 match address CRYPTO-TO-SITE-1
!
interface FastEthernet0/0
 description LAN
 ip address 10.10.10.1 255.255.255.0
 ip nat inside
!
interface Serial1/0
 description Connection to Internet
 ip address 192.168.2.2 255.255.255.0
 ip nat outside
 crypto map VPN
!
ip route 0.0.0.0 0.0.0.0 192.168.2.1
!
ip nat inside source static network 10.10.10.0 10.222.222.0 /24
!
ip access-list extended CRYPTO-TO-SITE-1
 permit ip 10.222.222.0 0.0.0.255 10.111.111.0 0.0.0.255

Wenn aus dem linken Netz das rechte erreicht werden soll, muss natürlich die NAT-Adresse genommen werden. Bei einem Ping vom linken LAN-Interface zum rechten LAN-Interface sieht das dann folgendermaßen aus:


R1#ping 10.222.222.1 source fastEthernet 0/0 rep 1 

Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 10.222.222.1, timeout is 2 seconds:
Packet sent with a source address of 10.10.10.1
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 32/32/32 ms
R1#
*Mar  1 00:49:23.527: ICMP: echo reply rcvd, src 10.222.222.1, dst 10.10.10.1

R2#
*Mar  1 00:49:23.319: ICMP: echo reply sent, src 10.10.10.1, dst 10.111.111.1

Ein entscheidender Nachteil dieser Methode ist, dass diese Adress-Übersetzung immer durchgeführt wird und ein Router mit dieser Konfiguration nicht mehr sinnvoll für andere Verbindungen verwendet werden kann. Diese Translation dürfte eigentlich nur verwendet werden, wenn das gegenüberliegende NAT-Netz angesprochen wird.
Diese Bedingung — die auf der PIX/ASA per Policy-NAT einfach umzusetzen ist — würde auf einem IOS-Router mit einer Route-Map beschrieben werden. Diese Route-Maps können aber leider in einer statischen Translation nicht verwendet werden, wenn ganze Netze übersetzt werden.

Cisco IOS: Embedded Packet Capture

routerViele Cisco-Geräte erlauben es, direkt auf der Netzwerk-Schnittstelle Pakete mitzuschneiden. Wie das mit der PIX/ASA geht habe ich schon vor längerer Zeit beschrieben.

Seit IOS 12.4(20)T geht das auch auf dem Router. Steffen Lehmann von Systema hat dazu eine kleine Einführung gerschrieben und sie mir zur Verfügung gestellt:


Ab 12.4(20)T kann ohne großen Aufwand ein Router Interface gespiegelt werden und per ftp/tftp der Output im Wireshark kompatiblen Format exportiert werden.

Dies funktioniert auch für SUB Interfaces auf einem 802.1q Trunk .

Die Konfguration

  1. Erstellen des Buffers
  2. Hier wird der das Puffer File definiert, welches für die „gedumpten“ Pakete verwendet wird.

    
    Router#monitor capture buffer >Buffer Filename<
    

    embedded-packet-capture_htm_4d612e2

  3. Erstellen des Capture Point
  4. Damit wird definiert, welche Source für eine bestimmte Session (Capture Point) genutzt wird.

    
    Router#monitor capture point ip cef >CapturePointName< >IF Name< >Richtung<
    

    embedded-packet-capture_htm_m43ffb00a

  5. Zuordnung Buffer – Capture Point
  6. 
    Router#monitor capture point associate >CapturePointName< >Buffer Filename<
    

    embedded-packet-capture_htm_efca750

  7. Start des Capture
  8. 
    Router#monitor capture point start >CapturePointName<
    

    embedded-packet-capture_htm_m69e287f3

  9. Monitoring
  10. Um festzustellen, wie viele Pakete schon gemonitort wurden, kann mit folgendem Kommando nachgesehen werden...

    
    Router#show monitor capture buffer > Buffer Filename<
    

    embedded-packet-capture_htm_m1a74612e

  11. Beenden des Capture
  12. 
    Router#monitor capture point stop >CapturePointName<
    
  13. Kopieren des Capture File auf externen Server
  14. 
    Router#monitor capture buffer >Buffer Filename< export tftp://>IPADRESSE>/>Dateiname<
    

    embedded-packet-capture_htm_43109f51

    Jetzt kann die Datei auf dem remote Rechner mit Wireshark geöffnet und analysiert werden.

Cisco IOS autostate

routerAuf Routern mit einem eingebauten Switch ist ein VLAN erst dann aktiv, wenn ein Gerät an dem zugehörigen Switchport angeschlossen ist.
In Umgebungen, in denen nachts alle Geräte ausgeschaltet werden (und die den Link nicht aktiv halten), geht das VLAN-Interface in den Down-State und das zugehörige Netz wird per Routing-Protokoll nicht mehr angekündigt.
Das hat natürlich alles seinen Grund. Man möchte beispielsweise keinen Traffic für ein Netz “anziehen”, das aktuell nicht vorhanden ist. In manchen Umgebungen macht das aber Probleme. Unter anderem, wenn man für das ISDN-Backup mit einer einfachen “Floating-Static-Route”-Konfiguration arbeitet. Oder man möchte das LAN-Interface administrativ nutzen; natürlich wäre dafür ein Loopback-Interface viel besser geeignet.
Eine Möglichkeit, dieses Problem zu umgehen, ist das Ausschalten des “autostate”:

int Vlan 1
 no autostate

Hiermit bleibt das VLAN-Interface immer “Up”, das Netz im Routing und die VLAN-IP-Adresse erreichbar.

Cisco Access-Control-Listen

routerImmer wieder stelle ich fest, dass manche Admins eine der wichtigsten Erweiterungen der Cisco Access-Listen verpasst haben:

Access-Listen lassen sich komfortabel editieren
Seit einiger Zeit (nein, an das genaue Release erinnere ich mich nicht mehr) haben die ACEs (Access-List-Entries) Sequenznummern, die man beim show access-lists sehen kann:

c1841#sh access-lists
Extended IP access list 100
    10 permit icmp any any (5 matches)
Extended IP access list TEST
    10 permit icmp any any (5 matches)
    20 permit udp any any
    30 permit esp any any

Diese Sequenznummern können verwendet werden, um neue ACEs einzufügen. Dazu muss eine bisher nicht verwendete Nummer genommen werden:

c1841(config)#ip access-list ext TEST
c1841(config-ext-nacl)#15 permit tcp any any
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-list TEST
Extended IP access list TEST
    10 permit icmp any any (5 matches)
    15 permit tcp any any
    20 permit udp any any
    30 permit esp any any
c1841(config-ext-nacl)#

ACEs können natürlich auch gelöscht werden:

c1841(config-ext-nacl)#no 10
c1841(config-ext-nacl)#do sh ip access-list TEST
Extended IP access list TEST
    15 permit tcp any any
    20 permit udp any any
    30 permit esp any any
c1841(config-ext-nacl)#

Wenn in einer ACL keine freien Sequenznummern mehr zur Verfügung stehen, können diese neu gebildet werden. Bei einem Reload werden diese mit einem Startwert von 10 und einer Schrittweite von 10 gebildet.

c1841(config)#ip access-list resequence TEST 50 20
c1841(config)#
c1841(config)#do sh ip access-list TEST
Extended IP access list TEST
    50 permit tcp any any
    70 permit udp any any
    90 permit esp any any
c1841(config)#

Wer noch an seinen nummerierten ACLs hängt, kann die Editier-Funktionen natürlich auch benutzen. Dafür muss die Nummer einfach wie ein Name in den named ACLs verwendet werden:

c1841(config)#ip access-list extended 100
c1841(config-ext-nacl)#20 deny ip any any log
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-list 100
Extended IP access list 100
    10 permit icmp any any (5 matches)
    20 deny ip any any log
c1841(config-ext-nacl)#

Weitere Funktionen, die bei den ACLs in der Vergangenheit hinzugekommen sind:

Direktes Anzeigen der ACL zu einem Interface

c1841#sh ip access-list interface loo11
Extended IP access list TEST in
    10 permit icmp any any (5 matches)
c1841#
c1841#sh ip access-list interface loo12
Extended IP access list TEST in
    10 permit icmp any any (10 matches)
c1841#
c1841#sh ip access-list interface loo13
Extended IP access list TEST in
    10 permit icmp any any (15 matches)
Extended IP access list TEST2 out
    10 permit tcp any any

Obwohl dieselbe ACL auf drei verschiedenen Interfaces gebunden wurde, werden getrennte Statistiken geführt.

Mehrere Ports pro ACE

c1841(config)#ip access-list ext IPSEC
c1841(config-ext-nacl)#permit esp any any
c1841(config-ext-nacl)#permit udp any any eq isakmp non500-isakmp
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh access-list IPSEC
Extended IP access list IPSEC
    10 permit esp any any
    20 permit udp any any eq isakmp non500-isakmp
c1841(config-ext-nacl)#

Natürlich verliert man bei dieser Konfiguration die getrennten Counter für die unterschiedlichen Ports (hier 500 und 4500).

ACLs können auf weitere Felder wie z.B. den TTL-, den DSCP-Wert oder TCP-Flags filtern

c1841(config)#ip access-list extended TEST3
c1841(config-ext-nacl)#permit icmp any any ttl gt 128
c1841(config-ext-nacl)#permit udp any any dscp ef
c1841(config)#ip access-list extended TEST4
c1841(config-ext-nacl)#permit tcp any any match-all +syn +ack +fin -urg

Im zweiten Beispiel wird TCP-Traffic erlaubt, der sowohl das SYN, ACK und FIN-Bit trägt, aber nicht das URG-Bit.

Gruppieren von Network- oder Service-Objekten
Wer sich traut, das IOS 12.4(20)T einzusetzen, hat sogar die Möglichkeit, Object-Groups zu verwenden, wie es die PIX bzw. ASA schon lange vorgemacht hat:

c1841(config)#object-group network RFC1918
c1841(config-network-group)#10.0.0.0 0.255.255.255
c1841(config-network-group)#172.16.0.0 0.15.255.255
c1841(config-network-group)#range 192.168.0.0 192.168.255.255
c1841(config-network-group)#exit
c1841(config)#
c1841(config)#ip access-list extended TEST5
c1841(config-ext-nacl)#permit icmp any object-group RFC1918

Setzen von Cookies für das Logging
Ab 12.4(22)T kann an das Keyword log oder log-input ein “Cookie” angehängt werden, das als Tag zum Syslog-Server mitgesendet wird:

c1841(config)#ip access-list ext TEST6
c1841(config-ext-nacl)#deny icmp host 10.1.1.1 host 10.2.2.2 log BewareOfTheseHosts
c1841(config-ext-nacl)#
c1841(config-ext-nacl)#do sh ip access-lists TEST6
Extended IP access list TEST6
    10 deny icmp host 10.1.1.1 host 10.2.2.2 log (10 matches) (tag = BewareOfTheseHosts)
c1841(config-ext-nacl)#

Auf dem Syslog-Server kommt dieses Tag mit der Log-Meldung an und kann z.B. gefiltert werden:

%SEC-6-IPACCESSLOGDP: list TEST6 denied icmp 10.1.1.1 -> 10.2.2.2 (0/0), 10 packets  [BewareOfTheseHosts]

Die OSPF Prozess ID beim PE-CE-Routing

router
Wenn OSPF als IGP in einem Netz konfiguriert wird, ist die Prozess-ID nur lokal signifikant. Es ist keine AS-Nummer wie bei EIGRP, und daher funktioniert folgende Konfiguration ohne Probleme:

hostname R1
router ospf 10
 network 10.10.10.1 0.0.0.0 area 0

hostname R2
router ospf 20
 network 10.10.10.2 0.0.0.0 area 0

Etwas anders verhält sich die Sache aber, wenn man OSPF als PE-CE-Routing-Protokoll einsetzt. In den original Kursunterlagen zum Kurs “Implementing Cisco MPLS” kann man folgendes zum Thema nachlesen:

process-id: Internally used identification parameter for an OSPF routing process.
This parameter is locally assigned and can be any positive integer. A unique value is assigned for each OSPF routing process.

Wenn man seine PE-Router aber so konfiguriert, bekommt man nicht das erwartete Ergebnis.
Um das zu verdeutlichen, habe ich die Konfiguration des MPLS-Kurses verwendet:
pe-ce-ospf
Die (relevante) Konfiguration des CE11A:

router ospf 5
 network 10.1.11.17 0.0.0.0 area 0
 network 150.1.11.17 0.0.0.0 area 0

Die (relevante) Konfiguration des CE12A:

router ospf 6
 network 10.1.12.17 0.0.0.0 area 0
 network 150.1.12.17 0.0.0.0 area 0

Die (relevante) Konfiguration des PE11:

router ospf 10 vrf CUST-A
 redistribute bgp 65001 subnets
 network 150.1.11.18 0.0.0.0 area 0

Die (relevante) Konfiguration des PE12:

router ospf 20 vrf CUST-A
 redistribute bgp 65001 subnets
 network 150.1.12.18 0.0.0.0 area 0

Wie man sieht, sind alle Prozess-IDs unterschiedlich, was innerhalb eines AS kein Problem darstellen würde.
Wenn man sich die Routing-Tabelle der CE-Router anschaut, zeigt sich aber folgendes Problem:

CE11A#sh ip route ospf
     10.0.0.0/8 is variably subnetted, 5 subnets, 3 masks
O E2    10.1.12.16/28 [110/65] via 150.1.11.18, 00:26:01, Serial1/0.101
     150.1.0.0/28 is subnetted, 2 subnets
O E2    150.1.12.16 [110/1] via 150.1.11.18, 00:26:01, Serial1/0.101

Die Routen werden als External gelernt, anstelle als Intra-Area-Routen, wie es sein sollte.

Eine Möglichkeit, das Problem zu lösen, ist, für jeden Kunden dieselbe Prozess-ID zu benutzen.
Es geht aber auch anders. Innerhalb des PE-OSPF-Prozesses kann die domain-id spezifiziert werden. Wenn diese auf den PE-Routern für jeden Kunden identisch ist, werden die Routen wie gewünscht als IA gelernt.
Die PE12-Konfig wird folgendermaßen angepaßt:

router ospf 20 vrf CUST-A
 domain-id 0.0.0.10
 redistribute bgp 65001 subnets
 network 150.1.12.18 0.0.0.0 area 0

Jetzt passt die Routing-Tabelle auf CE11A:

CE11A#sh ip route ospf
     10.0.0.0/8 is variably subnetted, 5 subnets, 3 masks
O IA    10.1.12.16/28 [110/129] via 150.1.11.18, 00:00:35, Serial1/0.101
     150.1.0.0/28 is subnetted, 2 subnets
O IA    150.1.12.16 [110/65] via 150.1.11.18, 00:00:35, Serial1/0.101

Warum das Ganze? Aus der Prozess-ID wird der Domain-Identifier abgeleitet und standardmäßig als extended Community Wert 0005 übertragen (beschrieben im RFC 4577).
Die Domain ID des PE11 kommt also bei PE12 an (ich habe “Extended Community” gegen “ExtCom” abgekürzt, damit es lesbar bleibt):

PE12#sh ip bgp vpnv4 all 10.1.11.16
BGP routing table entry for 65001:10:10.1.11.16/28, version 44
Paths: (1 available, best #1, table CUST-A)
  Not advertised to any peer
  Local
    192.168.1.17 (metric 193) from 192.168.1.17 (192.168.1.17)
      Origin incomplete, metric 65, localpref 100, valid, internal, best
      ExtCom: RT:65001:10 OSPF DOMAIN ID:0x0005:0x0000000A0200
        OSPF RT:0.0.0.0:2:0 OSPF ROUTER ID:150.1.11.18:0
      mpls labels in/out nolabel/11107

Die “0A” ist in diesem Fall die hexadezimale Form der “10″, die auf PE11 konfiguriert ist. Wenn auf PE11 domain-id 11.12.13.14 konfiguriert wäre, käme bei PE12 folgendes an: OSPF DOMAIN ID:0x0005:0x0B0C0D0E0200

Der Standard sieht jetzt vor, daß eine Route mit abweichender Domain-ID als External importiert wird. Ist die Domain-ID hingegen identisch, wird sie als Intra-Area-Route importiert. Die ganze Sache kann aber noch dadurch erweitert werden, daß es mehr als eine Domain-ID geben kann.

Remote RIP-Routing

IGPs werden normalerweise dazu verwendet, um direkt angeschlossenen Nachbarn Routing-Informationen zu senden. Aber was ist, wenn man einem entfernten Router ein Update senden möchte:

remote-rip

Kann R3 ein RIP-Update an R1 senden wenn R2 kein RIP spricht? Tunnel etc. sind natürlich nicht erlaubt. Ja, es geht. Z.B., indem R3 diesen Traffic direkt per Unicast versendet.
Die Konfiguration von R1 startet mit einer IP auf dem Interface und dem Aktivieren von RIP:

interface FastEthernet0/0
 ip address 10.10.1.1 255.255.255.0
!
router rip
 version 2
 passive-interface default
 network 10.0.0.0
 no auto-summary

Auf R2 werden nur die Interfaces konfiguriert, kein RIP:

interface FastEthernet0/0
 ip address 10.10.1.2 255.255.255.0
!
interface FastEthernet0/1
 ip address 10.10.2.2 255.255.255.0

Router R3 spricht RIP, benutzt R1 als Neighbor und sendet daher diesem seine Updates als Unicast. Alle Interfaces werden passiv gesetzt (auch auf R1), per Multicast sollen keine Nachbarn mehr erreicht werden. Weiterhin benötigt R3 eine Route, um R1 zu erreichen:

interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface FastEthernet0/1
 ip address 10.10.2.3 255.255.255.0
!
router rip
 version 2
 passive-interface default
 network 1.0.0.0
 network 10.0.0.0
 neighbor 10.10.1.1
 no auto-summary
!
ip route 0.0.0.0 0.0.0.0 10.10.2.2

Mit dieser Konfig fängt R3 an, seine Updates zu senden:

*Mar  1 00:12:26.291: RIP: sending v2 update to 10.10.1.1 via FastEthernet0/1 (10.10.2.3)
*Mar  1 00:12:26.291: RIP: build update entries
*Mar  1 00:12:26.291:   1.1.1.1/32 via 0.0.0.0, metric 1, tag 0

Diese Updates kommen auch bei R1 an, werden dort aber aufgrund der ungültigen Source-Adresse verworfen:

*Mar  1 00:44:50.767: RIP: ignored v2 update from bad source 10.10.2.3 on FastEthernet0/0

Wenn in der RIP-Konfiguration die Validierung der Source-Adresse abgeschaltet wird, kann die Route von R3 problemlos gelernt werden:

router rip
 version 2
 passive-interface default
 no validate-update-source
 network 10.0.0.0
 no auto-summary
Router#sh ip route rip
     1.0.0.0/32 is subnetted, 1 subnets
R       1.1.1.1 [120/1] via 10.10.2.3, 00:00:21

Wird das für irgendetwas benötigt? Vermutlich nicht, aber interessant ist dieses Verhalten trotzdem … ;-)

Generieren von Crypto-Keys

routerEin Artikel in Cisco IOS Hints and Tricks beschreibt einen Fehler, den vermutlich viele Leute schon begangen haben (ja, ich natürlich auch): Bei Problemen mit der SSH-Verbindung wurde zu schnell ein “crypto key generate rsa” eingegeben, um neue RSA-Keys zu erzeugen. Leider hat man vergessen, daran zu denken, daß die zertifikatbasierten VPNs von den Schlüsseln abhängen.

Glücklicherweise kennt das IOS seit Version 12.2(8)T die Möglichkeit, jedem Key-Paar ein Label mitzugeben und diese damit für verschiedene Einsatzzwecke zu unterscheiden.
Dabei wird der Befehl crypto key generate rsa mit dem Parameter label versehen:

crypto key generate rsa modulus 2048 label MYLABEL

Dieses Key-Paar kann dann in einem PKI-Trustpoint benutzt werden:

crypto pki trustpoint MYCA
 enrollment ...
 rsakeypair MYLABEL

Wenn später ein unvorsichtiges “crypto key generate” eingegeben wird, kann das den für die VPN-Zertifikate verwendeten Keys nichts anhaben.

Ein weiterer Vorteil ist, daß beim nächsten Wechsel der Zertifikate auch die Keys neu generiert werden können, ohne daß sich der SSH-Fingerprint ändert.

Update: Mit ISRs hat das bisher immer gut funktioniert. Heute ging die Methode mit 1700er Routern und einem 12.4(15)T8 allerdings schief. Also aufpassen!

Small-Site Multihoming

Ivan Pepelnjak hat in seinen sehr lesenswerten Artikeln Small Site Multi-homing, Redundant Small Site Multi-homing und Servers in Small Site Multi-homing sehr schön beschrieben, wie man sich als kleiner Kunde mit mehreren Providern verbinden kann. Eine sehr wichtige Topologie fehlt allerdings: Wie implementiert man Server, wenn man mit zwei Routern an unterschiedlichen ISPs angeschlossen ist:

small site multihoming 1

Dort ist das Problem des asymmetrischen Traffics etwas aufwendiger zu lösen.
Wie in dem Dokument Servers in Small Site Multi-homing beschrieben, hat der Server zwei zusätzliche IP-Adressen, für die auf den zwei Routern jeweils ein statischer NAT-Eintrag vorhanden ist.

Wenn man für den Server annimmt, daß dieser für das Mail-Handling zuständig ist, dann muss man annehmen, daß über beide ISPs Mails eingeliefert werden, egal ob der MX mit der höheren Priorität erreichbar ist oder nicht.

Die Grundkonfig der Router könnte folgendermaßen aussehen (anstelle des Intrerface-Trakings könnte man besser auch “ip sla” verwenden):

hostname R1
!
interface FastEthernet0/0
 ip address 10.10.10.1 255.255.255.0
 ip nat inside
 standby 0 ip 10.10.10.3
 standby 0 priority 105
 standby 0 preempt
 standby 0 track FastEthernet0/1
!
interface FastEthernet0/1
 ip address 192.168.1.1 255.255.255.0
 ip nat outside
!
ip nat pool ISP-A-POOL 192.168.1.11 192.168.1.11 prefix-length 24
ip nat inside source list INSIDE-HOSTS pool ISP-A-POOL overload
ip nat inside source static 10.10.10.101 192.168.1.101 extendable
!
ip access-list standard INSIDE-HOSTS
 permit 10.10.10.0 0.0.0.255

hostname R2
!
interface FastEthernet0/0
 ip address 10.10.10.2 255.255.255.0
 ip nat inside
 standby 0 ip 10.10.10.3
 standby 0 preempt
!
interface FastEthernet0/1
 ip address 192.168.2.1 255.255.255.0
 ip nat outside
!
ip nat pool ISP-B-POOL 192.168.2.12 192.168.2.12 prefix-length 24
ip nat inside source list INSIDE-HOSTS pool ISP-B-POOL overload
ip nat inside source static 10.10.10.102 192.168.2.102 extendable
!
ip access-list standard INSIDE-HOSTS
 permit 10.10.10.0 0.0.0.255

Der Traffic fließt hier folgendermaßen:

small site multihoming 2
  • Vom Server ausgehender Traffic (schwarz) fließt zum aktiven HSRP-Router und bekommt eine Adresse aus dem ISP-A-POOL.
  • Von außen initiierter Traffic auf die 192.168.1.101 (grün) fließt über den aktiven Router zurück und NAT läuft wie erwartet.
  • Von aussen initiierter Traffic auf die 192.168.2.102 (rot) fließt ebenfalls über den aktiven Router zurück. NAT behandelt diesen Traffic wie vom Server ausgehenden Traffic und das Antwort-Paket bekommt ebenfalls eine Absender-Adresse aus dem ISP-A-POOL, mit der der Client nichts anfangen kann.

Auf dem Switch PBR zu konfigurieren ist aufgrund der PBR-Implementierung vermutlich keine Option (3750: nur auf routed Interface oder SVI, IP Services Image, kein PBR bei gemeinsamen IPv4 und IPv6).
Auf dem Server die Konfiguration vorzunehmen ist evtl. auch nicht möglich oder gewollt.
Auf dem Router R1 ist es allerdings relativ einfach umzusetzen:

ip access-list extended TRAFFIC-FROM-102
 permit ip host 10.10.10.102 any
!
route-map POLICY-INSIDE-IN permit 10
 match ip address TRAFFIC-FROM-102
 set ip next-hop 10.10.10.2
!
interface FastEthernet0/0
 ip policy route-map POLICY-INSIDE-IN

Jetzt ergibt sich der Traffic-Fluß wie es gewünscht ist:

small site multihoming 3

Jetzt kommt natürlich noch die IOS-Firewall und eingehende ACLs auf beiden Interfaces hinzu.
Dafür muss die Konfiguration noch etwas erweitert werden. Zum einen müssen sowohl eingehende, als auch ausgehende Antwortpakete per Inspection erlaubt werden, da die ACLs ein abschließendes deny any haben sollten. Zum anderen muss der Traffic, der per PBR umgeroutet wird, auch in der ACL erlaubt werden, da die ACL vor dem Policy-Based Routing abgearbeitet wird (hier könnte man natürlich zwischen einer aus- und eingehenden FW-Policy unterscheiden):

ip inspect name FW tcp router-traffic
ip inspect name FW udp router-traffic
ip inspect name FW icmp router-traffic
!
interface FastEthernet0/0
 ip access-group INSIDE-IN in
 ip inspect FW out
!
interface FastEthernet0/1
 ip access-group OUTSIDE-IN in
 ip inspect FW out
!
ip access-list extended INSIDE-IN
 permit ip host 10.10.10.102 any
 !permit whatever you want
ip access-list extended OUTSIDE-IN
 permit tcp any host 192.168.1.101 eq smtp

Abschließend natürlich noch der Hinweis, daß dieser Server sinnvollerweise als Mail-Relay in der DMZ implementiert sein sollte. Der “richtige” Mail-Server steht dann intern und bekommt seine Mails von dem Relay.

Nächste Seite »