Prevent nginx from serving content to external domains (hotlinking)

Written by - 0 comments

Published on - Listed in Linux Unix Internet Nginx


Imagine you have a web server with an application and containing some static files which you only want to serve for visitors of your application. You also want to prevent that external domains can embed your pictures (hotlink) in their websites. This is where the nginx parameter "valid_referers" comes to play.

Scenario:
- Application running on under domain "app.example.com"
- There is a static file (an image) called "image.jpg"
- The image can only be displayed through the domain "app.example.com"

The following nginx config (residing within the 'server' definition) takes care of the rule:

server {
[...]
  server_name app.example.com;
[...]
  location ~* (\.jpg|\.png)$ {
    valid_referers none app.example.com;
    if ($invalid_referer) {
        return 410;
    }
  }
}

Let's explain this config snippet piece by piece:

location: Defines a location for all requests ending with .jpg or .png.
valid_referers none: All requests without a http referer will be treated as a valid referer (allowed). This is typically when your own application embeds the picture with a relative path (/image.jpg). Direct URL access also have no referer.
valid_referers app.example.com: All requests coming from "app.example.com" as referer are treated as valid and are allowed.
the if clause: All other referers/sources are treated as invalid and nginx will return a http status 410 (gone).

Now how does that work in a practical example?
Let's open a browser and go to http://app.example.com/image.jpg. The image is shown in the browser and the nginx access log shows the following entry:

1.2.3.4 - - [04/Jun/2014:10:17:24 +0200] "GET /image.jpg HTTP/1.0" 200 114557 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0"

I now created a test page on my own domain (www.claudiokuenzler.com) and embedded the picture with the img tag:

cat nginx-test/test.php

Opened www.claudiokuenzler.com/nginx-test/test.php in the browser and the picture was not shown:

Nginx valid_referers test

The nginx access log meanwhile shows this new entry:

1.2.3.4 - - [04/Jun/2014:10:17:35 +0200] "GET /image.jpg HTTP/1.0" 410 0 "http://www.claudiokuenzler.com/nginx-test/test.php" "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0"

See the status code 410 in the log? Yes, it is working!


Add a comment

Show form to leave a comment

Comments (newest first)

No comments yet.

RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Database   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Office   OpenSearch   PGSQL   PHP   Perl   Personal   PostgreSQL   Postgres   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder