# Hotlink protection before proxy when using proxy\_pass?

**URL:** <https://www.ruby-forum.com/t/hotlink-protection-before-proxy-when-using-proxy-pass/220051>\
**Category:** NGINX\
**Created:** [May 25, 2012, 6:07pm UTC](https://www.ruby-forum.com/t/hotlink-protection-before-proxy-when-using-proxy-pass/220051 "2012-05-25T18:07:06Z")\
**Posts on this page:** 3\
**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 25, 2012, 6:07pm UTC](https://www.ruby-forum.com/t/hotlink-protection-before-proxy-when-using-proxy-pass/220051/1 "2012-05-25T18:07:06Z")

</div>

Hi,

I have nginx 1.3.0 configured for a server that forwards to a proxy

server {  
server\_name dev.local.lan;  
listen 192.168.1.100:80;  
root /var/empty;  
access\_log /var/log/nginx/access.log  
main;  
rewrite\_log on;  
ssl off;  
location / {  
proxy\_pass [http://PROXY](http://PROXY);  
proxy\_redirect off;  
proxy\_set\_header Host $host;  
proxy\_set\_header X-Real-IP $remote\_addr;  
proxy\_connect\_timeout 600s;  
proxy\_read\_timeout 600s;  
}  
}

It works like it should.

192.168.1.100 is the IP of my workstation; the server is on this same  
workstation while I develop.

I want to add hotlink protection at the nginx so attempted hotlinks from  
unauthorized hosts never get passed to the proxy, but all OK image  
requests do as usual.

Using

[http://nginxlibrary.com/hotlink-protection/](http://nginxlibrary.com/hotlink-protection/)

I modify the server config

server {  
server\_name dev.local.lan;  
listen 192.168.1.100:80;  
root /var/empty;  
access\_log /var/log/nginx/access.log  
main;  
rewrite\_log on;  
ssl off;

- 

```
          location ~* \.(png|gif|jpg|jpeg|swf|ico)(\?[0-9]+)?$ {

```

- 

```
                  valid_referers none blocked dev.local.lan

```

\*.dev.local.lan;

- 

```
                  if ($invalid_referer) {

```

- 

```
                          return 403;

```

- 

```
                  }

```

- 

```
          }

```

location / {  
proxy\_pass [http://PROXY](http://PROXY);  
proxy\_redirect off;  
proxy\_set\_header Host $host;  
proxy\_set\_header X-Real-IP $remote\_addr;  
proxy\_set\_header X-Forwarded-For  
$proxy\_add\_x\_forwarded\_for;  
proxy\_set\_header X-Client-Verify SUCCESS;  
proxy\_connect\_timeout 600s;  
proxy\_read\_timeout 600s;  
}  
}

With this config, If I nav as usual to my site root

[http://dev.local.lan](http://dev.local.lan)

I get my site content displayed in the browser – minus ANY images.

And in the logs lots of these,

==\> /var/log/nginx/error.log \<==  
2012/05/25 08:52:37 [error] 21132#0: \*48 open()  
“/var/empty/img/img1.png” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/img1.png HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/](http://dev.local.lan/)”  
2012/05/25 08:52:37 [error] 21132#0: \*49 open()  
“/var/empty/img/img2.png” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/img2.png HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/](http://dev.local.lan/)”  
2012/05/25 08:52:37 [error] 21132#0: \*51 open()  
“/var/empty/img/img3.png” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/img3.png HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/](http://dev.local.lan/)”  
2012/05/25 08:52:37 [error] 21132#0: \*50 open()  
“/var/empty/img/img4.png” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/img4.png HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/](http://dev.local.lan/)”  
2012/05/25 08:52:37 [error] 21132#0: \*48 open()  
“/var/empty/img/imgA.gif” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/imgA.gif HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/css/css\_i9LjMH-EfBMHZV516oBxThl0uqd7YYp4V7x4fuvUFVs.css](http://dev.local.lan/css/css_i9LjMH-EfBMHZV516oBxThl0uqd7YYp4V7x4fuvUFVs.css)”  
2012/05/25 08:52:37 [error] 21132#0: \*50 open()  
“/var/empty/img/img4.png” failed (2: No such file or directory),  
client: 192.168.1.100, server: dev.local.lan, request: “GET  
/img/img4.png HTTP/1.1”, host: “dev.local.lan”, referrer:  
“[http://dev.local.lan/](http://dev.local.lan/)”  
…

The anti-hotlink stanza IS having an effect, just not the one I want.

What do I need to correct?

RandyK

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 25, 2012, 6:28pm UTC](https://www.ruby-forum.com/t/hotlink-protection-before-proxy-when-using-proxy-pass/220051/2 "2012-05-25T18:28:12Z")

</div>

> The anti-hotlink stanza IS having an effect, just not the one I want.  
> What do I need to correct?

It is because the regular expression locations are matched first (  
[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/HttpCoreModule#location) ).

As in:

location ~\* .(png|gif|jpg|jpeg|swf|ico)(?[0-9]+)?$ {  
is processed first and since nginx doesn’t merge/apply directives from  
multiple (matching) location blocks the proxy\_pass defined in  
‘location /’ is not effective.

So you either have to duplicate the proxy\_\* block:

location ~\* .(png|gif|jpg|jpeg|swf|ico)(?[0-9]+)?$ {  
valid\_referers none blocked dev.local.lan \*.dev.local.lan;

```
if ($invalid_referer) {
         return 403;
}
proxy_pass http://PROXY;
proxy_redirect off;
.....

```

}

or use nested locations (I think it should work):

location / {  
proxy\_pass [http://PROXY](http://PROXY);  
proxy\_redirect off;  
…

```
location ~* \.(png|gif|jpg|jpeg|swf|ico)(\?[0-9]+)?$ {
     valid_referers none blocked dev.local.lan *.dev.local.lan;
     if ($invalid_referer) {
         return 403;
    }

```

}

rr

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [May 25, 2012, 8:51pm UTC](https://www.ruby-forum.com/t/hotlink-protection-before-proxy-when-using-proxy-pass/220051/3 "2012-05-25T20:51:43Z")

</div>

> or use nested locations (I think it should work):

That failed to work, still getting the same errors :-/

> So you either have to duplicate the proxy\_\* block:

I switched to

location ~\* .(png|gif|jpg|jpeg|swf|ico)(?[0-9]+)?$ {  
valid\_referers none blocked dev.local.lan  
\*.dev.local.lan;  
if ($invalid\_referer) {  
return 403;  
}  
proxy\_pass [http://PROXY](http://PROXY);  
proxy\_redirect off;  
…  
}

location / {  
proxy\_pass [http://PROXY](http://PROXY);  
proxy\_redirect off;  
…  
}

and for valid referrer (e.g., visiting the site from  
mach2.dev.local.lan), the site renders correctly, and I can ‘grab’ all  
image files for hotlinking.

BUT, I’m still able to hotlink to (for example)

[http://dev.local.lan/favicon.ico](http://dev.local.lan/favicon.ico)

from a !whitelisted machine, e.g. visiting from other.other.lan.

RandyK
