AWS Route 53 white label nameserver setup

Tue 14th Nov 2017 / Tags: #AWS

Also see: AWS CLI setup

Check the registrar supports glue records

I think this is standard, but make sure your domain registrar supports configuring glue records.

If you want to use IPv6, make sure it supports IPv6 glue records too. (LCN does not support IPv6 glue records, so I transferred my domain to Route 53 instead.)

Warning: Transferring a domain can sometimes take 5-10 days, and during the transfer you can't change the nameservers - so either do this in advance, or use IPv4 initially and transfer it once it's all working.

Create a delegation set (reusable group of nameservers)

This first part can only be done via the CLI or IP, not the web console.

aws route53 create-reusable-delegation-set --caller-reference $(date +%s%N)

Example output:

{
    "Location": "https://route53.amazonaws.com/2013-04-01/delegationset/N244H6F5LUSLJ8",
    "DelegationSet": {
        "NameServers": [
            "ns-39.awsdns-04.com",
            "ns-523.awsdns-01.net",
            "ns-1129.awsdns-13.org",
            "ns-1612.awsdns-09.co.uk"
        ],
        "CallerReference": "1512169214076311809",
        "Id": "/delegationset/N244H6F5LUSLJ8"
    }
}

Make a note of the Id and NameServers.

In case you need to see it again:

aws route53 list-reusable-delegation-sets

Get the IPv4 and IPv6 addresses

$ host ns-39.awsdns-04.com
ns-39.awsdns-04.com has address 205.251.192.39
ns-39.awsdns-04.com has IPv6 address 2600:9000:5300:2700::1

$ host ns-523.awsdns-01.net
ns-523.awsdns-01.net has address 205.251.194.11
ns-523.awsdns-01.net has IPv6 address 2600:9000:5302:b00::1

$ host ns-1129.awsdns-13.org
ns-1129.awsdns-13.org has address 205.251.196.105
ns-1129.awsdns-13.org has IPv6 address 2600:9000:5304:6900::1

$ host ns-1612.awsdns-09.co.uk
ns-1612.awsdns-09.co.uk has address 205.251.198.76
ns-1612.awsdns-09.co.uk has IPv6 address 2600:9000:5306:4c00::1

Make a note of these - you will need them later.

Create a hosted zone for the domain

aws route53 create-hosted-zone --caller-reference $(date +%s%N) --delegation-set-id /delegationset/N244H6F5LUSLJ8 --name davejamesmiller.com

Make a note of the HostedZone > Id.

Change the NS records

The rest of this can be done via the Console if you prefer – it's probably easier if you do – but I've included the CLI commands anyway.

Change the nameservers to the custom ones and, as recommended in the documentation, also reduce the TTL until we're sure it's working.

aws route53 change-resource-record-sets --hosted-zone-id /hostedzone/Z2QRBSITGQ197P --change-batch '{
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "davejamesmiller.com",
            "Type": "NS",
            "ResourceRecords": [
                {"Value": "ns1.davejamesmiller.com."},
                {"Value": "ns2.davejamesmiller.com."},
                {"Value": "ns3.davejamesmiller.com."},
                {"Value": "ns4.davejamesmiller.com."}
            ],
            "TTL": 60
        }
    }]
}'

Change the SOA record

The format of an SOA record is:

[primary-nameserver] [admin-email] [serial-number] [refresh-time] [retry-time] [expire-time] [negative-cache-ttl]

The default is something like this:

ns-81.awsdns-10.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

We will change the primary nameserver, admin email and negative cache TTL:

aws route53 change-resource-record-sets --hosted-zone-id /hostedzone/Z2QRBSITGQ197P --change-batch '{
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "davejamesmiller.com",
            "Type": "SOA",
            "ResourceRecords": [
                {"Value": "ns1.davejamesmiller.com. dave.davejamesmiller.com. 1 7200 900 1209600 60"}
            ],
            "TTL": 60
        }
    }]
}'

Create other resource records

I did this by writing zone files and importing them via the AWS Console, to avoid writing lots of JSON in the CLI or manually entering each record in the Console:

; davejamesmiller.com

; Nameservers - use the IP addresses you found above
ns1 60 IN A    205.251.192.39
ns1 60 IN AAAA 2600:9000:5300:2700::1
ns2 60 IN A    205.251.194.11
ns2 60 IN AAAA 2600:9000:5302:b00::1
ns3 60 IN A    205.251.196.105
ns3 60 IN AAAA 2600:9000:5304:6900::1
ns4 60 IN A    205.251.198.76
ns4 60 IN AAAA 2600:9000:5306:4c00::1

