Test DHCP Relaying with netlab « ipSpace.net blog
[ad_1]
After figuring out how DHCP relaying works, I decided to test it out in a lab. netlab has no DHCP configuration module (at the moment); the easiest way forward seemed to be custom configuration templates combined with a few extra attributes.
Lab Topology
This is how I set up the lab:
- I created simple lab topology with DHCP server (IOSv), DHCP client (another IOSv), and a relaying node that could be anything that supports DHCP relaying.
Lab IP addressing
Interface IPv4 address Description
=========================================================
srv (10.0.0.1/32)
GigabitEthernet0/1 10.1.0.2/30 srv -> relay
relay (10.0.0.2/32)
GigabitEthernet0/1 10.1.0.1/30 relay -> srv
GigabitEthernet0/2 172.16.0.2/24 relay -> user
user (10.0.0.3/32)
GigabitEthernet0/1 172.16.0.3/24 user -> relay
- I used interface attribute dhcp.client (boolean) on the client and dhcp.server (node name, string) on the relay node. This is how I defined those attributes:
Extra DHCP attributes
defaults.attributes:
link.dhcp:
client: bool
server: str
DHCP client, relay, and server groups
groups:
dhcp_server:
members: [ srv ]
module: [ ospf ]
config: [ dhcp-server ]
device: iosv
dhcp_client:
members: [ user ]
config: [ dhcp-client ]
device: iosv
switch:
members: [ relay ]
module: [ ospf ]
config: [ dhcp-relay ]
- I’m running OSPF between DHCP relay and DHCP server. While that’s not how you’d set up a typical DHCP server, it allows me to relay DHCP requests to the DHCP server loopback interface.
- Finally, I had to define the nodes and the links:
Nodes and links
nodes: [ srv, relay, user ]
links:
- relay-srv
- user:
dhcp.client: True
relay:
dhcp.server: srv
type: lan
I set the link type on the link between user and relay switch to LAN to ensure it gets a /24 prefix. Doing DHCP on a /30 prefix is boring.
As always, you can find the final topology file on GitHub.
Configuration Templates
Now for the fun part: custom configuration templates (also on GitHub). The client template was trivial:
- Find interfaces with dhcp.client attribute
- Remove static IPv4 address from them
- Enable DHCP client on the interface
DHCP client configuration template
% for intf in interfaces if intf.dhcp.client is defined and intf.dhcp.client %
interface intf.ifname
no ip address
ip address dhcp
% endfor %
The relaying template was already a bit more convoluted. I had to find the interfaces with dhcp.server attribute and then find the loopback IP address of the DHCP server to use in the helper-address command. Interestingly, I could use identical template for Cisco IOSv and Arista vEOS.
DHCP relay configuration template
% for intf in interfaces if intf.dhcp.server is defined %
interface intf.ifname
ip helper-address hostvars[intf.dhcp.server].loopback.ipv4
% endfor %
Finally the DHCP server template. This one is a beast:
- It iterates over all other nodes in the Ansible inventory and finds interfaces with dhcp.server attribute (relaying interfaces)
- For each relaying interface, the template excludes its IPv4 address from the DHCP pool, and creates a corresponding pool with the relaying interface IPv4 address as the default router.
- I also turned on debugging in the configuration template so I could log into the DHCP server and inspect the logs immediately after netlab up completes its job.
DHCP server configuration template
logging buffered
no service timestamp debug
!
do debug ip dhcp server packet
do debug ip dhcp server event
!
% for h,v in hostvars.items() %
% for intf in v.interfaces if intf.dhcp.server is defined and intf.ipv4 is defined %
ip dhcp excluded-address intf.ipv4
% endfor %
% endfor %
!
% for h,v in hostvars.items() %
% for intf in v.interfaces if intf.dhcp.server is defined and intf.ipv4 is defined %
!
ip dhcp pool p_ipaddr('network')
network ipaddr('network') intf.ipv4
default-router ipaddr('address')
% endfor %
% endfor %
Here are the extra configuration commands generated by these templates:
Cisco IOS DHCP client configuration
interface GigabitEthernet0/1
no ip address
ip address dhcp
Cisco IOS DHCP relay configuration
interface GigabitEthernet0/2
ip helper-address 10.0.0.1
Cisco IOS DHCP server configuration (including debugging commands)
logging buffered
no service timestamp debug
!
do debug ip dhcp server packet
do debug ip dhcp server event
!
ip dhcp excluded-address 172.16.0.2
!
!
ip dhcp pool p_172.16.0.0
network 172.16.0.0 255.255.255.0
default-router 172.16.0.2
You can find the final device configurations using Arista EOS on the DHCP relay in the GitHub netlab-example repository.
Does It Work?
You bet. Here’s the printout from the client router:
user#show dhcp lease
...
Temp IP addr: 172.16.0.3 for peer on Interface: GigabitEthernet0/1
Temp sub net mask: 255.255.255.0
DHCP Lease server: 10.1.0.2, state: 5 Bound
DHCP transaction id: EAB
Lease: 86400 secs, Renewal: 43200 secs, Rebind: 75600 secs
Temp default-gateway addr: 172.16.0.2
Next timer fires after: 11:59:35
Retry count: 0 Client-ID: cisco-5254.002c.2b7b-Gi0/1
Client-ID hex dump: 636973636F2D353235342E303032632E
326237622D4769302F31
Hostname: user
There seems to be a tiny glitch in the printout: the DHCP relay is forwarding DHCP requests to 10.0.0.1, but the DHCP client claims it’s talking with DHCP server with IP address 10.1.0.2 – the LAN interface IPv4 address of the DHCP server. The change of IP address is a perfect implementation of RFC 2131 which says:
If the server has received a message through a DHCP relay agent, the server SHOULD choose an address from the interface on which the message was recieved [sic] as the ‘server identifier’ (unless the server has other, better information on which to make its choice).
It’s nice to see things working exactly the way they should 😉
Fighting Repeatability Crisis One Lab at a Time
Want to run this lab on your own, or try it out with different devices? No problem:
Coming Up Next
Simple DHCP relaying works, but what about inter-VRF DHCP relaying? That’s the topic of the next blog post in this series.
[ad_2]
Source link