Evil_TTL> show | s

DHCP Snooping

Category:Cisco Systems -> Security

Basic configuration:

DHCP server---VLAN30---(Fa0/22)Switch2(Gi0/26)---VLAN20---(Gi0/26)Switch1(Fa0/10)---VLAN100----DHCP client

Switch1 – runs DHCP snooping
Switch2 – no DHCP snooping functionality

Switch1
(config)#ip dhcp snooping vlan 100
Switch1(config)#interface vlan 100
Switch1(config-if)#ip helper-address 192.168.1.50
Switch1(config-if)#ip dhcp relay information trusted
Switch1(config-if)#exit
Switch1(config)#interface gigabitethernet0/26
Switch1(config-if)#ip dhcp snooping trust
Switch1(config-if)#exit
Switch1(config)#ip dhcp snooping 

More details taken from https://cciereview.wordpress.com/2012/02/23/dhcp-snooping-giaddr-option-82/:

What is happening behind the scenes with this basic configuration:

Rack1R4(config)#do debug ip dhcp server event
DHCP server event debugging is on.
Rack1R4(config)#do debug ip dhcp server packet
DHCP server packet debugging is on.
Rack1R4(config)#
*Feb 22 23:54:57.759IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 34 4input featureMCI Check(64), rtype 0forus FALSEsendself FALSEmtu 0fw dchk FALSE
*Feb 22 23:54:57.759IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 34 4rcvd 2
*Feb 22 23:54:57.759IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 34 4stop process pak for forus packet
*Feb 22 23:54:57.759DHCPDinconsistent relay information.
*
Feb 22 23:54:57.759DHCPDrelay information option existsbut giaddr is zero 

We are receiving the DHCP packet from R1, source 0.0.0.0, and destination 255.255.255.255 broadcast, but if you notice below, R4, our DHCP Server, is complaining that the relay information is inconsistent.  Option 82, Information Option, is contained in the packet but the GIADDR is zero.  The GIADDR stands for Gateway IP Address, which is the IP Address of the relaying agent.  The Option 82, Information Option, would then contain the receiving port and hostname of the Relaying Agent by default.

R4 sees the Option 82 information, signalling that the DHCP packet might have been relayed, BUT there is no relaying IP Address.  This is the behavior of DHCP Snooping when enabling it on a switch, and since the switchport does not contain an IP Address, since it’s Layer 2, no GIADDR will be added.  Instead, just the Option 82 Information is added and this is the problem we have, but there are options:

  1. You could trust all on R4 the DHCP Server, which will cause the server to not be so suspicious:
    • (g) ip dhcp relay information trust-all
    • (i) ip dhcp relay information trusted
  2. Disable the addition of Option 82 information on SW1:
    • (g) no ip dhcp snooping information option
  3. Trust the port that is receiving the DHCP Discover:
    • (i) ip dhcp snooping trust

Any of these options will fix our predicament, but for now we’ll choose number 2 on SW1:

Rack1SW1(config)#no ip dhcp snooping information option 

Now R4 should stop complaining:

