Dynamic 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.
Ein Beispiel zur Benutzung des Scriptes. Für das Vlan63 soll die ARP-Tabelle mit der DHCP-Snooping-Tabelle verglichen werden:
- Sicherstellen, dass die ARP-Tabelle des L3-Switches aktuell ist
- Ausgeben der ARP-Tabelle des Cisco-L3-Switches:
- Ausgeben der DHCP-Snooping-Tabelle des Cisco-Access-Switches, auf dem DAI konfiguriert werden soll:
- Auswerten der beiden Dateien mit dai-check.py:
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$
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
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.
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! 😉