VLAN

Static ARP ACLs: Inspecting ARP Without DHCP Snooping

DAI needs DHCP snooping bindings to validate ARP. On a static-IP segment there are none, so you supply the legitimate IP-to-MAC pairs with a static ARP ACL. Proven in CML: 8 spoofed ARPs dropped.
Dynamic ARP Inspection dropping 8 forged ARP replies with a static ARP ACL
In: VLAN, Network Security, CCIE, Labs

Dynamic ARP Inspection (DAI) is the control that kills ARP poisoning on a switch, but it has a hidden dependency: it validates ARP packets against the DHCP snooping bindings database. So what happens on a segment that has no DHCP at all - a rack of statically addressed servers, a management VLAN, a point-to-point link? There are no snooping bindings to check against, and DAI has nothing to enforce. This is where static ARP ACLs come in. They let you hand DAI the legitimate IP-to-MAC pairs yourself, so ARP inspection works with zero DHCP in the picture. This article is part of the PingLabz VLANs and Layer 2 switching cluster and the broader network infrastructure security guide, and every command below was captured live on a Cisco IOL-XE switch in CML.

Why a static-IP segment breaks normal DAI

Regular DAI works like this: DHCP snooping watches DHCP exchanges and records each lease as an IP-to-MAC-to-port binding in a table. When an ARP reply crosses an untrusted port, DAI looks up the sender's IP and MAC in that table. If the pair matches a known binding, the ARP is forwarded. If it does not, the ARP is dropped and logged. That is a clean, automatic defense - as long as every host got its address from DHCP.

A static-IP segment breaks the whole chain. If your servers are configured by hand (as most server and management subnets are), no DHCP exchange ever happens, so snooping never builds a binding for them. Turn on DAI in that VLAN and, with an empty binding table, DAI would drop every legitimate ARP on the wire. You need a different source of truth for what is legitimate, and that source is a static ARP ACL: a hand-written list of the IP-to-MAC pairs you know are real.

Why ARP needs a bodyguard at all

ARP is one of the oldest and most trusting protocols on the network. When a host asks "who has 10.20.10.100?", any device on the segment can answer, and the asker caches whatever reply arrives first. There is no authentication, no sequence number, no way for the victim to tell a legitimate reply from a forged one. That design was fine in 1982 and is a gift to attackers today: poison a cache with one unsolicited reply and you can silently redirect traffic, run a man-in-the-middle, or blackhole a host. DAI exists precisely because ARP will never defend itself. On a switch it becomes the trusted third party that decides which IP-to-MAC claims are allowed to pass, and on a static segment the static ARP ACL is how you tell it the truth.

The lab: VLAN 120, no DHCP

The setup is a single user VLAN (VLAN 120, 10.20.10.0/24) on an IOL-XE switch. The gateway lives off the uplink, and two hosts sit on access ports, both statically addressed:

Gateway (uplink)
PortEt0/0 (trusted)
IP10.20.10.254
HOST1 (legit)
PortEt0/1 (untrusted)
IP10.20.10.100
MAC5254.0089.dbfd
HOST2 (attacker)
PortEt0/2 (untrusted)
IP10.20.10.101
MAC5254.007f.1646

There is no DHCP server anywhere in this VLAN. Every address was typed in by hand. That is exactly the condition where a static ARP ACL earns its place.

Configuring the static ARP ACL

An ARP access-list is not an IP ACL. Its entries permit a specific IP paired with a specific MAC, and DAI treats that pair as the definition of a legitimate host. You list every real host, then point DAI at the ACL for the VLAN:

arp access-list PLZ-ARP-ACL
 permit ip host 10.20.10.100 mac host 5254.0089.dbfd    ! HOST1's real IP-MAC
 permit ip host 10.20.10.101 mac host 5254.007f.1646    ! HOST2's real IP-MAC
ip arp inspection vlan 120
ip arp inspection filter PLZ-ARP-ACL vlan 120
interface Ethernet0/0
 ip arp inspection trust                                 ! the gateway uplink is trusted

Two things to note. First, the uplink to the gateway is marked ip arp inspection trust. Trusted ports skip inspection entirely, which is correct for an infrastructure link where you control both ends - you do not want DAI second-guessing ARP from your own router. Second, the two access ports (Et0/1 and Et0/2) are left untrusted by default, so every ARP they send is checked against PLZ-ARP-ACL.

The attack: HOST2 impersonates HOST1

Now the classic ARP-poisoning move. HOST2 wants to insert itself between HOST1 and the gateway (a man-in-the-middle). To do that, it sends gratuitous ARP replies claiming that HOST1's IP (10.20.10.100) lives at HOST2's own MAC (52:54:00:7f:16:46). If the gateway believes it, traffic destined for HOST1 gets sent to HOST2 instead. Here HOST2 fires eight forged ARP replies at the gateway with nping:

HOST2$ nping --arp --arp-type ARP-reply --arp-sender-ip 10.20.10.100 \
  --arp-sender-mac 52:54:00:7f:16:46 --arp-target-ip 10.20.10.254 -e eth0 -c 8 10.20.10.254
SENT (7.0584s) ARP reply 10.20.10.100 is at 52:54:00:7F:16:46
Raw packets sent: 8 (336B)

