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

1 Answer 1

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;
}
1
  • Thank you!! This is awesome and now I know something else about nginx. Much appreciated. Oct 11, 2020 at 0:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.