weserv / images

Source code of wsrv.nl (formerly images.weserv.nl), to be used on your own server(s).
https://wsrv.nl/
BSD 3-Clause "New" or "Revised" License
1.97k stars 193 forks source link

Allow list images from specified domains #314

Closed thesohodigital closed 2 years ago

thesohodigital commented 2 years ago

If self hosting, is there a way to allow only images from a list of domains I specify?

eg. if the &url value is not on the allow list, then a 404 is returned.

andrieslouw commented 2 years ago

The easiest way is to specify your own resolver in the NGINX config: https://github.com/weserv/images/blob/439f5c854b0a8895751da349e99bc7d5d45666d2/ngx_conf/imagesweserv.conf#L55

and let that resolver only respond to specific domains. It is the way we use to filter ourselves.

We use Unbound as a local(host) resolver, which forwards the requests to OpenDNS, and adds some of our own blocklists for our public service. But it should be easy to let Unbound only respond to specific domains.

kleisauke commented 2 years ago

If there's only one domain you want to allow, you can also use proxy_pass in combination with the weserv filter directive. For example, to process only images from Imgur:

location /imgur {
    weserv filter;

    proxy_pass https://i.imgur.com:443/;
    proxy_redirect off;

    # Enable SNI on the upstream connection
    proxy_ssl_server_name on;

    # Use a custom user agent
    proxy_set_header User-Agent "Mozilla/5.0 (compatible; ImageFetcher/9.0; +http://images.weserv.nl/)";

    # Set upstream host
    proxy_ssl_name "i.imgur.com";
    proxy_set_header Host "i.imgur.com";

    # Enable the upstream persistent connection
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}
$ curl -s -o /dev/null -w "%{http_code}" http://localhost/imgur/FY1AbSo.gif?w=512
200
kleisauke commented 2 years ago

I hope this information helped. Please feel free to re-open if questions remain.

kleisauke commented 1 year ago

Another option is to use the ngx_http_secure_link_module module to check the authenticity of requested links and protect resources from unauthorized access. This module is included by default in the Dockerfile (see commit ce4ea86fde74cea71f0a2cad33c392253ac99243).

For example:

FROM ghcr.io/weserv/images:5.x

ARG SECRET

RUN cp ngx_conf/imagesweserv-secure-link.conf /etc/nginx/imagesweserv.conf \
    && sed -i "s/<SECRET>/$SECRET/g" /etc/nginx/imagesweserv.conf
$ docker build --build-arg SECRET=mysecret -t weserv/images .
$ docker run -d -p 8080:80 --shm-size=1gb --name=weserv weserv/images
$ echo -n 'url=https://wsrv.nl/lichtenstein.jpg&w=100 mysecret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
hqx4I-j6fhgY6LVhGTbHdw
$ curl -s -o /dev/null -w "%{http_code}" "localhost:8080/s/hqx4I-j6fhgY6LVhGTbHdw/?url=https://wsrv.nl/lichtenstein.jpg&w=100"
200
$ curl -s -o /dev/null -w "%{http_code}" "localhost:8080/s/hqx4I-j6fhgY6LVhGTbHdw/?url=https://wsrv.nl/lichtenstein.jpg&w=1000"
403

(ensure that you change mysecret to something else)