DNSSEC in AWS, the best of the worst
AWS have made it fairly clear that they’re still not supporting DNSSEC in Route53, so let’s run through the options available.
Step 1, not using Route53, there’s no workaround for this, Route53 outright does not support DNSSEC for hosted zones, therefore isn’t an option. This means we have to host our DNS externally, once you’ve picked your DNS provider (which we won’t go into here), you’re ready to set up your DNS record.
The goto at this point is to set up your application in AWS, hopefully behind a load balancer, then CNAME your external DNS onto it, as it good practice with AWS load balancers.
This ends up looking something along the lines of:
# dig app.securedomain.com
app.securedomain.com. 300 IN CNAME aws-lb-1234567890.eu-west-1.elb.amazonaws.com.
aws-lb-1234567890.eu-west-1.elb.amazonaws.com. 49 IN A 126.96.36.199
aws-lb-1234567890.eu-west-1.elb.amazonaws.com. 49 IN A 188.8.131.52
aws-lb-1234567890.eu-west-1.elb.amazonaws.com. 49 IN A 184.108.40.206
So the flow you end up with is, your user looks up app.securedomain.com, now has a valid DNSSEC setup which is great, picks up the CNAME to amazonaws.com, but unfortunately in-line with AWS’ abstinence from DNSSEC, isn’t signed.
In practice, this means that someone trying to repoint your app, can poison your DNS for the amazonaws.com domain rather than your securedomain.com and still replace your site.
This means that DNSSEC and CNAMES onto an AWS load balancer, won’t give you any extra security.
This should be a quick one as we hopefully all know that pointing A records at AWS load balancer IPs is bad. Just to call that out explicitly, setting up your DNS in a third party system, then adding A records to the AWS load balancer IPs, will work, to start with, then one day it will eventually fail as AWS eventually have replaced the IPs in your load balancer that you hardcoded.
Now it’s possible to look those IPs up and keep updating them, but that’s extra work, complexity, and points of failure.
But naturally, AWS have advice here on how to solve this issue…
Static IPs for an Application Load Balancer
AWS have an article that shows you how to add a Network Load Balancer, fronting your Application Load Balancer, as the NLBs let you assign static IPs.
This sounds great on the surface, and then you read through the article and see, as usual, the fix is to build a lambda to patch AWS’ functionality, ultimately looking up the ALB’s IPs, then registering them to the target group that’s used by the NLB. This looks along the lines of:
Now, this can obviously work, but do we really like that as a solution?
Application or Network Load Balancer
We’re now getting somewhere in having determined that actually the NLBs can be assigned static IPs, and therefore can solve that problem of adding A records directly in your external DNS system.
This is a good point to consider whether you actually need an Application Load Balancer. It’s pretty common for these to be the default go-to, mostly due to AWS’ history that these have been the natural evolution of the classic load balancers, and were available long before the Network Load Balancers. The key benefits of the ALBs being the layer 7 routing, so matching hostname/paths and sending them to different target groups, but in many cases, this isn’t actually needed and you’re looking to spin up a load balancer for a single application.
In the initial launch, the NLBs were also lacking the ability to do TLS termination, but that was also solved as of 2019 so also keeps your setup simple allowing you to keep your certificate management in ACM.
So what does our final setup look like?
Working DNSSEC Setup
This leaves us at the point of:
Which finally works, and other than having to have external DNS doesn’t include extra code complexity or moving parts. Let’s take that as a win for the current state of DNSSEC in AWS.