Because the CDN should be considered a man-in-the-middle.
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.
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.
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.
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.
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.
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!
Have cdntp://
and run it on port 433 (because I always mix up 443 and 433). This would be best for compatibility.