Skip to content

CDN overview

To be able to support customers and visitors, our infrastructure relies on a Content Delivery Network (CDN).

From an operational perspective, it is a redundant fast-performant server with copies of assets (CSS, Images, Videos) that relies on a global network to deliver content fast and without sacrificing our website performance.

Content type

Images

Buckets:

  • ixdf--images -> public-images
  • idf--assets -> public-media (deprecated)

Images are a special use case we are leveraging a service to automatically process and optimize any image uploaded to our website. Using a service to handle this means we do not need to spend time maintaining a critical piece of infrastructure. It also ensures that user-generated content is automatically optimized and served in optimal formats.

At the time of writing, we are using the service ImageKit.io to process images. ImageKit operates atop the AWS CloudFront CDN, so these diagrams generally encapsulate the request flow for images, video and other assets (substitute "Image CDN" with "AWS CloudFront" and remove the "Optimize" step).

For images, we currently use two subdomains: public-media and public-images. public-media effectively "points to" the AWS S3 bucket idf--assets and pre-dates our usage of ImageKit. Using the laravel Storage facade will resolve to a filesystem mapped to this bucket.

Please note: Over time the idf--assets bucket has become polluted and disorganized. It is no longer being used to store newly created media or assets and the public-media subdomain is deprecated.

public-images "points to" the AWS S3 bucket ixdf--images. All image-related components of our application (e.g. RTE image uploads, Nova image fields, "classic" admin image uploads) are now using this system. To access this filesystem, you should utilize the class App/Services/Filesystems/ImageFilesystem. Resolving/injecting this class will return a Laravel FilesystemAdapter object pre-configured to access the filesystem.

To maintain the "hygiene" of this filesystem, passing a path in to Laravel FilesystemAdapter methods such as store or putFile is strongly discouraged. Instead, use the static method ImageFilesystem::getPath(). The getPath method maintains a mapping of path "keys" to actual paths in the filesystem. This is to ensure files are uploaded to a logical and consistent path on the filesystem.

First request

Subsequent requests

Video

As per above, the basic CDN and data retrieval flow is consistent with images. Videos are served via two AWS CloudFront distributions: the distinction between them is that videos can be public or private.

Public videos are accessible via the subdomain public-video.interaction-design.org, which is mapped to a CloudFront distribution pointing to the /tv path of the idf--assets S3 bucket. These videos are accessible to site visitors.

Private videos are served via signed URLs and from the CloudFront distribution "Private CDN (Videos)" which points to the S3 bucket idf--video-processed.

Other Assets

There’s an additional subdomain, public-assets mapped to the S3 bucket ixdf--assets. This bucket is intended for non-image-and-video related files, such as templates. The purpose of this distribution is to make sure it is free of third party services (previous image optimization services tested would interfere with serving non-image files).

Creating Distributions

Serving Static Assets

Please, follow the "Deliver Content Fast" guide from AWS. This is a basic guide to help you create a CDN to serve some assets.

Serving S3 from CDN

Another guide from AWS to serve assets but from a S3 bucket. You can check it here.

Serving Private Content

There are several possibilities for signed URLs:

  • Share protected content (copyright)
  • Deliver resource available for a specific group of customers/guests
  • Others

When creating a signed URL you may restrict access to specific folders, or even an entire bucket.

Please follow this guide to be aware of the latest updates on private resources.

It is a very detailed and extensive document, and YES, you'll need to read it IF you want to make any substantial architectural change to content delivery architecture.

CDN Security

We use AWS WAF to secure our CDN, preventing bot and excessive access. We use some built-in WAF rules, plus some exceptions to allow/block certain traffic.

Detecting & Preventing Hackers

To detect & prevent hackers, we currently rely on a simple query. We sign all links to our private video distribution, meaning that having excessive number of failed requests to a video URL is an indicator that the IP address is a malicious one.

Steps

  1. Go to the AWS Console and open the Athena service
  2. Run a saved query named IPs with max errors for all video
  3. Add the IP addresses to either the Hacker or Hackers-IPv6 to block them using WAF.

A safer way to identify hacking attempts is to inspect the CloudFront > Reports & analytics > Popular objects to see if there are any suspicious requests, probably with many rejections. You can query Athena for the suspicious resource & extract the IP addresses.