Showing posts with label DHCP. Show all posts
Showing posts with label DHCP. Show all posts

Static DHCP assignment for clients without client-id

A while ago I've installed Fedora Linux on one of my workstations and spent enormous amount of time trying to give it a static IP address from the Cisco IOS DHCP server. I though I was the only one dumb enough to have this problem, so I didn’t document my solution, but then one of the readers made a comment to the Assigning server IP addresses with DHCP post describing almost identical symptoms:

I have a hp2300n and I want to make a static IP assignment with DHCP. Nothing is working: hardware-address, client-identifier, no prepend, 01 prepend, 00 prepend.

In my case, the Fedora DHCP client did not send any DHCP client-ID in the DHCPREQUEST message. One would think that the IOS DHCP server would use the MAC address as the client-ID, but that's not the case. You have to configure the hardware-address parameter in the host DHCP pool to match the MAC address of the DHCP client with the pool and the static IP address:

ip dhcp pool fedi
host 192.168.200.206 255.255.255.240
hardware-address 000f.fe83.bca9
dns-server 208.67.220.220 208.67.222.222

This article is part of You've asked for it series.

Cable modem problems with Cisco 871

The undesired intermittent bridging behavior of Cisco 871 using old ROMMON software can lead to hard-to-diagnose problems if you're connected to an Internet access network through a cable modem that accepts only a single MAC address. The right sequence of events can leave the router/modem combination in a state with no external connectivity requiring a modem power-cycle:

  1. The router and the cable modem are power-cycled.
  2. The router starts to bridge between all LAN interfaces, effectively connecting inside workstations directly to the cable modem.
  3. One of the workstations could detect a LAN failure (due to router reload) and restart the DHCP process (a Windows XP host would definitely do that).
  4. The DHCP requests from the workstation are bridged straight to the cable modem which caches the workstation's MAC address and forwards the DHCP request.
  5. The workstation is assigned a public IP address (at this time, the workstation is connected directly to Internet and thus vulnerable).
  6. The router loads Cisco IOS and reinitializes the Ethernet interfaces. Bridging between internal and external interfaces is stopped.
  7. The router sends DHCP request on the outside interface, but the modem ignores it, as the MAC address of the DHCP request differs from the previously cached one.

In most cases, the cable modem has to be power-cycled to lose the cached MAC address.

This behavior can be observed only if the router and the cable modem are reset at the same time and the cable provider doesn't care much about MAC security and allows the modem to learn the MAC address. If you reset only the cable modem, the router is not bridging (no problem); if you reset just the router, the cable modem still caches the router's MAC address and ignores the DHCP request from the inside workstation(s).

Track the DHCP default route

Cisco has recently published a series of documents describing how you can connect a SOHO site to two ISPs. According to the timestamps on the documents, it took them a few days more than a year to publish a configuration that's almost identical to the one I've described in the IP Corner article “Small-site multihoming” … which can only mean that my configuration was close to optimal :)

Their configuration also includes a nice trick: the ip dhcp client route track number command is a convenient replacement for a static default route with the track option if one of the upstream interfaces uses DHCP and the router generates the default route based on DHCP replies.

Restart IOS DHCP server after a change in DHCP pools

I've stumbled across an interesting problem recently:

  • I've added a Linux box to my home network;
  • It used my Cisco router to get a dynamic DHCP address;
  • I've inspected the DHCP bindings on the Cisco router to find the new MAC address and configured a host DHCP pool as I'm using the Linux box as a server;
  • Even after multiple configuration changes, the IOS would fail to use the host DHCP pool.

The only solution I've found was to restart the IOS DHCP server with the no service dhcp followed by service dhcp configuration commands. Obviously, you lose all DHCP bindings when you restart the DHCP server (which could be a problem if you use conflict logging) unless you've configured the router to store them in an external file.

DHCP conflict between a Cisco router and Windows DHCP server

