1

I'm running Ghost on nginx 1.14.0 and Ubuntu 18.04. I am trying block image hotlinking by external sites.

I've added the recommended code from this post (starts with location ~* .(gif|png|jpe?g)$) to prevent image hotlinking.

Here is my site config file:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name example.com;
root /var/www/example.com/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:2368;
}

location ~* \.(gif|png|jpe?g)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
        return 403;
    }
}

location ~ /.well-known {
    allow all;
}

client_max_body_size 50m;}

The issue is when I add this code block and restart nginx, it works properly and blocks external requests returning a 403 Forbidden error. However, it also breaks local display of images despite the referer seemingly coming from the https://example.com domain when I use the network inspector in Firefox to check the request.

I've tried adding different servers to the valid_referers line: localhost, 127.0.0.1, the ip of the server, https://example.com/*, http://example.com/*. Yet no matter how I configure the valid_referers line, images are still blocked when trying to load them from within the local site.

When I delete the entire hotlink blocking block, everything works fine locally and images are able to be hotlinked.

Any ideas? It's been driving me crazy. Thanks in advance.

1 Answers1

2

By adding the location ~* \.(gif|png|jpe?g)$ block, these URIs are no loger processed by the location / block. See how Nginx processes a request.

You will need to make the proxy_xxx statements available to the new block. The proxy_set_header statements can be inherited.

For example:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;

location / {
    proxy_pass http://127.0.0.1:2368;
}

location ~* \.(gif|png|jpe?g)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
        return 403;
    }
    proxy_pass http://127.0.0.1:2368;
}
Richard Smith
  • 11,859
  • 2
  • 18
  • 26