3

Seeking help from Nginx experts here.

I want to block people accessing CSS or JS directly from my website. A bit like this: http://assets.behance.net/

I got this reference from ServerFault: https://serverfault.com/a/332493/117595

location ~* (\.jpg|\.png|\.gif|\.jpeg|\.png)$ {
 valid_referers none blocked www.example.com example.com;
 if ($invalid_referer) {
    return 403;
 }
}

But a few questions:

  1. In the valid_referers, how should I include all the domains from my vhosts directory, which contains the server block for all my domains on this server. (It's a dedicated WHM server with many Cpanel domains.) I would prefer this list of allowed domains to somehow be automated, in case we add more domains in the future.

  2. More importantly, how can I make this in the main "http" block, and not server by server (i.e., the vhosts for each domain!)?

  3. Isn't the "IF" condition going to make the Nginx server slower? We have stayed away from all IF blocks so far as I remember reading this has a significant adverse influence on performance.

Thanks!

Community
  • 1
  • 1
PKHunter
  • 682
  • 2
  • 13
  • 28
  • 1
    For 2: i think you should add to each server something like `include global/holinking.conf;` with your code inside it. For 1: you can try to include $host to valid_referers. And for 3: I think so too. But in this situation it's the only way to do that, so don't mind about that. – Dmitry Verhoturov May 16 '12 at 12:04
  • Thanks Dmitri. But in this case, I am still adding a directive to each and every "Server" block, right? – PKHunter May 16 '12 at 13:01
  • 1
    Yep. You can edit restrictions in once place but you still have to include it to each server location. – Dmitry Verhoturov May 16 '12 at 13:12
  • [Don't know why the format is not working!] Thanks. Actually I realize my server blocks already have one directive for these types of static files: ` location ~* \.(png|gif|jpg|jpeg|swf|ico|)$ { expires 7d; try_files $uri @backend; } ` Can I just add these lines? ` location ~* \.(png|gif|jpg|jpeg|swf|ico|)$ { expires 7d; try_files $uri @backend; valid_referers none blocked site.com mysite.com ~\.google\. ~\.yahoo\. ~\.bing\. ~\.facebook\. ~\.fbcdn\.; if ($invalid_referer) { return 403; } } ` – PKHunter May 16 '12 at 14:36
  • 1
    Comments sucks at formatting. And yes, you can add this `if`, but it will be better to include some other file and put all this stuff in it so you will not be required to change any single file to make changes to `valid_referers` list. – Dmitry Verhoturov May 16 '12 at 16:02
  • Actually this is not working. I entered code similar to above, and then restart Nginx, cleared all my browser caches etc. And also the proxy cache from Nginx on the server. Then I linked directly to an image in a new browser window. It shows up. I do not want people to be able to see any direct image at all (as in the example I gave in my first post above), I only want the images and static assets visible when being called from within my pages in my allowed sites. What am I missing? Thanks for any ideas. – PKHunter May 16 '12 at 17:11
  • Got it. I had "none" in the thing, which I have now removed. Then direct access from browser shows 403 too. Is there any risk to leaving "none" out of my config? What does "none" really do? – PKHunter May 16 '12 at 17:35
  • Check [docs](http://nginx.org/en/docs/http/ngx_http_referer_module.html#valid_referers). – Dmitry Verhoturov May 16 '12 at 17:40
  • Sorry, had some code, so I've added an "answer". Could you pls comment on that? Much appreciate your help. Thx! – PKHunter May 17 '12 at 09:25

1 Answers1

0

Thanks @dmitry-paskal. I'll keep skipping "none". But the thing is that the 403 message is coming from nginx default. I have this in my "Server" block:

error_page 404 /404.html;
location = /404.html {
  root   /etc/nginx/html;
  internal;
}
error_page 403 /403.html;
  location = /403.html {
  root   /etc/nginx/html;
  allow all;
}
error_page 500 502 503 504  /500.html;  
  location = /500.html {  
  root  /etc/nginx/html;  
}  

And the directory /etc/nginx/html is chmod 777.

The docs and all the google search results I've found suggest that the above code should work. What am I missing, how can I show my own 403 page?

PKHunter
  • 682
  • 2
  • 13
  • 28
  • 1
    [Root inside location block](http://wiki.nginx.org/Pitfalls#Root_inside_Location_Block) isn't good. Why do you need all these locations for your error pages? Try just to declarate them and make some /error/ location which will define where all of them and all their rules placed. Like `error page 403 /error/403.html;`, `location /error`, `root /etc/nginx/html`, `allow all`, `try files @uri @uri/ 404.html` (if someone access /error/ directly, he will get 404 error page). – Dmitry Verhoturov May 17 '12 at 09:38
  • But then I will have to create these error pages in ALL the server blocks, right? I have about 40 domains on this server, plus some subdomains. In all, this means about 65 server blocks. Will I have to create the error pages in all the 65 server blocks? – PKHunter May 17 '12 at 11:07
  • Or maybe I missed the code you were suggesting. Could you pls include it as a full answer, not a comment here? Thanks! – PKHunter May 17 '12 at 11:17
  • Please rewrite original question. I don't understand what do you want from me:) Custom 403 for any page? Or invalid referer blocking? Or? – Dmitry Verhoturov May 17 '12 at 11:33
  • Thanks. Have asked a question here: http://stackoverflow.com/questions/10641792/server-wide-nginx-403-custom-defaults – PKHunter May 17 '12 at 18:52