ANS Exercise 1.3: DHCP Fundamentals

January 17, 2020

ANS Exercise 1.3: DHCP Fundamentals

In this exercise we will investigate how the Dynamic Host Configuration Protocol (DHCP) is implemented in AWS EC2. We will look at the default implementation, then change the defaults by creating and applying our own DCHP Option Set.

This is exercise 1.3 for the AWS Advanced Networking Specialty training. For an explanation and overview of all exercises, see the overview post.

The exercises are built on the assumption that you’re already familiar with the AWS basics and have achieved at least one associate level AWS certification.

Create a VPC

Log in to your AWS account and navigate to the VPC console. On the VPC Dashboard click the “Launch VPC Wizard” button.

1.2-launch-vpc-wizard

Next, select “VPC with a Single Public Subnet” and click Select.

1.2-select-vpc-configuration

Give the VPC a name and click the “Create VPC” button.

1.3-create-vpc-settings

Launch an EC2 Instance

Navigate to the EC2 console and click the “Launch Instance” button.

1.3-launch-instance

Select the latest Amazon Linux 2 AMI for x86, a t2.micro instance, and enable “Auto-assign Public IP” under instance details:

1.3-auto-assign-public-ip

In Step 6: Configure Security Group, make sure you open port 22 to your IP address. In the last step, select an existing SSH key or create a new one.

Check the EC2 DHCP configuration

SSH into the instance you just launched. Once logged in, run sudo grep dhclient /var/log/messages. This will display all output from the DHCP client running on the instance. The result should look like this:

Jan 17 10:10:15 ip-10-0-0-157 dhclient[2858]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5 (xid=0x5d1a4bfa)
Jan 17 10:10:15 ip-10-0-0-157 dhclient[2858]: DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x5d1a4bfa)
Jan 17 10:10:15 ip-10-0-0-157 dhclient[2858]: DHCPOFFER from 10.0.0.1
Jan 17 10:10:15 ip-10-0-0-157 dhclient[2858]: DHCPACK from 10.0.0.1 (xid=0x5d1a4bfa)
Jan 17 10:10:15 ip-10-0-0-157 NET[2902]: /usr/sbin/dhclient-script : updated /etc/resolv.conf
Jan 17 10:10:15 ip-10-0-0-157 dhclient[2858]: bound to 10.0.0.157 -- renewal in 1612 seconds.

There is already a lot of information here. Let’s go through it line by line.

DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5 (xid=0x5d1a4bfa) - The instance sends out a broadcast to locate available servers.
DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x5d1a4bfa) - The instance sends out a broadcast request for an address.
DHCPOFFER from 10.0.0.1 - The DHCP server running on 10.0.0.1 offers its configuration parameters.
DHCPACK from 10.0.0.1 (xid=0x5d1a4bfa) - The DHCP server running on 10.0.0.1 offers its configuration parameters including the committed network address.
/usr/sbin/dhclient-script : updated /etc/resolv.conf - See below.
bound to 10.0.0.157 -- renewal in 1612 seconds. The client has accepted the IP address 10.0.0.157 as its local address.

The line updated /etc/resolv.conf bears some extra investigation. The /etc/resolv.conf file is used by the Linux DNS system to determine how it should resolve any DNS query. Running a cat /etc/resolv.conf yields the following output:

; generated by /usr/sbin/dhclient-script
search eu-west-1.compute.internal
options timeout:2 attempts:5
nameserver 10.0.0.2

We will look at the meaning of these lines in ANS Exercise 1.4: DNS Fundamentals, but for now it’s important to remember that the DHCP protocol has updated the DNS configuration on the server.

Next, run a cat /var/lib/dhclient/dhclient--eth0.lease. This will give you a lot of additional information about the instance’s DHCP lease:

lease {
  interface "eth0";
  fixed-address 10.0.0.157;
  option subnet-mask 255.255.255.0;
  option routers 10.0.0.1;
  option dhcp-lease-time 3600;
  option dhcp-message-type 5;
  option domain-name-servers 10.0.0.2;
  option dhcp-server-identifier 10.0.0.1;
  option interface-mtu 9001;
  option broadcast-address 10.0.0.255;
  option host-name "ip-10-0-0-157";
  option domain-name "eu-west-1.compute.internal";
  renew 5 2020/01/17 11:47:37;
  rebind 5 2020/01/17 12:12:31;
  expire 5 2020/01/17 12:20:01;
}

Of specific interest is the line routers 10.0.0.1. This tells the instance that its gateway (the next hop) is located at 10.0.0.1. This is propagated into the instance’s route table, which can be verified with route -n:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.0.1        0.0.0.0         UG    0      0        0 eth0
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.169.254 0.0.0.0         255.255.255.255 UH    0      0        0 eth0

Check the VPC DHCP configuration

Navigate back to the VPC console and select your VPC. In the description tab, you should see a “DHCP options set”:

1.3-vpc-details

Click the dopt- name, and you should see the DHCP Options used for this VPC:

1.3-default-dopt-options

This should look a bit familiar; the domain-name matches the search domain in resolv.conf, and the domain-name-servers are set to AmazonProvidedDNS. In ANS Exercise 1.4: DNS we will learn how this translates to the 10.0.0.2 we saw in resolv.conf.

Creating a new VPC DHCP options set

