Perimeter security with Fastly edge and AWS — Part II

This post talks about how to secure your cloud perimeter with AWS and Fastly edge. This is part 2 in a series covering the communication flow, TLS options, and example configurations.

Perimeter security with Fastly edge and AWS — Part II

This is part II of a series discussing how to secure the perimeter using AWS and Fastly.

In Part I, we covered some of the basic concepts and background context necessary to determine how to architect a perimeter security solution with both platforms.

In this article, we will cover the actual implementation consisting of the following:

  • Top-level architecture and flow
  • TLS configuration
  • DNS CNAME configuration
  • High-level Architecture and Flow

The following figure shows the high-level flow and end-to-end communication diagram of the solution we’ve employed:

Network Flow

In our example, we actually have a few endpoints that are used to split API and application, but we`ve kept it simple in this example. The following flow will be described below:

  1. If the client tries to access the origin endpoints directly they are blocked access as only known IPs (Fastly POPs) are allowed to talk to origin
  2. When client resolves foo.bar.com DNS resolves these to the fastly endpoints (e.g. k.sni.global.fastly.net)
  3. Client sends request which is done directly to Fastly
  4. Fastly handles the request and can throttle (rate-limiting), or block (DDoS/WAF)
  5. IF the request is denied or throttled the response is sent back to the client
  6. Depending on the endpoint you may require a valid auth token (e.g. JWT). At this point we have Rust code running in Fastly edge which is used to inspect and validate JWT tokens and redirect if necessary
  7. IF an auth token is required we redirect the client to the IDP (e.g. Auth0, Google, etc.) to authenticate
  8. Once the client has a token we inspect and validate the auth token and ensure they are able to access the endpoint (using same Rust code running in Fastly edge above)
  9. After the auth token has been validated, we have the possibility to augment the request before it is forwarded to the backend
  10. Authorization can be performed at the edge before authorizing the request to be sent to origin
  11. Request is sent from Fastly to origin
  12. Origin performs auth token validation, performs authorization, and handles the request
  13. Origin sends response back to Fastly which in turn forwards to the client

TLS configuration

Certificates are essential to prove and validate a site is who they say they are as well as provide the necessary keys to facilitate encrypted communication. Before we configure DNS we need to configure TLS certificates for each publically accessible endpoint.

When it comes to TLS, there are a few core options:

  • TLS v1.3
  • TLS v1.3 + 0-RTT
  • HTTP/3 & TLS v1.3 + 0-RTT

0-RTT

0-RTT stands for zero round trip time resumption which allows the client to start sending requests before the TLS handshake completes.

In the traditional flow you`d see something similar to the following:

TLS handshake without 0-RTT

With 0-RTT the flow is more like the following (changes highlighted in bold):

TLS handshake with 0-RTT

HTTP/3 (QUIC)

QUIC takes this even a step further and allows the client to send data in the very first round trip and not wait for TCP/TLS handshakes.

With QUIC the flow is similar to the following:

TLS handshake QUIC

As you can both allow you to send application data (HTTP request) before waiting to the TLS ServerHello response which does reduce some latency. Now it all sounds great, but some potential attack vectors need to be considered before allowing.

For example, because you can perform requests before the TLS handshake completes there is the potential possibility of sending requests which are non-encrypted. There is also the potential possibility for man-in-the-middle replay attack where an attacker could intercept the TLS ClientHello and HTTP requests, and reply those to the server.

There are things like RFC8470 which can tell the client to resend the data after the handshake is completed.

Which one to choose?

By default things will use TLS v1.3, however, there are some very interesting performance implications and benefits of 0-RTT/QUIC. This comes down to the following:

  • Is latency a concern?
  • Is the server capable of 0-RTT/QUIC?
  • Are things RFC8470 (Too Early) compliant?

Luckily all of the major CDN vendors are RFC8470 compliant and send the Early-Data header when 0-RTT is enabled which means if you want to use those options they are possible with minimal risk. NOTE: I say minimal as there are always threat vectors introduced with any change.

We have noticed significant performance improvements when moving from TLS-1.2 to TLS-1.3. At the time of writing this O-RTT is only supported from clients to Fastly and not from Fastly to origin servers.

Fastly TLS configuration

In the Fastly console navigate to Secure then Manage TLS certificates and click on Secure another domain. Follow the guide to create the certificates for your endpoints (they will be assigned to domains in the Edge service automatically).

Follow the guides and apply the activations necessary to the TLS configuration. For example, here you can see we have enabled all 3:

Depending on the TLS activations you will get CNAME records that will be used in your DNS configuration.

DNS configuration

One you have your TLS configurations performed it is now time to create the DNS CNAME entries to point things to Fastly.

For example, if you wanted to use HTTP/3 & TLS v1.3+0-RTT you would configure your CNAME record to point to n.sni.global.fastly.net.

; <<>> DiG 9.16.1-Ubuntu <<>> foo.bar.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63760
;; flags: qr rd ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available;; QUESTION SECTION:
;foo.bar.com. IN A;; ANSWER SECTION:
foo.bar.com. 0 IN CNAME n.sni.global.fastly.net.
k.sni.global.fastly.net. 0 IN A 151.101.2.137
k.sni.global.fastly.net. 0 IN A 151.101.66.137
k.sni.global.fastly.net. 0 IN A 151.101.130.137
k.sni.global.fastly.net. 0 IN A 151.101.194.137;; Query time: 50 msec
;; SERVER: 172.29.208.1#53(172.29.208.1)
;; WHEN: Thu Apr 14 09:29:47 CDT 2022
;; MSG SIZE rcvd: 168

That covers this part, in the next part we will cover AWS configuration!

essential