Skip to content

Instantly share code, notes, and snippets.

@SoniEx2

SoniEx2/CDNTP.md Secret

Last active June 25, 2018 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SoniEx2/a12fbdb6d20f9f0567ebe37474b0ac52 to your computer and use it in GitHub Desktop.
Save SoniEx2/a12fbdb6d20f9f0567ebe37474b0ac52 to your computer and use it in GitHub Desktop.

Content Delivery Network Transfer Protocol (CDNTP)

Because the CDN should be considered a man-in-the-middle.

Glossary

This is a glossary of terms specific to this document. You're expected to already know what things like TLS, HTTP, CDN, etc are.

  • CDNTP: Content Delivery Network Transfer Protocol
  • First-party: The client, usually a web browser.
  • Second-party: The service which is making use of a CDN.
  • Third-party: The CDN.

The Issue

All data between the client and service goes through the CDN first, and if you want any results from a CDN (as you should), the encryption (TLS) needs to be terminated at the CDN.

This means that the CDN can not only see all public and private information going through your service, it can also alter data both ways, and you wouldn't know it.

The Solution

CDNTP solves these problems by using encryption and signing.

Cached responses, such as those from most forms of HTTP GET, MUST be signed by the second-party.

Additionally, non-cached requests and responses are double-encrypted.

Client<->CDN

An example CDNTP request looks as following, assuming CDNTP over HTTP/1.1:

GET /index.html HTTP/1.1
CDNTP: 0.1
Host: www.example.com

(TODO maybe add a signature mechanism?)

An example (cached) response:

HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 22:38:34 GMT
CDNTP: 0.1; <SIGNATURE GOES HERE>
CDNTP-Path: GET /index.html
CDNTP-Host: www.example.com
Content-Type: text/plain; charset=UTF-8

etc, you get the idea, body goes here

The signature includes all headers after it until the end of the request. Clients (first-parties) MUST NOT accept unsigned responses (see below). Second-parties SHOULD provide CDNTP-Path and CDNTP-Host response headers. These MUST be signed. If present, clients MUST validate them against the request.

An example private request:

POST / HTTP/1.1
CDNTP: 0.1
Host: www.example.com

<start of TLS handshake, everything from now on gets forwarded to the server. do use SNI here.>
[request, headers, body go here]

The path/URL and the host are visible to the CDN.

An example private response:

<start of TLS handshake>
[response, headers, body go here]

These TLS are verified just like normal TLS.

CDN<->Second-Party

Cached requests and responses look (roughly) the same on this side. (unsigned headers could look different, but that's about it.)

Private requests and responses are basically just TLS in TLS. The request as seen above is completely ignored in the second-party: the POST / HTTP/1.1 lets the CDN know that this is a private request/to forward the body of the request, while the Host header lets the CDN know where to find the host. Only the body of the request is used.

Getting the keys and certificates

So, how does the client authenticate the server? Well, it's simple really. The server needs to send a certificate chain.

This certificate chain must have some "unusual" properties, which makes this protocol slightly incompatible with normal HTTP(S):

  • The CDN certificate is not signed by any valid CA. It's signed by the server.
  • The server certificate MUST be a wildcard certificate. (The CDN SHOULD NOT have DNS access.)

This means it's not strictly TLS, but we use the TLS mechanism to get the certs through.

The backwards incompatibility can be easily mitigated by trusting the cert anyway. Pretty easy!

Recommendations

Have cdntp:// and run it on port 433 (because I always mix up 443 and 433). This would be best for compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment