The example topology will be using three routers and one switch as shown below:
Here are the associated configurations for us to start with:
R1hostname R1
interface FastEthernet0/0
mac-address 0000.0000.0001
ip dhcp client client-id hex ABCD0123
ip address dhcp
duplex auto
speed auto
shutdown
end
R2hostname R2
ip dhcp pool R1
host 10.1.123.1 255.255.255.0
client-identifier abcd.0123
lease infinite
!
interface FastEthernet0/0
mac-address 0000.0000.0002
ip address 10.1.123.2 255.255.255.0
duplex auto
speed auto
no shutdown
end
R3hostname R3
ip dhcp pool R1
host 10.1.123.11 255.255.255.0
client-identifier abcd.0123
lease infinite
!
interface FastEthernet0/0
mac-address 0000.0000.0003
ip address 10.1.123.3 255.255.255.0
duplex auto
speed auto
no shutdown
end
SW1
hostname SW1
vtp mode transparent
vlan 123
name DHCP
interface range fa1/0/1 - 3
switchport mode access
switchport access vlan 123
spanning-tree portfast
no shutdown
interface range Fa1/0/4 - 24 , gi1/0/1 - 2
shutdown
So far R2 and R3 will both be competing to provide R1 with it's IP Address. R2 is our legitimate DHCP Server and R3 is a rogue.
R2#deb ip dhcp server packet
R3#deb ip dhcp server packet
R3#deb ip dhcp server packet
We have debugs on the DHCP servers turned on and we'll bring our DHCP client online:
R1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R1(config-if)#int fa0/0
R1(config-if)#no shut
R1(config-if)#end
*Mar 1 00:00:53.403: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Mar 1 00:00:54.403: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to up
*Mar 1 00:00:59.539: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.12.11, mask 255.255.255.0, hostname R1
Enter configuration commands, one per line. End with CNTL/Z.
R1(config-if)#int fa0/0
R1(config-if)#no shut
R1(config-if)#end
*Mar 1 00:00:53.403: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Mar 1 00:00:54.403: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to up
*Mar 1 00:00:59.539: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.12.11, mask 255.255.255.0, hostname R1
We can see that R3 and not R2 was the successful DHCP Server here:
R2#
*Mar 1 04:53:04.454: DHCPD: DHCPDISCOVER received from client abcd.0123 on interface FastEthernet0/0.
*Mar 1 04:53:04.458: DHCPD: Sending DHCPOFFER to client abcd.0123 (10.1.12.1).
*Mar 1 04:53:04.458: DHCPD: broadcasting BOOTREPLY to client 0000.0000.0001.
*Mar 1 04:53:04.482: DHCPD: DHCPREQUEST received from client abcd.0123.
*Mar 1 04:53:04.482: DHCPD: client rejected 10.1.12.1, sent 10.1.12.11.
R3#
*Mar 1 04:52:45.714: DHCPD: DHCPDISCOVER received from client abcd.0123 on interface FastEthernet0/0.
*Mar 1 04:52:45.718: DHCPD: Sending DHCPOFFER to client abcd.0123 (10.1.12.11).
*Mar 1 04:52:45.718: DHCPD: broadcasting BOOTREPLY to client 0000.0000.0001.
*Mar 1 04:52:45.742: DHCPD: DHCPREQUEST received from client abcd.0123.
*Mar 1 04:52:45.742: DHCPD: No default domain to append - abort update
*Mar 1 04:52:45.742: DHCPD: Sending DHCPACK to client abcd.0123 (10.1.12.11).
*Mar 1 04:52:45.742: DHCPD: broadcasting BOOTREPLY to client 0000.0000.0001.
Okay, the use of DHCP snooping can help here if we activate the feature and tell the switch who is trusted:
R1#release dhcp fa0/0
R1#sh ip int bri | exc unassigned
Interface IP-Address OK? Method Status Protocol
R3#
*Mar 1 00:24:22.639: DHCPD: DHCPRELEASE message received from client abcd.0123 (10.1.123.11).
*Mar 1 00:24:22.643: DHCPD: Finding a relay for client abcd.0123 on interface FastEthernet0/0.
*Mar 1 00:24:24.623: DHCPD: DHCPRELEASE message received from client abcd.0123 (10.1.123.11).
*Mar 1 00:24:24.631: DHCPD: Finding a relay for client abcd.0123 on interface FastEthernet0/0
SW1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
SW1(config)#ip dhcp snooping
SW1(config)#ip dhcp snooping vlan 123
SW1(config)#int fa1/0/2
SW1(config-if)#ip dhcp snooping trust
SW1(config-if)#end
SW1#
01:03:36: %SYS-5-CONFIG_I: Configured from console by console
SW1#show ip dhcp snooping
Switch DHCP snooping is enabled
DHCP snooping is configured on following VLANs:
123
DHCP snooping is operational on following VLANs:
123
DHCP snooping is configured on the following L3 Interfaces:
Insertion of option 82 is enabled
circuit-id format: vlan-mod-port
remote-id format: MAC
Option 82 on untrusted port is not allowed
Verification of hwaddr field is enabled
DHCP snooping trust/rate is configured on the following Interfaces:
Interface Trusted Rate limit (pps)
------------------------ ------- ----------------
FastEthernet1/0/2 yes unlimited
So let's see if this now works so only R2's DHCP server is allowed by the switch
SW1#deb ip dhcp snooping 0.0.1
R2#deb ip dhcp server packet
R3#deb ip dhcp server packet
R1#renew dhcp fa0/0
Not in Bound state.
SW1#
*Mar 1 05:48:08.220: DHCP_SNOOPING: process new DHCP packet, message type: DHCPDISCOVER, input interface: Fa1/0/1, MAC da: ffff.ffff.ffff, MAC sa: 0000.0000.0001, IP da: 255.255.255.255, IP sa: 0.0.0.0, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 0.0.0.0, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0000.0000.0001
*Mar 1 05:48:08.220: DHCP_SNOOPING: add relay information option.
*Mar 1 05:48:08.220: DHCP_SNOOPING: binary dump of relay info option, length: 20 data:
0x52 0x12 0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x3 0x2 0x8 0x0 0x6 0x0 0x1A 0x6C 0xCC 0x73 0x80
*Mar 1 05:48:08.220: DHCP_SNOOPING_SW: bridge packet get invalid mat entry: FFFF.FFFF.FFFF, packet is flooded to ingress VLAN: (123)
R2#
*Mar 1 00:29:16.827: DHCPD: inconsistent relay information.
*Mar 1 00:29:16.827: DHCPD: relay information option exists, but giaddr is zero.
This time R3 didn't even receive the DHCP discover packet, however R2 is having a problem with the DHCP options inserted by the Switch - specificy the DHCP relay information, which we can fix in two ways:
Option 1 - tell the DHCP server not to get upset about the relay options
R2#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R2(config)#ip dhcp relay information trust-all
R2(config)#end
R1#renew dhcp fa0/0
*Mar 1 00:36:33.939: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.123.1, mask 255.255.255.0, hostname R1
R2#
*Mar 1 00:34:28.011: DHCPD: DHCPDISCOVER received from client abcd.0123 on interface FastEthernet0/1.
*Mar 1 00:34:28.015: DHCPD: Sending DHCPOFFER to client abcd.0123 (10.1.123.1).
*Mar 1 00:34:28.015: DHCPD: broadcasting BOOTREPLY to client 0000.0000.0001.
*Mar 1 00:34:28.639: DHCPD: DHCPREQUEST received from client abcd.0123.
*Mar 1 00:34:28.643: DHCPD: No default domain to append - abort update
*Mar 1 00:34:28.647: DHCPD: Sending DHCPACK to client abcd.0123 (10.1.123.1).
*Mar 1 00:34:28.647: DHCPD: broadcasting BOOTREPLY to client 0000.0000.0001.
SW1#
01:11:15: DHCP_SNOOPING: process new DHCP packet, message type: DHCPDISCOVER, input interface: Fa1/0/1, MAC da: ffff.ffff.ffff, MAC sa: 0000.0000.0001, IP da: 255.255.255.255, IP sa: 0.0.0.0, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 0.0.0.0, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0000.0000.0001
01:11:15: DHCP_SNOOPING: add relay information option.
01:11:15: DHCP_SNOOPING: binary dump of relay info option, length: 20 data:
0x52 0x12 0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15 0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:15: DHCP_SNOOPING_SW: bridge packet get invalid mat entry: FFFF.FFFF.FFFF, packet is flooded to ingress VLAN: (123)
01:11:15: DHCP_SNOOPING: process new DHCP packet, message type: DHCPOFFER, input interface: Fa1/0/2, MAC da: ffff.ffff.ffff, MAC sa: 0000.0000.0003, IP da: 255.255.255.255, IP sa: 10.1.123.2, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 10.1.123.1, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0000.0000.0001
01:11:15: DHCP_SNOOPING: binary dump of option 82, length: 20 data:
0x52 0x12 0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15 0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:15: DHCP_SNOOPING: binary dump of extracted circuit id, length: 8 data:
0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15
01:11:15: DHCP_SNOOPING: binary dump of extracted remote id, length: 10 data:
0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:15: DHCP_SNOOPING: remove relay information option.
01:11:15: DHCP_SNOOPING: direct forward dhcp reply to output port: FastEthernet1/0/1.
01:11:16: DHCP_SNOOPING: process new DHCP packet, message type: DHCPREQUEST, input interface: Fa1/0/1, MAC da: ffff.ffff.ffff, MAC sa: 0000.0000.0001, IP da: 255.255.255.255, IP sa: 0.0.0.0, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 0.0.0.0, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0000.0000.0001
01:11:16: DHCP_SNOOPING: add relay information option.
01:11:16: DHCP_SNOOPING: binary dump of relay info option, length: 20 data:
0x52 0x12 0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15 0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:16: DHCP_SNOOPING_SW: bridge packet get invalid mat entry: FFFF.FFFF.FFFF, packet is flooded to ingress VLAN: (123)
01:11:16: DHCP_SNOOPING: process new DHCP packet, message type: DHCPACK, input interface: Fa1/0/2, MAC da: ffff.ffff.ffff, MAC sa: 0000.0000.0003, IP da: 255.255.255.255, IP sa: 10.1.123.2, DHCP ciaddr: 0.0.0.0, DHCP yiaddr: 10.1.123.1, DHCP siaddr: 0.0.0.0, DHCP giaddr: 0.0.0.0, DHCP chaddr: 0000.0000.0001
01:11:16: DHCP_SNOOPING: binary dump of option 82, length: 20 data:
0x52 0x12 0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15 0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:16: DHCP_SNOOPING: binary dump of extracted circuit id, length: 8 data:
0x1 0x6 0x0 0x4 0x0 0x7B 0x1 0x15
01:11:16: DHCP_SNOOPING: binary dump of extracted remote id, length: 10 data:
0x2 0x8 0x0 0x6 0x0 0x1A 0xE3 0x65 0xA0 0x80
01:11:16: DHCP_SNOOPING: remove relay information option.
01:11:16: DHCP_SNOOPING: direct forward dhcp reply to output port: FastEthernet1/0/1.
R1#release dhcp fa0/0
Option 2 - tell the switch not to add any dhcp options
R2#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R3(config)#no ip dhcp relay information trust-all
R3(config)#end
SW1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
SW2(config)#no ip dhcp snooping information option
SW2(config)#end
01:14:49: %SYS-5-CONFIG_I: Configured from console by console
SW2#show ip dhcp snooping | i option
Insertion of option 82 is disabled
So lets check this method works:
R1#renew dhcp fa0/0
R1#
*Mar 1 00:40:31.927: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.123.1, mask 255.255.255.0, hostname R1
Okay, so we're protected against DHCP servers that shouldn't be hooked up to our network, what else can we do with this information? Since the Switch is inspecting the DHCP transactions, it is therefore possible for the switch to know what IP addresses should be associated with particular interfaces, and protect our network against spoofed end devices.
Let's set up our DHCP client (R1) port on the switch to support ip source guard:
R1#release dhcp fa0/0
SW1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
SW1(config)#int fa1/0/1
SW1(config-if)#ip verify source
SW1(config-if)#end
SW1#sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active deny-all 123
Currently Fa1/0/1 is set to deny all incoming ip traffic
R1#renew dhcp fa0/0
*Mar 1 03:17:54.843: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.123.1, mask 255.255.255.0, hostname R1
DHCP Snooping has learnt about the end device contected to Fa1/0/1
SW1#sh ip dhcp snooping binding
MacAddress IpAddress Lease(sec) Type VLAN Interface
------------------ --------------- ---------- ------------- ---- --------------------
00:00:00:00:00:01 10.1.123.1 infinite dhcp-snooping 123 FastEthernet1/0/1
Total number of bindings: 1
IP source guard has used this information to open a pin hole for the end host IP Address 10.1.123.1
SW1#sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.123.1 123
R1#ping 10.1.123.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.123.2, timeout is 2 seconds:
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 4/10/28 ms
If we manually set an IP Address the network should be protected against an end device with an unauthorised IP address allocation:
R1#release dhcp fa0/0
R1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R1(config)#int fa0/0
R1(config-if)#ip add 10.1.123.100 255.255.255.0
R1(config-if)#do ping 10.1.123.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.123.2, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
SW1#sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active deny-all 123
Traffic is being dropped by the switch, so let's return R1 to obtaining it's IP address back with DHCP
R1(config-if)#ip address dhcp
R1(config-if)#end
R1#
*Mar 1 03:59:28.379: %SYS-5-CONFIG_I: Configured from console by console
*Mar 1 03:59:30.275: %DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 10.1.123.1, mask 255.255.255.0, hostname R1
SW1#sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.123.1 123
Let's see if we can protect Fa1/0/2
SW1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
SW1(config)#int fa1/0/2
SW1(config-if)#ip verify source
SW1(config-if)#do sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.123.1 123
Fa1/0/2 ip inactive-trust-port
Due to the "ip dhcp snooping trust" configuration on Fa1/0/2 - IP Source Guard filters are disabled since the port is already considered trusted. Let's try protecting a static IP allocated port.
SW1(config-if)#int fa1/0/3
SW1(config-if)#ip verify source
SW1(config-if)#do sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.12.1 123
Fa1/0/2 ip inactive-trust-port
Fa1/0/3 ip active deny-all 123
Without DHCP snooping able to provide the means to feed the IP Source Guard filters, a static configuration is required:
SW1(config-if)#ip source binding 0000.0000.0003 vlan 123 10.1.12.3 interface fa1/0/3
SW1(config)#do sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.12.1 12
Fa1/0/2 ip inactive-trust-port
Fa1/0/3 ip active 10.1.12.3 12
R1#ping 10.1.123.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.123.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/4 ms
Although we have specified the MAC address for the binding, the filter is only of the type IP, this suggests that we could change the MAC address on R3 and things should still work:
R3#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R3(config)#int fa0/0
R3(config-if)#mac 0.0.33
R3(config-if)#end
*Mar 1 04:29:34.026: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
*Mar 1 04:29:36.890: %SYS-5-CONFIG_I: Configured from console by console
R3#
R3#ping 10.1.123.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.123.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/4 ms
R1#sh arp 10.1.123.3
Protocol Address Age (min) Hardware Addr Type Interface
Internet 10.1.123.3 0 0000.0000.0033 ARPA FastEthernet0/0
To force IP Source Guard to take into consideration the MAC address as well, we need to enable port security.
SW1(config)#int fa1/0/3
SW1(config-if)#switchport port-security maximum 2
SW1(config-if)#switchport port-security violation shutdown
SW1(config-if)#switchport port-security mac-address sticky
SW1(config-if)#switchport port-security
SW1(config-if)#ip verify source port-security
SW1(config-if)#do sh ip verify source
Interface Filter-type Filter-mode IP-address Mac-address Vlan
--------- ----------- ----------- --------------- ----------------- ----------
Fa1/0/1 ip active 10.1.12.1 123
Fa1/0/2 ip inactive-trust-port
Fa1/0/3 ip-mac active 10.1.12.3 00:00:00:00:00:03 123
We can see that both the IP and MAC now need to be in alignment
R3#sh int fa0/0 | i bia
Hardware is Gt96k FE, address is 0000.0000.0033 (bia c202.0497.0000)
R3#ping 10.1.12.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.12.1, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
Although the IP lines up, the MAC doesn't and therefore fails - let's restore the MAC
R3#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R3(config)#int fa0/0
R3(config-if)#mac 0.0.3
*Mar 1 04:34:06.814: %LINK-3-UPDOWN: Interface FastEthernet0/0, changed state to up
R3(config-if)#end
R3#sh int fa0/0 | i bia
Hardware is Gt96k FE, address is 0000.0000.0003 (bia c202.0497.0000)
R3#ping 10.1.12.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.12.1, timeout is 2 seconds:
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 4/11/32 ms