As applications grow, so do the demands for secure and scalable content delivery. Imagine a scenario where sensitive media files, such as images and videos, are stored in Amazon S3, but need to be accessed only by authorised users through an application. With Amazon CloudFront, a powerful content delivery network (CDN), and the use of signed URLs, you can control access to private S3 content while optimising delivery to users worldwide.

In this guide, I’ll walk through setting up Amazon CloudFront to securely distribute content stored in an S3 bucket. I’ll cover how to configure CloudFront with signed URLs to control access, demonstrating how to implement, test, and validate this setup on an Amazon EC2 instance.

Why Use Amazon CloudFront with Signed URLs?

Signed URLs allow you to:

  • Control Access: Serve content exclusively to authenticated users.
  • Optimize Performance: Cache content at CloudFront edge locations for faster delivery.
  • Enhance Security: Protect assets from unauthorized access by setting expiry times and integrating with secure key pairs.

Step 1: Configuring Amazon S3

  1. Create an S3 Bucket
    Start by creating an S3 bucket in the AWS Management Console. Enable Block Public Access to prevent public access to files by default. This ensures that only authorized CloudFront requests can access your content.
  2. Upload Content
    Organize and upload your media files (e.g., images, videos) in a folder within the S3 bucket, such as media/.

Step 2: Setting Up CloudFront with Signed URLs

  1. Create a CloudFront Distribution
    • Origin Domain: Select your S3 bucket as the origin for the distribution.
    • Restrict Bucket Access: Enable and create an Origin Access Identity (OAI), allowing only CloudFront to access the bucket.
    • Viewer Protocol Policy: Set it to Redirect HTTP to HTTPS for secure access.
    • Restrict Viewer Access: Enable this option to require signed URLs for access.
  2. Create a Key Group in CloudFront
    A key group holds the public keys required to validate signed URLs:

Generate a key pair:

openssl genrsa -out private_key.pem 2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
  • Upload the public key in the Public Keys section of CloudFront and add it to the key group.

Step 3: Integrating Signed URL Generation in Your Application

To generate signed URLs, I’ll use a PHP script to dynamically create expiring URLs based on the requested S3 content. Below is the code that leverages AWS SDK for PHP:

require ‘vendor/autoload.php’;
use Aws\CloudFront\CloudFrontClient;

function getSignedUrl($fileKey) {
    $cloudfrontDomain = ‘https://<YOUR_CLOUDFRONT_DOMAIN>.cloudfront.net’;
    $privateKeyPath = ‘/path/to/private_key.pem’;
    $keyPairId = ‘<YOUR_KEY_PAIR_ID>’;

    $cloudFrontClient = new CloudFrontClient([
        ‘region’  => ‘us-east-1’,
        ‘version’ => ‘latest’,
    ]);

    $expires = time() + 300; // URL expires in 5 minutes

    return $cloudFrontClient->getSignedUrl([
        ‘url’         => $cloudfrontDomain . ‘/’ . $fileKey,
        ‘expires’     => $expires,
        ‘private_key’ => $privateKeyPath,
        ‘key_pair_id’ => $keyPairId,
    ]);
}

// Example usage
$signedUrl = getSignedUrl(‘media/sample-image.jpg’);
echo $signedUrl;

This script will create a temporary, signed CloudFront URL for any file specified. You can integrate this function into your application to generate secure URLs as needed.

Step 4: Testing the Setup on an Amazon EC2 Instance

  1. Upload Files to EC2
    Place the PHP script, private key file (private_key.pem), and any necessary dependencies on your EC2 instance.

Run the Test Script
SSH into the EC2 instance, navigate to the test folder, and execute the PHP script:

php test_signed_url.php
  1. Verify the Signed URL
    Copy the generated URL from the output and paste it into your browser. The link should work and, after the expiration time, should no longer be accessible.

Security and Optimization Benefits

With this setup:

  • Security: Files are kept private, with access controlled by signed URLs.
  • Cost Efficiency: Reduced S3 load, as content is cached at CloudFront edge locations.
  • Scalability: CloudFront handles surges in traffic, ensuring reliability and performance.

Conclusion

By combining Amazon CloudFront with signed URLs, you unlock a powerful mechanism to securely and efficiently serve media content. This approach is ideal for applications requiring controlled access to S3 content, while benefiting from the global distribution capabilities of CloudFront.