ANS Exercise 1.4: DNS Fundamentals

ANS Exercise 1.4: DNS Fundamentals

Luc van Donkersgoed

Luc van Donkersgoed

In this exercise we will look at the Domain Name System (DNS) implementation in AWS VPCs. We will look at DNS hostnames, DNS resolution, and Route 53 integration.

This is exercise 1.4 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.4-create-vpc-settings

Select your VPC in the VPC overview page, and look at the Description tab in the bottom. You will see that the options “DNS resolution” and “DNS hostnames” are set to Enabled.

1.4-vpc-details

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.4-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.

DNS Hostnames

When the instance has booted up, SSH to it and run hostname. The result should look like this:

[ec2-user@ip-10-0-0-128 ~]$ hostname
ip-10-0-0-128.eu-west-1.compute.internal

As you can see, the EC2 instance has an internal hostname. This address will be resolvable by any resource within the AWS ecosystem. The .internal TLD will not resolve anywhere outside AWS.

We can also query the EC2 metadata service for the instance’s public hostname:

[ec2-user@ip-10-0-0-128 ~]$ curl http://169.254.169.254/latest/meta-data/public-hostname
ec2-34-246-168-74.eu-west-1.compute.amazonaws.com

This is the Fully Qualified Domain Name (FQDN) for the instance. There are two requirements leading to an EC2 instance having a FQDN:

  1. The instance needs to have a public IP (either a dynamic public IP or an Elastic IP)
  2. The VPC setting DNS hostnames needs to be enabled.

Let’s disable the DNS hostnames setting and see what a instance’s addresses look like then.

Disable DNS Hostnames

Navigate to the VPC console, select your VPC and click “Edit DNS hostnames”.

1.4-edit-dns-hostnames

Uncheck the checkbox and click Save.

1.4-disable-dns-hostnames

Spin up a new EC2 instance using the same settings as before. Then SSH into the instance. Running the same commands now shows these results:

[ec2-user@ip-10-0-0-229 ~]$ hostname
ip-10-0-0-229.eu-west-1.compute.internal
[ec2-user@ip-10-0-0-229 ~]$ curl http://169.254.169.254/latest/meta-data/public-hostname
[ec2-user@ip-10-0-0-229 ~]$

The internal hostname is still there, but there is no public hostname anymore.

DNS Resolution

From one of the instances above, run the command host ip-10-0-0-128.eu-west-1.compute.internal while DNS Hostnames are still disabled in your VPC’s configuration. The result should be like this:

[ec2-user@ip-10-0-0-128 ~]$ host ip-10-0-0-128.eu-west-1.compute.internal
Host ip-10-0-0-128.eu-west-1.compute.internal not found: 3(NXDOMAIN)

Now re-enable the DNS Hostnames in you VPC settings, wait a few minutes, and try again. The result should be updated to this:

[ec2-user@ip-10-0-0-128 ~]$ host ip-10-0-0-128.eu-west-1.compute.internal
ip-10-0-0-128.eu-west-1.compute.internal has address 10.0.0.128

You can resolve any hostname in this format, regardless whether you have resources with that hostname:

[ec2-user@ip-10-0-0-128 ~]$ host ip-10-2-3-128.eu-west-1.compute.internal
ip-10-2-3-128.eu-west-1.compute.internal has address 10.2.3.128

Resolving public addresses

Resolving the public DNS name (eg. ec2-34-246-168-74.eu-west-1.compute.amazonaws.com) from your laptop would result in its public address:

➜  ~ host ec2-34-246-168-74.eu-west-1.compute.amazonaws.com
ec2-34-246-168-74.eu-west-1.compute.amazonaws.com has address 34.246.168.74

Like the private hostnames, these addresses always resolve, whether they are in use or not.

When you try to resolve a public address you own from within the same VPC, the AWS DNS server will return the private address, but when you don’t own the resource, the public address is returned:

[ec2-user@ip-10-0-0-229 ~]$ host ec2-34-246-168-74.eu-west-1.compute.amazonaws.com
ec2-34-246-168-74.eu-west-1.compute.amazonaws.com has address 10.0.0.128
[ec2-user@ip-10-0-0-229 ~]$ host ec2-34-246-168-88.eu-west-1.compute.amazonaws.com
ec2-34-246-168-88.eu-west-1.compute.amazonaws.com has address 34.246.168.88

The AWS DNS server

If your VPC has DNS Resolution set to enabled, AWS provides an DNS server for the resources in your environment. This server resolves both private resources (eg. ip-10-2-3-128.eu-west-1.compute.internal) and public resources (eg. sentia.com).

The AWS DNS server is available at your subnet’s base address + 2 (10.0.0.2 in our example), but can also be reached at 169.254.169.253 (not to be confused with the metadata service at 169.254.169.254).