The forged binding is 10.20.10.100 paired with 5254.007f.1646. Your ACL says 10.20.10.100 belongs to 5254.0089.dbfd. The pair does not match a permit entry, so DAI has every reason to drop it.

DAI drops all eight

Check the inspection statistics for the VLAN and the result is unambiguous:

SW1#show ip arp inspection statistics vlan 120
 Vlan      Forwarded        Dropped     DHCP Drops      ACL Drops
 ----      ---------        -------     ----------      ---------
  120              2              8              8              0
 Vlan   DHCP Permits    ACL Permits  Probe Permits   Source MAC Failures
 ----   ------------    -----------  -------------   -------------------
  120              0              1              0                     0

Eight forged ARPs sent, eight dropped. One legitimate ARP was permitted by the ACL, and two frames were forwarded. The man-in-the-middle attempt is dead on arrival: the gateway's ARP cache is never poisoned, and HOST1's traffic keeps flowing to HOST1. This is the entire value of the control, proven on the wire, and it is the same defense the deeper Dynamic ARP Inspection and IP Source Guard article builds on for DHCP-based segments.

Read the drop column carefully: DHCP-Drops vs ACL-Drops

Look again at the counters. The eight drops landed in the DHCP Drops column, not ACL Drops, even though it was the static ARP ACL that caught them. That is not a bug, it is how ip arp inspection filter <acl> vlan <n> behaves by default. Without the static keyword, DAI checks the ARP ACL first and then falls back to the DHCP snooping database. Because the fallback path exists, drops are attributed to the DHCP side of the counters.

If you want the ACL to be the sole, authoritative source (no snooping fallback), add the static keyword:

ip arp inspection filter PLZ-ARP-ACL vlan 120 static
filter <acl> vlan <n>
ACL checked first, then falls back to the DHCP snooping database. Denied ARPs count as DHCP Drops. Use when you mix static and DHCP hosts in one VLAN.
filter <acl> vlan <n> static
ACL is authoritative, no snooping fallback. Denied ARPs count as ACL Drops. Use on a pure static-IP segment where the ACL is the whole truth.

The 15 pps rate-limit is your first line of defense

There is a second control at work here that fires before the ACL check even runs. DAI applies a rate-limit to ARP packets on untrusted ports, defaulting to 15 packets per second with a 1-second burst interval. You can see it in the interface state:

SW1#show ip arp inspection interfaces
 Interface        Trust State     Rate (pps)    Burst Interval
 Et0/0            Trusted               None               N/A
 Et0/1            Untrusted               15                 1
 Et0/2            Untrusted               15                 1

The uplink is trusted with no rate-limit, and both access ports cap ARP at 15 pps. This matters because ARP poisoning is rarely eight polite packets - a real attacker floods thousands per second to keep the victim's cache poisoned. If ARP crosses the rate-limit, the port is error-disabled, so the flood is throttled before DAI ever consults the ACL. Two layers: rate-limit the volume, then validate what remains against the static bindings.

When to reach for a static ARP ACL

Use one wherever DAI needs to run but DHCP snooping cannot feed it bindings:

  • Server and DMZ subnets that are statically addressed by design.
  • Management VLANs where every device has a fixed IP.
  • Mixed segments, where a handful of static servers share a VLAN with DHCP clients (omit the static keyword so DAI validates static hosts against the ACL and DHCP hosts against the snooping table).

The trade-off is honest maintenance: an ARP ACL is a hand-maintained list. Add a server, add an entry. Re-image a NIC and the MAC changes, so update the pair. On a stable static segment that is a small price for closing the ARP-poisoning door completely. If your hosts do use DHCP, prefer snooping-backed DAI plus IP Source Guard, covered in the L2 security stack article.

Key Takeaways

  • DAI validates ARP against the DHCP snooping bindings database. On a static-IP segment there are no bindings, so you supply the legitimate IP-to-MAC pairs yourself with a static ARP ACL.
  • An arp access-list uses permit ip host X mac host Y entries. Point DAI at it with ip arp inspection filter <acl> vlan <n> and trust your infrastructure uplinks.
  • In the lab, eight forged ARP replies impersonating HOST1 were all dropped (Forwarded 2, Dropped 8), killing the man-in-the-middle before the gateway cache could be poisoned.
  • Without the static keyword, ACL-denied ARPs count in the DHCP Drops column because DAI can still fall back to snooping. Add static to make the ACL authoritative and land the drops in ACL Drops.
  • Untrusted ports also enforce a default 15 pps ARP rate-limit, throttling a flood before the ACL check even runs.
  • Static ARP ACLs fit server, DMZ, and management VLANs. For DHCP-based segments, use snooping-backed DAI plus IP Source Guard instead. See the full VLANs and Layer 2 switching cluster and the network infrastructure security guide.
Written by
More from Ping Labz
Private VLAN association with isolated and community secondaries
VLAN

Private VLANs: Isolating Hosts That Share a Subnet

Private VLANs isolate hosts that share a subnet, at Layer 2, without a subnet per host. Primary, isolated, and community secondary VLANs on Cisco IOS XE, with the classic DMZ use case and real show output.
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.