# Best way to redirect non-CloudFront requests to CloudFront

**URL:** <https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458>\
**Category:** NGINX\
**Created:** [May 3, 2012, 3:06pm UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458 "2012-05-03T15:06:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [May 3, 2012, 3:06pm UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458/1 "2012-05-03T15:06:28Z")

</div>

A summary of what I want to do is to redirect requests for image URL’s  
that don’t come from Amazon’s CloudFront service to CloudFront. This is  
because I’m using origin pull, but what the redirect to be done at the  
nginx level.

Obviously this won’t work:

rewrite ^/(.\*).(png|gif|jpg) [http://abc.cloudfront.net/$1.$2](http://abc.cloudfront.net/$1.$2)

because CloudFront’s original requests will be redirected to itself, and  
also because I’ve got some further rewriting going on for WordPress  
image uploads (such that /files/myimage.png will be redirected to a PHP  
script for some sites, so I need that redirect to still happen and the  
one above to be bypassed in those instances when CloudFront is trying to  
do it’s original lookup).

What I want to do is basically say:

if ($remote\_addr !~ “[abc.cloudfront.net](http://abc.cloudfront.net)”) {  
rewrite ^/(.\*).(png|gif|jpg) [http://abc.cloudfront.net/$1.$2](http://abc.cloudfront.net/$1.$2)  
}

but this isn’t possible (as remote\_addr is an IP that may change) and is  
probably inefficient. Is there a correct way to redirect everything to a  
hostname that doesn’t come from the hostname itself efficiently?

Posted at Nginx Forum:

> **[Best way to redirect non-CloudFront requests to CloudFront](https://forum.nginx.org/read.php?2,226015,226015#msg-226015)**
>
> A summary of what I want to do is to redirect requests for image URL's that don't come from Amazon's CloudFront service to CloudFront. This is because I'm using origin pull, but what the redirect to be done at the nginx level. Obviously this won't...

---

<div class="post-metadata">

**Author:** ![WheresWardy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/db5fbb/32.png) [@WheresWardy](https://www.ruby-forum.com/u/WheresWardy)\
**Post date:** [May 3, 2012, 3:17pm UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458/2 "2012-05-03T15:17:04Z")

</div>

> A summary of what I want to do is to redirect requests for image URL’s  
> that don’t come from Amazon’s CloudFront service to CloudFront. This is  
> …  
> but this isn’t possible (as remote\_addr is an IP that may change) and is  
> probably inefficient. Is there a correct way to redirect everything to a  
> hostname that doesn’t come from the hostname itself efficiently?

Check its user agent instead.

---

<div class="post-metadata">

**Author:** ![WheresWardy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/db5fbb/32.png) [@WheresWardy](https://www.ruby-forum.com/u/WheresWardy)\
**Post date:** [May 3, 2012, 3:45pm UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458/3 "2012-05-03T15:45:01Z")

</div>

Would a regex match in an if statement on the user agent string still be  
efficient in nginx? Presumably this is the only way to do it.

Posted at Nginx Forum:

> **[Re: Best way to redirect non-CloudFront requests to CloudFront](https://forum.nginx.org/read.php?2,226015,226021#msg-226021)**
>
> A summary of what I want to do is to redirect requests for image URL's that don't come from Amazon's CloudFront service to CloudFront. This is because I'm using origin pull, but what the redirect to be done at the nginx level. Obviously this won't...

---

<div class="post-metadata">

**Author:** ![WheresWardy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/db5fbb/32.png) [@WheresWardy](https://www.ruby-forum.com/u/WheresWardy)\
**Post date:** [May 8, 2012, 11:53am UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458/4 "2012-05-08T11:53:45Z")

</div>

OK, in the end I went with:

if ($http\_user\_agent !~ “Amazon CloudFront”) {  
rewrite ^/(.\*).(png|gif|jpg) [http://abc.cloudfront.net/$1.$2](http://abc.cloudfront.net/$1.$2)  
}

which seems to do the trick. Seems like there should be a better way of  
doing what must be quite a common form of rewrite though? (Or is this  
the fast alternative to Apache’s REWRITE\_COND?)

Posted at Nginx Forum:

> **[Re: Best way to redirect non-CloudFront requests to CloudFront](https://forum.nginx.org/read.php?2,226015,226168#msg-226168)**
>
> A summary of what I want to do is to redirect requests for image URL's that don't come from Amazon's CloudFront service to CloudFront. This is because I'm using origin pull, but what the redirect to be done at the nginx level. Obviously this won't...

---

<div class="post-metadata">

**Author:** ![WheresWardy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/db5fbb/32.png) [@WheresWardy](https://www.ruby-forum.com/u/WheresWardy)\
**Post date:** [May 8, 2012, 1:37pm UTC](https://www.ruby-forum.com/t/best-way-to-redirect-non-cloudfront-requests-to-cloudfront/219458/5 "2012-05-08T13:37:50Z")

</div>

On 8 May 2012 10:53, WheresWardy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> OK, in the end I went with:
> 
> if ($http\_user\_agent !~ “Amazon CloudFront”) {  
> rewrite ^/(.\*).(png|gif|jpg) [http://abc.cloudfront.net/$1.$2](http://abc.cloudfront.net/$1.$2)  
> }
> 
> which seems to do the trick. Seems like there should be a better way of  
> doing what must be quite a common form of rewrite though? (Or is this  
> the fast alternative to Apache’s REWRITE\_COND?)

This is an example of the more general “has my request been /from/ the  
CDN I’m using, or has it bypassed it?” problem.

The solution is never to leak the un-CDN’d URIs, and enforce that only  
the CDN can access them (perhaps via basic auth; perhaps via UA  
blocking; perhaps via IP restrictions).

If you’ve already missed that opportunity, and also don’t have a  
dedicated static-assets domain you can CNAME to the CDN, then you  
could look at using their published list of cloudfront IPs along with  
[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/HttpGeoModule) and do something like

```
location ~ \.(png|gif|jpg)$ {
  if ($request_not_from_cloudfront_netblocks) {
    rewrite ^/(.*)$ http://abc.cloudfront.net/$1;
  }
}
```

Yes, it’s not _massively_ different from what you’ve got, but I’d  
personally prefer it as it doesn’t involve a string-based regex only  
invokes the geo/map evaluation for those image suffixes, and isn’t  
externally gameable. Unless “cloudfront netblocks” == “EC2 netblocks”,  
of course, in which case Amazon have been daft.

Yes, it also requires keeping this geo map IP list up to date. Still  
preferable to my mind.

## J

Jonathan M.  
Oxford, London, UK

> **[Jonathan Matthews :: Words Typed, Great Rates For Cash](https://www.jpluscplusm.com)**