[ec2-user@ip-10-0-0-229 ~]$ host -t A sentia.com 10.0.0.2
Using domain server:
Name: 10.0.0.2
Address: 10.0.0.2#53
Aliases:

sentia.com has address 52.233.128.61
[ec2-user@ip-10-0-0-229 ~]$ host -t A sentia.com 169.254.169.253
Using domain server:
Name: 169.254.169.253
Address: 169.254.169.253#53
Aliases:

sentia.com has address 52.233.128.61

By default, all DNS queries on EC2 instances will be forwarded to the AWS DNS server. As discussed in the previous exercise (DHCP Fundamentals
), this server has been configured in the instance’s /etc/resolv.conf:

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

The last line in this file defines the DNS server’s address.

The line before that (search eu-west-1.compute.internal) is the search domain used when a DNS name without domain (eg. ip-10-0-1-2 is queried. When the domain is missing, the domain specified in the search line is used instead. For example:

[ec2-user@ip-10-0-0-229 ~]$ host ip-10-0-1-2
ip-10-0-1-2.eu-west-1.compute.internal has address 10.0.1.2

Disabling the AWS DNS server

The AWS DNS server can be disabled in the VPC settings. When you do, two things happen:

  1. The DNS server at your subnet’s base address + 2 / 169.254.169.253 is no longer reachable.
  2. DNS hostnames are disabled, just like when you would have manually set the the DNS hostnames option to disabled.

Let’s disable the DNS resolution option and verify this:

1.4-edit-dns-resolution

1.4-disable-dns-resolution

[ec2-user@ip-10-0-0-229 ~]$ host ip-10-0-1-2 169.254.169.253
;; connection timed out; no servers could be reached
[ec2-user@ip-10-0-0-229 ~]$ host ip-10-0-1-2 10.0.0.2
;; connection timed out; no servers could be reached
[ec2-user@ip-10-0-0-229 ~]$ curl http://169.254.169.254/latest/meta-data/public-hostname

With DNS resolution disabled, there is no AWS DNS server anymore, nor do we have a public hostname.

Integration with Route 53

For the next section, make sure DNS hostnames and DNS resolution are enabled for your VPC.

1.4-vpc-details

Now resolve sentia.com from an EC2 instance:

[ec2-user@ip-10-0-0-229 ~]$ host sentia.com
sentia.com has address 52.233.128.61

The result is a public address. But a common scenario would require an EC2 instance to resolve the target’s private address, for example if you want to route traffic over VPN.

In this example, when a customer wants to visit sentia.com, the hostname for sentia.com should resolve to the public address. But when an internal system needs to connect to sentia.com, the hostname should resolve to its private address (eg. 10.2.3.4).

As we’ve seen before, the AWS DNS server already does something like this for EC2 hostnames:

[ec2-user@ip-10-0-0-229 ~]$ host ec2-34-246-168-74.eu-west-1.compute.amazonaws.com
ec2-34-246-168-74.eu-west-1.compute.amazonaws.com has address 10.0.0.128
[ec2-user@ip-10-0-0-229 ~]$ host ec2-34-246-168-88.eu-west-1.compute.amazonaws.com
ec2-34-246-168-88.eu-west-1.compute.amazonaws.com has address 34.246.168.88

With Route 53 Private Zones we can achieve the same result for every domain. Let’s build that now.

Navigate to the AWS Route 53 console and click the “Create Hosted Zone” button.

1.4-create-hosted-zone

In the next screen, fill in your domain name, select the Private Hosted Zone type and select your VPC. The screen will remind / warn you that DNS hostnames and DNS resolution need to be enabled for your VPC.

1.4-create-hosted-zone-2

If you would select “Public Hosted Zone”, the domain would be publicly resolvable. By setting it to “Private Hosted Zone” we will assure that it will only be used within the VPC.

Click Create. Then click the Create Record Set button. Fill in the following details:

1.4-create-record-set

Click the “Create” button at the bottom of the page, and our private hosted zone is complete.

Navigate back to the SSH session to your EC2 instance and run host sentia.com:

[ec2-user@ip-10-0-0-128 ~]$ host sentia.com
sentia.com has address 10.2.3.4

Hurrah!

Conclusion

In this exercise we’ve seen how AWS assigns public and private hostnames to resources in a VPC if DNS hostnames and DNS resolution are enabled.

If DNS resolution is enabled, the AWS-managed DNS server is available at your subnet’s base address + 2 and 169.254.169.253.

If both DNS hostnames and DNS resolution are enabled, AWS supports overriding public DNS records with private DNS.

In a future exercise we will replace the AWS-managed DNS server with one of our own.

Luc van Donkersgoed
Luc van Donkersgoed