In the VPC console, click the “Create DHCP options set” button. In the next screen, fill in a custom domain name and domain name server, then click “Create DHCP option set”.

1.3-custom-dhcp-options

Then navigate back to your VPC, and click “Edit DHCP options set”.

1.3-edit-dhcp-options

In the next screen, select your new DHCP options set and click Save.

1.3-save-dhcp-options

Spin up a new EC2 instance

The EC2 instance used earlier in this exercise will not quickly update its DHCP configuration to the new options set (although it will when the renew time expires). For now, terminate the old instance and start a new one with the same configuration.

When the new instance is running, SSH into it and run sudo grep dhclient /var/log/messages. The output will be much like the last time:

Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 8 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPOFFER from 10.0.0.1
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPACK from 10.0.0.1 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 NET[2901]: /usr/sbin/dhclient-script : updated /etc/resolv.conf
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: bound to 10.0.0.34 -- renewal in 1570 seconds.

However, when we look at /etc/resolv.conf we will see significant differences:

; generated by /usr/sbin/dhclient-script
search example.com
options timeout:2 attempts:5
nameserver 8.8.8.8

As you can see, the domain-name and domain-name-servers we configured in the VPC settings are now present in the resolv.conf on the EC2 instance.

Running a cat /var/lib/dhclient/dhclient--eth0.lease now displays:

lease {
  interface "eth0";
  fixed-address 10.0.0.34;
  option subnet-mask 255.255.255.0;
  option routers 10.0.0.1;
  option dhcp-lease-time 3600;
  option dhcp-message-type 5;
  option domain-name-servers 8.8.8.8;
  option dhcp-server-identifier 10.0.0.1;
  option interface-mtu 9001;
  option broadcast-address 10.0.0.255;
  option host-name "ip-10-0-0-34";
  option domain-name "example.com";
  renew 5 2020/01/17 11:31:54;
  rebind 5 2020/01/17 11:58:14;
  expire 5 2020/01/17 12:05:44;
}

Automatic updates of DHCP options

As seen in the lease info, every lease has a renew time. When this time arrives, the DHCP client on the instance will request the DHCP server for a new lease.

In the example above, the renew time is set to 2020/01/17 11:31:54;. If we update the VPC DHCP options before that time (eg. change the domain name into my-example.com, the instance will update its configuration automatically:

sudo cat /var/log/messages | grep dhclient | grep -v "Solicit"
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 8 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPOFFER from 10.0.0.1
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: DHCPACK from 10.0.0.1 (xid=0x5463f45b)
Jan 17 11:05:44 ip-10-0-0-34 NET[2901]: /usr/sbin/dhclient-script : updated /etc/resolv.conf
Jan 17 11:05:44 ip-10-0-0-34 dhclient[2857]: bound to 10.0.0.34 -- renewal in 1570 seconds.
Jan 17 11:31:54 ip-10-0-0-34 dhclient[2917]: DHCPREQUEST on eth0 to 10.0.0.1 port 67 (xid=0x5463f45b)
Jan 17 11:31:54 ip-10-0-0-34 dhclient[2917]: DHCPACK from 10.0.0.1 (xid=0x5463f45b)
Jan 17 11:31:54 ip-10-0-0-34 NET[3719]: /usr/sbin/dhclient-script : updated /etc/resolv.conf
Jan 17 11:31:54 ip-10-0-0-34 dhclient[2917]: bound to 10.0.0.34 -- renewal in 1571 seconds.

As you can see, an update was triggered at 11:31:54. Also, /etc/resolv.conf was updated:

cat /etc/resolv.conf
options timeout:2 attempts:5
; generated by /usr/sbin/dhclient-script
search my-example.com example.com
nameserver 8.8.8.8
nameserver 8.8.4.4

And /var/lib/dhclient/dhclient--eth0.lease now looks like this:

lease {
  interface "eth0";
  fixed-address 10.0.0.34;
  option subnet-mask 255.255.255.0;
  option routers 10.0.0.1;
  option dhcp-lease-time 3600;
  option dhcp-message-type 5;
  option domain-name-servers 8.8.8.8;
  option dhcp-server-identifier 10.0.0.1;
  option interface-mtu 9001;
  option broadcast-address 10.0.0.255;
  option host-name "ip-10-0-0-34";
  option domain-name "example.com";
  renew 5 2020/01/17 11:31:54;
  rebind 5 2020/01/17 11:58:14;
  expire 5 2020/01/17 12:05:44;
}
lease {
  interface "eth0";
  fixed-address 10.0.0.34;
  option subnet-mask 255.255.255.0;
  option routers 10.0.0.1;
  option dhcp-lease-time 3600;
  option dhcp-message-type 5;
  option domain-name-servers 8.8.8.8,8.8.4.4;
  option dhcp-server-identifier 10.0.0.1;
  option interface-mtu 9001;
  option broadcast-address 10.0.0.255;
  option host-name "ip-10-0-0-34";
  option domain-name "my-example.com";
  renew 5 2020/01/17 11:58:05;
  rebind 5 2020/01/17 12:24:24;
  expire 5 2020/01/17 12:31:54;
}

Conclusion

In this exercise, we have learned how an EC2 instance requests and receives its DHCP lease. We have seen how we can change the VPC DHCP options in the console, and how any new instance will receive those new settings. Any existing EC2 instance will update its configuration when the DHCP renew time expires.

Luc van Donkersgoed

Luc van Donkersgoed