; Other records to import
@   1800 IN MX   10 aspmx.l.google.com.
@   1800 IN MX   20 alt1.aspmx.l.google.com.
@   1800 IN MX   20 alt2.aspmx.l.google.com.
@   1800 IN MX   30 aspmx2.googlemail.com.
@   1800 IN MX   30 aspmx3.googlemail.com.
@   1800 IN MX   30 aspmx4.googlemail.com.
@   1800 IN MX   30 aspmx5.googlemail.com.
@   1800 IN SPF  "v=spf1 include:_spf.google.com ~all"
@   1800 IN A    31.25.184.158
@   1800 IN AAAA 2a02:24e0:eda1:14:dbcd:fe82:1721:6e9d
www 1800 IN A    31.25.184.158
www 1800 IN AAAA 2a02:24e0:eda1:14:dbcd:fe82:1721:6e9d

If you prefer to do this via the command line, you may find cli53 simpler than AWS CLI - but I don't think it works with MFA enabled so I couldn't use it.

Change nameservers & create glue records for the primary domain

This will vary depending on your domain registrar.

Change the nameservers to the new white label ones (ns1.davejamesmiller.com, etc.) and enter the IP addresses discovered above where prompted (both IPv4 and IPv6 if supported) to create glue records. e.g.

Nameserver IPv4 (A) IPv6 (AAAA)
ns1.davejamesmiller.com 205.251.192.39 2600:9000:5300:2700::1
ns2.davejamesmiller.com 205.251.194.11 2600:9000:5302:b00::1
ns3.davejamesmiller.com 205.251.196.105 2600:9000:5304:6900::1
ns4.davejamesmiller.com 205.251.198.76 2600:9000:5306:4c00::1

If the domain is registered with Route 53 you can do this via the CLI:

aws route53domains --region us-east-1 update-domain-nameservers --domain-name davejamesmiller.com --nameservers Name=ns1.davejamesmiller.com,GlueIps=205.251.192.39,2600:9000:5300:2700::1 Name=ns2.davejamesmiller.com,GlueIps=205.251.194.11,2600:9000:5302:b00::1 Name=ns3.davejamesmiller.com,GlueIps=205.251.196.105,2600:9000:5304:6900::1 Name=ns4.davejamesmiller.com,GlueIps=205.251.198.76,2600:9000:5306:4c00::1

Then check it worked:

whois davejamesmiller.com

dig ns com
dig ns davejamesmiller.com @a.gtld-servers.net
dig a davejamesmiller.com @ns1.davejamesmiller.com

You should also use a tool like Pingdom DNS check to verify everything is configured correctly.

Change the TTLs to their normal values

Next we want to change all of the 60 second TTLs back to more reasonable values.

The default values in AWS are:

While my previous DNS provider used these values:

I decided to use these values:

Again I did this manually in the console, to avoid writing lots of JSON in the CLI.

Update the other domains

Finally, start using the nameservers for other domains too:

# Create hosted zone using the same delegation set
aws route53 create-hosted-zone --caller-reference $(date +%s%N) --delegation-set-id /delegationset/N244H6F5LUSLJ8 --name djm.me

# Change the NS records
aws route53 change-resource-record-sets --hosted-zone-id /hostedzone/Z1CFBKQ43TFSS9 --change-batch '{
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "djm.me",
            "Type": "NS",
            "ResourceRecords": [
                {"Value": "ns1.davejamesmiller.com."},
                {"Value": "ns2.davejamesmiller.com."},
                {"Value": "ns3.davejamesmiller.com."},
                {"Value": "ns4.davejamesmiller.com."}
            ],
            "TTL": 7200
        }
    }]
}'

# Change the SOA record
aws route53 change-resource-record-sets --hosted-zone-id /hostedzone/Z1CFBKQ43TFSS9 --change-batch '{
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "djm.me",
            "Type": "SOA",
            "ResourceRecords": [
                {"Value": "ns1.davejamesmiller.com. dave.davejamesmiller.com. 1 7200 900 1209600 300"}
            ],
            "TTL": 7200
        }
    }]
}'

# Create other resource records as needed...

# Set the nameservers with the registrar (no glue records this time)
aws route53domains --region us-east-1 update-domain-nameservers --domain-name djm.me --nameservers Name=ns1.davejamesmiller.com Name=ns2.davejamesmiller.com Name=ns3.davejamesmiller.com Name=ns4.davejamesmiller.com