In a response to my post Redundant DHCP Server I've speculated that a Cisco router should coexist with a Windows-based DHCP server if you configure them with non-overlapping address ranges. I was wrong, Edgar Cahuana discovered that Microsoft's DHCP server wants to have complete control over the LAN it's serving and shuts down if it detects another DHCP server on the same LAN.

To make the two DHCP servers coexist, you have to disable rogue DHCP server detection in Windows DHCP server, as explained in this article.

The difference between rogue server detection in Windows 2000/2003 and SBS 2003 is explained in this TechNet chat.

Assigning server IP addresses with DHCP

Using DHCP to assign server IP addresses is usually not a wise decision. To start with, you have to define static DHCP mappings, which rely on client-id attribute in the DHCP request (usually the MAC address of the client). For me, the easiest way to find the correct client ID is as follows:

  • Use DHCP to assign the IP address to the server
  • Note the newly assigned IP address
  • Use the show ip dhcp bindings | include ip-address command to display the client-id to IP address binding.
  • Create a static DHCP mapping (for example, by configuring a host DHCP pool on the router) and release/renew IP address on the server

Of course, if the Ethernet adapter in the server is replaced, the static mapping stops working. The only reliable workaround I've found so far is to assign a locally-administered MAC address to the server's LAN adapter (if anyone has figured out a way to assign ASCII client-ID to a Windows server, let me know). To do it on Windows XP, use the Advanced properties in the adapter configuration window.

Remember: locally-administered MAC addresses on Ethernet networks start with 02xx.

After you've configured MAC address on the server, prepend 01 to it and insert a dot after every fourth character to get the client-ID you need to enter on the DHCP server. For example, the MAC address 0200.1000.1234 becomes client-id 0102.0010.0012.34, and the static DHCP pool on a router is configured as follows:

ip dhcp pool Server_static
host 10.0.0.10 255.255.255.0
client-identifier 0102.0010.0012.34

Persistent DHCP bindings stored in NVRAM

If you'd like to implement persistent DHCP bindings on Cisco IOS, but cannot store them on an external server, you could always use the on-board NVRAM. Simply configure ip dhcp database nvram:dhcp.txt. Later on, you can examine the contents of the dhcp.txt file with more nvram:dhcp.txt command.

Don't miss the obvious