*Feb 23 00:08:22.075IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604input featureMCI Check(64), rtype 0forus FALSEsendself FALSEmtu 0fwdchk FALSE
*Feb 23 00:08:22.075IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604rcvd 2
*Feb 23 00:08:22.075IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604stop process pak for forus packet
*Feb 23 00:08:22.075DHCPDSending notification of DISCOVER:
*
Feb 23 00:08:22.075DHCPDhtype 1 chaddr 0016.c795.e180
*Feb 23 00:08:22.075DHCPDremote id 020a00009b01920401000000
*Feb 23 00:08:22.075DHCPDcircuit id 00000000
*Feb 23 00:08:22.079DHCPDDHCPDISCOVER received from client 0063.6973.636f.2d30.3031.362e.6337.3935.2e65.3138.302d.4661.302f.30 on interface FastEthernet0/1.
*Feb 23 00:08:22.079DHCPDSeeing if there is an internally specified pool class:
*
Feb 23 00:08:22.079DHCPDhtype 1 chaddr 0016.c795.e180
*Feb 23 00:08:22.079DHCPDremote id 020a00009b01920401000000
*Feb 23 00:08:22.079DHCPDcircuit id 00000000
*Feb 23 00:08:22.079DHCPDAllocate an address without class information (155.1.146.0)
*
Feb 23 00:08:22.079IPs=155.1.146.4 (local), d=155.1.146.5 (FastEthernet0/1), len 56sending
*Feb 23 00:08:22.079IPs=155.1.146.4 (local), d=155.1.146.5
Rack1R4
# (FastEthernet0/1), len 56, encapsulation failed
Rack1R4#
Rack1R4#
*Feb 23 00:08:23.579IPs=155.1.146.4 (local), d=155.1.146.5 (FastEthernet0/1), len 56sending
*Feb 23 00:08:23.579IPs=155.1.146.4 (local), d=155.1.146.5 (FastEthernet0/1), len 56encapsulation failed
*Feb 23 00:08:24.079DHCPDAdding binding to radix tree (155.1.146.5)
*
Feb 23 00:08:24.079DHCPDAdding binding to hash tree
*Feb 23 00:08:24.079DHCPDassigned IP address 155.1.146.5 to client 0063.6973.636f.2d30.3031.362e.6337.3935.2e65.3138.302d.4661.302f.30.
*
Feb 23 00:08:24.079DHCPDSending DHCPOFFER to client 0063.6973.636f.2d30.3031.362e.6337.3935.2e65.3138.302d.4661.302f.30 (155.1.146.5).
*
Feb 23 00:08:24.079DHCPDbroadcasting BOOTREPLY to client 0016.c795.e180.
*
Feb 23 00:08:24.079IPs=155.1.146.4 (local), d=255.255.255.255 (FastEthernet0/1), len 328sending broad/multicast
*Feb 23 00:08:24.079IPs=155.1.146.4 (local), d=255.255.255.255 (FastEthernet0/1), len 328sending full packet
*Feb 23 00:08:24.099IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604input featureMCI Check(64), rtype 0forus FALSEsendself FALSEmtu 0fwdchk FALSE
*Feb 23 00:08:24.099IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604rcvd 2
*Feb 23 00:08:24.099IPs=0.0.0.0 (FastEthernet0/1), d=255.255.255.255len 604stop process pak for forus packet
*Feb 23 00:08:24.099DHCPDDHCPREQUEST received from client 0063.6973.636f.2d30.3031.362e.6337.3935.2e65.3138.302d.4661.302f.30.
*
Feb 23 00:08:24.099DHCPDSending notification of ASSIGNMENT:
*
Feb 23 00:08:24.099DHCPDaddress 155.1.146.5 mask 255.255.255.0
*Feb 23 00:08:24.099DHCPDhtype 1 chaddr 0016.c795.e180
*Feb 23 00:08:24.099DHCPDlease time remaining (secs) = 86400
*Feb 23 00:08:24.099DHCPDNo default domain to append – abort update
*Feb 23 00:08:24.099DHCPDSending DHCPACK to client 0063.6973.636f.2d30.3031.362e.6337.3935.2e65.3138.302d.4661.302f.30 (155.1.146.5).
Rack1R4#
*Feb 23 00:08:24.099DHCPDbroadcasting BOOTREPLY to client 0016.c795.e180.
*
Feb 23 00:08:24.099IPs=155.1.146.4 (local), d=255.255.255.255 (FastEthernet0/1), len 328sending broad/multicast
*Feb 23 00:08:24.099IPs=155.1.146.4 (local), d=255.255.255.255 (FastEthernet0/1), len 328sending full packet 

You see the DISCOVER now reaches R4 and starts the assignment process.  The sever creates a binding with the client’s MAC and assigned IP Address 155.1.146.5, then tries to validate that no other client is using this address.

R1 receives the OFFER and sends the REQUEST since no other DHCP Server has sent an OFFER, and finally the server send an ACK, letting the client know that the address has been assigned.

You can see the entire process on SW1 take place:

