Reputation: 31871
I'm using origin servers on CloudFront (as opposed to s3) with signed URLs. I need a way to ensure that requests to my server are coming only from CloudFront. That is, a way to prevent somebody from bypassing CloudFront and requesting a resource directly on my server. How can this be done?
Upvotes: 5
Views: 2613
Reputation: 1981
AWS have finally created an AWS managed prefix list for CloudFront to Origin server requests. So no more need for custom Lambdas updating Security Groups etc.
Use the prefix com.amazonaws.global.cloudfront.origin-facing in your Security Groups etc.
See the following links for more info:
Upvotes: 5
Reputation: 1
I ended up creating 3 Security Groups filled solely with CloudFront IP addresses.
I found the list of IPs on this AWS docs page.
If you want to just copy and paste the IP ranges into the console, you can use this list I created:
Regional:
13.113.196.64/26, 13.113.203.0/24, 52.199.127.192/26, 13.124.199.0/24, 3.35.130.128/25, 52.78.247.128/26, 13.233.177.192/26, 15.207.13.128/25, 15.207.213.128/25, 52.66.194.128/26, 13.228.69.0/24, 52.220.191.0/26, 13.210.67.128/26, 13.54.63.128/26, 99.79.169.0/24, 18.192.142.0/23, 35.158.136.0/24, 52.57.254.0/24, 13.48.32.0/24, 18.200.212.0/23, 52.212.248.0/26, 3.10.17.128/25, 3.11.53.0/24, 52.56.127.0/25, 15.188.184.0/24, 52.47.139.0/24, 18.229.220.192/26, 54.233.255.128/26, 3.231.2.0/25, 3.234.232.224/27, 3.236.169.192/26, 3.236.48.0/23, 34.195.252.0/24, 34.226.14.0/24, 13.59.250.0/26, 18.216.170.128/25, 3.128.93.0/24, 3.134.215.0/24, 52.15.127.128/26, 3.101.158.0/23, 52.52.191.128/26, 34.216.51.0/25, 34.223.12.224/27, 34.223.80.192/26, 35.162.63.192/26, 35.167.191.128/26, 44.227.178.0/24, 44.234.108.128/25, 44.234.90.252/30
Global:
120.52.22.96/27, 205.251.249.0/24, 180.163.57.128/26, 204.246.168.0/22, 205.251.252.0/23, 54.192.0.0/16, 204.246.173.0/24, 54.230.200.0/21, 120.253.240.192/26, 116.129.226.128/26, 130.176.0.0/17, 99.86.0.0/16, 205.251.200.0/21, 223.71.71.128/25, 13.32.0.0/15, 120.253.245.128/26, 13.224.0.0/14, 70.132.0.0/18, 13.249.0.0/16, 205.251.208.0/20, 65.9.128.0/18, 130.176.128.0/18, 58.254.138.0/25, 54.230.208.0/20, 116.129.226.0/25, 52.222.128.0/17, 64.252.128.0/18, 205.251.254.0/24, 54.230.224.0/19, 71.152.0.0/17, 216.137.32.0/19, 204.246.172.0/24, 120.52.39.128/27, 118.193.97.64/26, 223.71.71.96/27, 54.240.128.0/18, 205.251.250.0/23, 180.163.57.0/25, 52.46.0.0/18, 223.71.11.0/27, 52.82.128.0/19, 54.230.0.0/17, 54.230.128.0/18, 54.239.128.0/18, 130.176.224.0/20, 36.103.232.128/26, 52.84.0.0/15, 143.204.0.0/16, 144.220.0.0/16, 120.52.153.192/26, 119.147.182.0/25, 120.232.236.0/25, 54.182.0.0/16, 58.254.138.128/26, 120.253.245.192/27, 54.239.192.0/19, 18.64.0.0/14, 120.52.12.64/26, 99.84.0.0/16, 130.176.192.0/19, 52.124.128.0/17, 204.246.164.0/22, 13.35.0.0/16, 204.246.174.0/23, 36.103.232.0/25, 119.147.182.128/26, 118.193.97.128/25, 120.232.236.128/26, 204.246.176.0/20, 65.8.0.0/16, 65.9.0.0/17, 120.253.241.160/27, 64.252.64.0/18
I'd like to note that by default, Security Groups only allow a maximum of 60 inbound and outbound rules each, which is why I'm splitting these up 122 IPs into 3 security groups.
After creating your 3 Security Groups, attach them to your EC2 (you can attach multiple Security Groups to an EC2). I left the EC2's default Security Group to only allow SSH traffic from my IP address.
Then you should be good to go! This forces users to use your CloudFront distribution and keeps your EC2's IP/DNS private.
Upvotes: 0
Reputation: 745
I've just done this for myself, and thought I'd leave the answer here where I started my search.
Here's the few lines you need to put in your .htaccess (assuming you've already turned the rewrite engine on):
RewriteCond %{HTTP_HOST} ^www-origin\.example\.com [NC]
RewriteCond %{HTTP_USER_AGENT} !^Amazon\ CloudFront$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
This will redirect all visitors to your Cloudfront distribution - https://example.com in this, um, example - and only let www-origin.example.com work for Amazon CloudFront. If your website code is also on a different URL (a development or staging server, for example) this won't get in the way.
Caution: the user-agent is guessable and spoofable; a more secure way of achieving this would be to set a custom HTTP header in Cloudfront, and check for its value in .htaccess.
Upvotes: 1
Reputation: 61551
As per the documentation, there's no support for that yet. The only thing I can think of is you can restrict more access, although not entirely by just allowing only Amazon IP addresses to your webserver. They should be able to provide them to you (IP address ranges) as they have provided them to us.
This what the docs say:
Using an HTTP Server for Private Content
You can use signed URLs for any CloudFront distribution, regardless of whether the origin is an Amazon S3 bucket or an HTTP server. However, for CloudFront to access your objects on an HTTP server, the objects must remain publicly accessible. Because the objects are publicly accessible, anyone who has the URL for an object on your HTTP server can access the object without the protection provided by CloudFront signed URLs. If you use signed URLs and your origin is an HTTP server, do not give the URLs for the objects on your HTTP server to your customers or to others outside your organization.
Upvotes: 1