I've recently replaced my old home router (well, actually a combination of two low-end models, one could handle ISDN and the other one 3DES) with a 1812. After I've struggled past the “interesting” interface names (it has 8 switched ports, named FastEthernet2 to FastEthernet9) and brushed up my BVI/VLAN skills, configuring it was a breeze … only the DHCP server was causing me problems; every time my laptop would wake from the standby mode, it would take almost half a minute before it got the LAN IP address. The obvious suspect (as I've installed the 12.4(15)T on it) was the software, the next one DHCP ping timers.

After replacing the software (didn't help) and tweaking DHCP timers (no change), it finally dawned on me: the ethernet ports are switched, so the spanning tree was playing tricks with me. Disabling spanning tree with the spanning-tree portfast interface configuration command solved the problem.

DHCP conflict logging: the true story

The on-line configuration help for the ip dhcp conflict logging configuration command (logging: Record address conflicts in a log file) is one of the more misleading texts I've found in Cisco IOS (and the CCO documentation is not much better). Here's how it actually works ...

If you have configured ip dhcp ping parameters (highly recommended), the router will ping the IP address it intends to allocate to a client before replying to the DHCP request. If the router receives ICMP Echo Reply message (response to ping), the address is obviously in use. If the DHCP conflict logging is enabled (default), the router will log the conflict with a syslog message (not in a separate log file) and put the address on the list of conflicts. The addresses on that list (displayed with show ip dhcp conflict) are not used in the future (similar to the addresses configured with the ip dhcp excluded-addresses command). To reuse a conflicting address, the network operator has to remove it from the list with the clear ip dhcp conflict address (or * for all addresses) command.

The DHCP conflict logging makes sense if the router uses persistent DHCP bindings (called DHCP database agents in Cisco IOS), otherwise any addresses allocated prior to a router reload would be reported as conflicts after the bindings are lost. If you don't use DHCP agents, it's thus best to turn off conflict logging with the no ip dhcp conflict logging configuration command. Even without conflict logging, there's no DHCP functionality loss and no chance of duplicate address allocation, as the router would still check whether an IP address is active before allocating it (and later on, it would be willing to re-check the conflicting IP address).

If you don't use DHCP database agents and you don't disable conflict logging (default setup), you'll have to clear the conflicts manually after a reload and you might potentially exhaust the DHCP pool because of a large number of blocked conflicting addresses.

Note: This article is part of You've asked for it series.

DHCP-based static routes

If you have configured your router as a DHCP client, you can use the default router option received in a DHCP reply as the next-hop for a static route. For example:

ip route 10.0.0.0 255.0.0.0 dhcp
You could use this functionality in scenarios where your core network uses DHCP (for example, in metropolitan networks using layer-2 Ethernet transport from an ISP), but your router needs a different default route.

You can also use this feature to change the administrative distance of the DHCP-based default route (or you could use the ip dhcp-client default-router distance value configuration command that one of the readers described in a comment to a previous DHCP-related post).

Any other good ideas where this might come handy? Post them as comments ...

Import DHCP options from an upstream DHCP server

If your router gets its IP address from an upstream DHCP server, it can automatically import the other DHCP options (DNS server, WINS server, domain prefix etc.) into its DHCP pools. For example, if you use a router to connect to a cable or MAN Ethernet ISP (see the following figure), you can use the DHCP option import to minimize your router configuration (and make it fail safe from any changes in the ISP network).

To configure the DHCP option import, use the import all DHCP pool configuration command. You cannot select which options you want to import, but you can override them with other DHCP pool configuration commands.

The import only happens when a DHCP reply is received. To force an immediate import, use the renew dhcp interface exec-level command.

The sample configuration for the above network topology is included below:
ip dhcp pool LAN
import all
network 10.0.0.0 255.255.255.0
default-router 10.0.0.5
!
interface FastEthernet0/0
description *** Internal LAN ***
ip address 10.0.0.1 255.255.255.0
!
interface FastEthernet0/1
description *** Public LAN interface ***
ip address dhcp client-id FastEthernet0/1

Default DHCP client-id

If you configure a Cisco router as a DHCP client, you'll notice that it uses weird client-id in its DHCP requests (assuming you care about client IDs on the DHCP server). Instead of using the interface MAC address as the client ID (as most workstations do), the client ID is the string 'cisco-dotted.mac.ascii-ifname' where the dotted.mac.ascii is the interface MAC address in ascii and the ifname is the short interface name.

Obviously, if your ISP checks your MAC address (and at least most cable operators do), you might have a problem. To make the router behave like a workstation, use the ip address dhcp client-id interface-name configuration command. The new client ID will be the MAC address of the specified interface (which can be different from the interface you're configuring).You can inspect the actual client ID in ASCII and hex with the debug dhcp detail. This is a sample default DHCP request packet:

DHCP: SRequest attempt # 1 for entry:
Temp IP addr: 172.18.0.3 for peer on Interface: FastEthernet0/1
Temp sub net mask: 255.255.255.0
DHCP Lease server: 172.18.0.1, state: 5 Renewing
DHCP transaction id: 2578
Lease: 600 secs, Renewal: 300 secs, Rebind: 525 secs
Next timer fires after: 00:03:46
Retry count: 1 Client-ID: cisco-0016.c85e.fbc9-Fa0/1
Client-ID hex dump: 636973636F2D303031362E633835652E
666263392D4661302F31

Hostname: a1
... and this is a DHCP request packet after the client-id option has been attached to the ip address dhcp command.
Temp IP addr: 0.0.0.0 for peer on Interface: FastEthernet0/1
Temp sub net mask: 0.0.0.0
DHCP Lease server: 0.0.0.0, state: 9 Purging
DHCP transaction id: 5CD
Lease: 0 secs, Renewal: 0 secs, Rebind: 0 secs
Next timer fires after: 00:00:26
Retry count: 0 Client-ID: 0016.c85e.fbc9
Client-ID hex dump: 0016C85EFBC9

Hostname: a1

Inspection of router-generated traffic does not recognize DHCP client traffic

After I've published a post on how you can use the new router-traffic keyword to minimize the Internet-facing access list you use with CBAC, Euphrates Greene pointed out to me that this feature does not work for client DHCP traffic (if the router is acting as a DHCP client, for example, when connected to a MAN Ethernet environment).

Once you start thinking about what's really going on, it all becomes obvious: as the router has no IP address when it sends the DHCP request, and it sends the DHCP request to a broadcast address (as it doesn't know the IP address of the upstream DHCP server), there is no session that could be entered into the CBAC session table. So you still have to allow all DHCP traffic to your router with an access-list similar to this one:

ip access-list extended Internet
 permit udp any eq bootps any eq bootpc
 deny ip any any

Note: Replace the highlighted any keyword with the actual DHCP server's IP adress if you have it available and you want to have an even more secure IP access-list.

DHCP and BOOTP coexistence

If you have an existing BOOTP environment (for example, a set of old Unix workstations and X-terminals) and want to deploy DHCP on the same LAN segment, you could run into interesting compatibility issues, as the DHCP servers by default responds to BOOTP requests.

However, IOS has an interesting feature when you use a router as a DHCP server: you can tell it to ignore the BOOTP requests with the ip dhcp bootp ignore global configuration command (introduced in 12.2T and 12.3). Even more, the router can respond to DHCP requests and forward BOOTP requests to a non-local BOOTP server configured with the ip helper-address interface configuration command.

Redundant DHCP server

If you want to build a truly redundant LAN infrastructure, you should also have redundant DHCP servers. If you decide to do the DHCP address allocation locally (on the router), you should take care that the two routers acting as DHCP servers don't assign overlapping addresses.

If the address space assigned to a LAN is at least twice as large as the number of LAN-attached devices, you can use the ip dhcp excluded-addresses command to exclude half of the address pool on each router, for example:

ip dhcp pool LAN
 network 192.168.1.0 192.168.0.0 255.255.255.0
!
! Exclude router addresses
ip dhcp excluded-addresses 192.168.0.1 192.168.0.10
!
! Exclude half of the pool
ip dhcp excluded-addresses 192.168.0.128 192.168.0.255
Alternatively, you can rely on the ip dhcp ping packets command; the router will ping an IP address to check whether it's live before assigning it (by default, the router sends two pings with 500 millisecond timeout).

Note: You can also inspect the conflicting IP addresses the router found with the show ip dhcp conflict command.

DHCP response sets the default route

It makes perfect sense in hindsight, but I was nonetheless pleasantly surprised: when the router acting as a DHCP client (configured with the ip address dhcp interface configuration command) receives the DHCP reply packet containing the default gateway option (option #3), it installs a static default route toward that next-hop. Even better, the default route is installed with the administrative distance 254 (floating static route), making sure that the default route you've configured manually or the default route received via a routing protocol are not overwritten.

To add icing on the cake, starting with IOS release 12.3(8)T you can disable this behavior with the no ip dhcp client request router interface-configuration command.The following listing contains a sample debugging session documenting this behavior:

DHCP: Received a BOOTREP pkt
DHCP: Scan: Message type: DHCP Ack
DHCP: Scan: Server ID Option: 192.168.0.1 = C0A80001
DHCP: Scan: Lease Time: 86400
DHCP: Scan: Renewal time: 43200
DHCP: Scan: Rebind time: 75600
DHCP: Scan: Host Name: r4.company.com.
DHCP: Scan: Subnet Address Option: 255.255.255.240
DHCP: Scan: Router Option: 192.168.0.1

... deleted ...

DHCP: Server ID Option: 192.168.0.1
DHCP Host Name Option: r4.company.com.
DHCP: Releasing ipl options:
DHCP: Applying DHCP options:
Setting default_gateway to 192.168.0.1
Adding default route 192.168.0.1
Allocated IP address = 192.168.0.6 255.255.255.240

%DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 192.168.0.6, mask 255.255.255.240, hostname r4

r4#show ip route 0.0.0.0
Routing entry for 0.0.0.0 0.0.0.0, supernet
Known via "static", distance 254, metric 0, candidate default path
Routing Descriptor Blocks:
* 192.168.0.1
Route metric is 0, traffic share count is 1

Unbundle DNS settings from DHCP client

In one of my previous posts I've been writing about the problems I had when the DHCP client on Cisco IOS was messing up the DNS name-servers I've configured manually with the ip name-server configuration command. As is quite usual in Cisco IOS, there's one more know to turn to fix this - the Configurable DHCP Client feature introduced in IOS release 12.3(8)T.

To stop the router's DHCP client from overwriting the static name-server settings, use the no ip dhcp client request dns-nameserver interface configuration command (you can also exclude a few other DHCP options).

DNS resolver in Cisco IOS is auto-configured with parameters from a DHCP reply

If you're using DHCP to get IP interface addresses on your router (using the ip address dhcp interface configuration command), the router will also inherit the DNS resolver settings included in the DHCP reply. Makes sense, but the implementation is "a bit" unexpected: if you configure the DNS name servers manually with the ip name-server address-list command, the ones matching the values in the DHCP reply packet are not included in the running configuration and thus not saved to NVRAM. Even worse, the statically-configured name-servers overwritten by a DHCP reply are lost if the DHCP-configured interface goes down.

To avoid total confusion, you thus have these options:

  • Do not use DHCP to acquire IP interface addresses
  • Make sure the DHCP server does not send DNS-related parameters (a bit hard if you're using DHCP with your ISP)
  • Rely exclusively on DHCP to provide your router with the DNS name server addresses
Here is also an example of what can happen if you mix static configuration with DHCP. We'll start by configuring the name servers and verifying they are configured:
ro#conf t
Enter configuration commands, one per line. End with CNTL/Z.
ro(config)#ip name-server 192.168.2.1 192.168.2.2
ro(config)#^Z
ro#show run | include name-server
ip name-server 192.168.2.1 192.168.2.2
Next, we'll configure DHCP client on an interface and watch the DHCP debugging to see what's actually going on (only parts of debugging printout are included):
ro(config)#interface FastEthernet 0/0
ro(config-if)#ip address dhcp
...
DHCP: Received a BOOTREP pkt
DHCP: Scan: Message type: DHCP Ack
DHCP: Scan: Server ID Option: 192.168.2.1 = C0A80201
DHCP: Scan: Lease Time: 86400
DHCP: Scan: Renewal time: 43200
DHCP: Scan: Rebind time: 75600
DHCP: Scan: Host Name: ro.address.net
DHCP: Scan: Subnet Address Option: 255.255.255.240
DHCP: Scan: Router Option: 192.168.2.1
DHCP: Scan: Domain Name: address.net
DHCP: Scan: DNS Name Server Option: 192.168.2.2
...
DHCP: Applying DHCP options:
Setting default_gateway to 192.168.2.1
Adding default route 192.168.2.1
Adding DNS server address 192.168.2.2
Setting default domain to address.net

%DHCP-6-ADDRESS_ASSIGN: Interface FastEthernet0/0 assigned DHCP address 192.168.2.5, mask 255.255.255.240, hostname ro
The name server received in the DHCP reply (192.168.2.2) is now missing from the running configuration:
ro#show run | include name-server
ip name-server 192.168.2.1