Rack1SW1#
*Mar 1 02:54:47.437DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/for pakWas not set
*Mar 1 02:54:47.437DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/1
*Mar 1 02:54:47.437DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/for pakWas not set
*Mar 1 02:54:47.437DHCP_SNOOPINGreceived new DHCP packet from input interface (FastEthernet0/1)
Rack1SW1#
*Mar 1 02:54:47.437DHCP_SNOOPINGprocess new DHCP packetmessage typeDHCPDISCOVERinput interface: Fa0/1MAC daffff.ffff.ffffMAC sa0016.c795.e180IP da255.255.255.255IP sa0.0.0.0DHCP ciaddr0.0.0.0DHCP yiaddr0.0.0.0DHCP siaddr0.0.0.0DHCP giaddr0.0.0.0DHCP chaddr0016.c795.e180
*Mar 1 02:54:47.437DHCP_SNOOPING_SWbridge packet get invalid mat entryFFFF.FFFF.FFFFpacket is flooded to ingress VLAN: (146)
Rack1SW1#
*Mar 1 02:54:49.450DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/13 for pakWas not set
*Mar 1 02:54:49.450DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/13
*Mar 1 02:54:49.450DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/13 for pakWas not set
*Mar 1 02:54:49.450DHCP_SNOOPINGreceived new DHCP packet from input interface (FastEthernet0/13)
*
Mar 1 02:54:49.450DHCP_SNOOPINGprocess new DHCP packetmessage typeDHCPOFFERinput interface: Fa0/13
Rack1SW1
#, MAC da: ffff.ffff.ffff, MAC sa: 0016.c8dd.cb85, IP da: 255.255.255.255, IP sa: 155.1.146.4, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 155.1.146.5, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0016.c795.e180
*Mar 1 02:54:49.450DHCP_SNOOPINGdirect forward dhcp replyto output portFastEthernet0/1.
*Mar 1 02:54:49.459DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/for pakWas not set
*Mar 1 02:54:49.459DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/1
*Mar 1
Rack1SW1
#02:54:49.459: DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/1 for pak. Was not set
*Mar 1 02:54:49.459DHCP_SNOOPINGreceived new DHCP packet from input interface (FastEthernet0/1)
*
Mar 1 02:54:49.459DHCP_SNOOPINGprocess new DHCP packetmessage typeDHCPREQUESTinput interface: Fa0/1MAC daffff.ffff.ffffMAC sa0016.c795.e180IP da255.255.255.255IP sa0.0.0.0DHCP ciaddr0.0.0.0DHCP yiaddr0.0.0.0DHCP siaddr0.0.0.0DHCP giaddr0.0.0.0DHCP chaddr0016.c795.e180
Rack1SW1
#
*Mar 1 02:54:49.459DHCP_SNOOPING_SWbridge packet get invalid mat entryFFFF.FFFF.FFFFpacket is flooded to ingress VLAN: (146)
*
Mar 1 02:54:49.467DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/13 for pakWas not set
*Mar 1 02:54:49.467DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/13
*Mar 1 02:54:49.467DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/13 for pakWas not set
*Mar 1 02:54:49.467DHCP_SNOOPINGreceived new DHCP packet from input inter
Rack1SW1
#face (FastEthernet0/13)
*Mar 1 02:54:49.467DHCP_SNOOPINGprocess new DHCP packetmessage typeDHCPACKinput interface: Fa0/13MAC daffff.ffff.ffffMAC sa0016.c8dd.cb85IP da255.255.255.255IP sa155.1.146.4DHCP ciaddr0.0.0.0DHCP yiaddr155.1.146.5DHCP siaddr0.0.0.0DHCP giaddr0.0.0.0DHCP chaddr0016.c795.e180
*Mar 1 02:54:49.467DHCP_SNOOPINGdirect forward dhcp replyto output portFastEthernet0/1.
*Mar 1 02:54:49.467DHCP_SNOOPINGadd binding on port FastEthern
Rack1SW1
#et0/1.
*Mar 1 02:54:49.467DHCP_SNOOPINGadded entry to table (index 225

At the bottom of this output you’ll see where the binding is added to SW1:

Rack1SW1#show ip dhcp snoop binding
MacAddress                 IpAddress       Lease(sec)    Type                VLAN            Interface
——————              —————  ———-     ————-             -       ——————–
00
:16:C7:95:E1:80    155.1.146.5     85752      dhcp-snooping    146       FastEthernet0/1
Total number of bindings

Seems like a simple topic, but there are a few gotchas like disabling the verification of source MAC-Address when receiving a release.  Overall, the harder subjects deal with source guard and Dyanmic ARP Inspection.

Next, we’ll use an actual relay agent through R6 to see how the switch, SW2, handles receiving DHCP Packets that already contain Information Option and GIADDR.  By default, the switch will drop these types of packets received on untrusted ports.  You can disable this behavior by trusting the interface:

  • (i) ip dhcp snooping trust

We’ll setup the Relay Agent on R6, Fa0/0.67, and set VLAN 67 on SW1 to request an IP Address via DHCP.  In addition, we need to setup the DHCP scope on R4:

Rack1R4(config)#ip dhcp pool VL67
Rack1R4(dhcp-config)#network
Rack1R4(dhcp-config)#network 155.1.67.0 255.255.255.0 
Rack1R6(config)#int fa0/0.67
Rack1R6(config-subif)#ip helper-address 155.1.146.4 
Rack1SW1(config)#int vlan 67
Rack1SW1(config-if)#ip address dhcp 

For reachability purposes, we need to setup a static on R4 to point to the 67 network through R6:

Rack1R4(config)#ip route 155.1.67.0 255.255.255.0 155.1.146.6 

Let’s enable DHCP Snooping on SW2 and view some debug action:

Rack1SW2(config)#ip dhcp snooping
Rack1SW2(config)#ip dhcp snooping vlan 146
Rack1SW2(config)#int fa0/13
Rack1SW2(config-if)#ip dhcp snooping trust
Rack1SW2(config-if)#int fa0/19
Rack1SW2(config-if)#ip dhcp snooping trust[code]

We are not trusting port Fa0/6 just yetlet’s see what happens when we receive DHCP Packets with Option 82 and the GIADDR already filled:

[code]*Mar 1 03:40:32.164DHCP_SNOOPINGchecking expired snoop binding entries
Rack1SW2
(config-if)#
*Mar 1 03:41:03.907DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/13 for pakWas not set
*Mar 1 03:41:03.907DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/13
*Mar 1 03:41:03.915DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/for pakWas not set
*Mar 1 03:41:03.915DHCPSNOOP(hlfm_set_if_input): Clearing if_input for pakWas Fa0/6
*Mar 1 03:41:03.915DHCPSNOOP(hlfm_set_if_input): Setting if_input to Fa0/for pakWas not set
*Mar 1 03:41:03.915:
Rack1SW2(config-if)#DHCP_SNOOPING: received new DHCP packet from input interface (FastEthernet0/6)
*Mar 1 03:41:03.915DHCP_SNOOPINGprocess new DHCP packetmessage typeDHCPDISCOVERinput interface: Fa0/6MAC da0016.c8dd.cb85MAC sa0018.ba95.2124IP da155.1.146.4IP sa155.1.67.6DHCP ciaddr0.0.0.0DHCP yiaddr0.0.0.0DHCP siaddr0.0.0.0DHCP giaddr155.1.67.6DHCP chaddr0023.3421.65c3
*Mar 1 03:41:03.915: %DHCP_SNOOPING-5-DHCP_SNOOPING_NONZERO_GIADDRDHCP_SNOOPING drop message with non-zero
giaddr 
or option82 value on untrusted portmessage typeDHCPDISCOVERMAC sa0018.ba95.2124 

Now our switch, SW2, is complaining that it’s receiving already filled GIADRE and/or Option 82 DHCP packets on an untrusted interface.  Let’s trust the interface so it allows this type of packet incoming:

Rack1SW2(config)#int fa0/6
Rack1SW2(config-if)#ip dhcp snoop trust 

The output is the same as above, but ultimately the address gets assigned to SW1’s VLAN 67 interface:

Rack1SW1#show ip int bri | in 67
Vlan67    155.1.67.2                 YES    DHCP        up        up 
By privilege15