Cisco DHCP Snooping with ISC DHCPd

Overview

Cisco has equipped some of its newer switches, notably the 3550 series and particular 2950 models, with a feature they have termed “DHCP Snooping.” This feature allows a switch to protect a network from rogue DHCP servers, as well as provide port information to the DHCP server. This information can be very useful in logs when tracking an IP address back to a physical port.

Configuration

Despite the ease of configuration, DHCP snooping can be a real pain to set up. A standard configuration will consist of:

ip dhcp snooping vlan <vlan id>
ip dhcp snooping

The first option enables DHCP snooping on a particular VLAN, and can be repeated for multiple VLANs. The second option enables DHCP snooping globally. Both options must be present to enable DHCP snooping, and the global option must be disabled before changing certain global settings related to DHCP snooping.

Due to the security features of DHCP snooping, your network will no longer work at this point, as the switch will not forward DHCP requests, only ignore them. To complete the setup, you must identify “trusted” ports to which DHCP requests will be forwarded, and from which DHCP replies will be accepted. This was the most painful part of my deployment, as identifying the uplink ports proved difficult.

interface FastEthernet0/1
 description Uplink to MDF
 ip dhcp snooping trust

One last thing… the DHCP Relay-Agent option that is set by the DHCP snooping process can cause other parts of your network to ignore DHCP requests. Particularly, if you use an ipĀ helper-address on a router attached to your network, you may find that it seems to stop working. You need to set up “trust” on your routers that use helper-addresses or relays as well:

interface Vlan45
 ip address 10.0.0.1 255.255.255.0
 ip helper-address 10.128.0.11
 ip dhcp relay information trusted

Things should work at this point, and show ip dhcp snooping and show ip dhcp snooping binding on your switch should show somewhat useful information.

DHCP Snooping and Option-82

Perhaps equally or more useful than the security features provided by DHCP snooping is its ability to provide the DHCP server with information about which switch and which port on that switch a DHCP request is coming from. This information is supplied in Agent-ID and Circuit-ID sub-fields of the Relay-Information DHCP Option (Option 82, RFC 3046). Cisco has an article related specifically to Option 82 in the context of DHCP snooping here.

As with many options related to emerging standards, Cisco has implemented their Option 82 injection differently on different platforms, some with backwards compatibility, and some without. Early releases of the 3550 operating system provided the SNMP ifIndex value in the Circuit-ID field. Newer releases default to the vlan-mod-port “standard” but can be configured to still supply ifIndex instead. 2950s on the other hand, support vlan-mod-port only, with no option to change it. The common denominator on my hardware was vlan-mod-port, which is what I used, however using SNMP ifIndex should not be difficult to use either.

Vlan-mod-port isn’t very well documented by Cisco, but it is fairly straight-forward. After some searching, I did find a document that describes it. The Circuit-ID field is 4 bytes in length, the first two represent the VLAN ID, the third is the module number, and the fourth is the port number.

Logging Option-82 Information with ISC DHCPd

ISC’s DHCPd implementation is a pretty common and advanced piece of software. It has the ability to interpret expressions within its configuration which is very useful for assigning dynamic host names or custom log entries. To log Cisco Option-82 vlan-mod-port encoded data, I used the following in my dhcpd.conf:

if exists agent.circuit-id
{
	log ( info, concat( "Lease for ", binary-to-ascii (10, 8, ".", leased-address), " is connected to interface ",
	binary-to-ascii (10, 8, "/", suffix ( option agent.circuit-id, 2)), " (add 1 to port number!), VLAN ",
	binary-to-ascii (10, 16, "", substring( option agent.circuit-id, 2, 2)),  " on switch ",
	binary-to-ascii(16, 8, ":", substring( option agent.remote-id, 2, 6))));

	log ( info, concat( "Lease for ", binary-to-ascii (10, 8, ".", leased-address),
	" raw option-82 info is CID: ", binary-to-ascii (10, 8, ".", option agent.circuit-id), " AID: ",
	binary-to-ascii(16, 8, ".", option agent.remote-id)));

}

This will give you log entries like this:

Aug 10 16:07:33 laforge dhcpd: Lease for 10.0.172.200 is connected to interface 0/47 (add 1 to port number!), VLAN 172 on switch 0:11:92:2b:fe:0
Aug 10 16:07:33 laforge dhcpd: Lease for 10.0.172.200 raw option-82 info is CID: 0.4.0.172.0.47 AID: 0.6.0.11.92.2b.fe.0

Complaints

Nothing is ever done perfectly. Cisco, in their infinite wisdom, sends the port number zero-based in the Option-82 information from the 3550 and 2950 despite the fact that in their configurations, the ports are one-based. Also, one might expect that dhcp-eval could come to the rescue and allow you to add one, but it doesn’t. So, we’re stuck with a reminder in the log to add one to the port number before giving the user their DMCA notice. Also, knowing the MAC address of the switch in question is not particularly useful. IP address would have been ideal, or even hostname or something. Instead we’ll have to build a database of MAC addresses to keep track of this.

3 replies on “Cisco DHCP Snooping with ISC DHCPd”

  1. Gregor says:

    Hi

    newer switches or IOS version can also insert the hostname instead of the switch mac address, how can I decode this?

    Thanks Gregor

  2. Thomas says:

    Gregor: try this.

    if exists agent.circuit-id
    {
    log ( info, concat( “Lease for “, binary-to-ascii (10, 8, “.”, leased-address), ” is
    connected to interface “,
    binary-to-ascii (10, 8, “/”, suffix ( option agent.circuit-id, 2)), “, VLAN “,
    binary-to-ascii (10, 16, “”, substring( option agent.circuit-id, 2, 2)), ” on switch
    “, substring(option agent.remote-id,2,9999)));
    }

  3. matthieu says:

    Hi,

    Your configuration works pretty well thank you !

    I would like to add the MAC address of the DHCP client on the line. I know there are other lines wich give also the MAC@ but I would like to have it on the same line like:
    Lease for 192.168.1.1 ( MAC@ ) is connected to interface 3/9 , VLAN 40 on switch my_switch

    Do you have an idea ?

    Thank you

Leave a Reply

Your email address will not be published. Required fields are marked *