Nginx изменение картинки по рефереру

В последнее время, стало модным вместо борьбы с хотлинками, выдавать вместо ожидаемого контента несколько другой. Я это заметил на примере мем сайтов, которые при обращение к их картинкам с других сайтов, отдают эту картинку, но приделывают к ней футер с адресом сайта или подобной рекламной информацией.

В целом весьма логично, если раньше все боялись за свой трафик, то теперь вопросы трафика мало кого интересуют, поэтому и приоритеты сместились в другую сторону. Хотя я видел ситуацию, когда на одном из рабочих ресурсов, образовался хотлинк канал японского трафика на 250mb/s.

Попробуйте открыть это изображение в новой вкладке (убедитесь что броузер не закешировал)

раньше тут была картинка

Рассматривая разные решения, я нашел самый простой способ, делать это с помощью nginx и встроенного модуля ngx_http_referer_module.

test_images.conf

server {
        listen 80;
        server_name images.dev;
        root /www/data/test_images;

        location /test_images {
                valid_referers none blocked server_name images.dev;

                if ($invalid_referer) {
                        rewrite ^(.*)/(.*)$ /images_bad/$2 last;
                }

                rewrite ^(.*)/(.*)$ /images_ok/$2;
        }

        location /images_ok {
                internal;
                alias /www/data/images/test_images/ok;
        }

        location /images_bad {
                internal;
                alias /www/data/images/test_images/bad;
        }
}

Собственно механика очень простая. Мы определяем с помощью "valid_referers" список правильных доменов, можно добавить в него домены поисковиков, например, что бы при поиске картинок пользователю показывалась правильная картинка. Потом мы создаем два внутренних location, которые отвечают за показ правильных и не правильных картинок. В случае не правильного реферера, в конструкции if мы делаем редирект на локейшн с картинками, которые должны отдаваться жуликам, которые ленятся скачивать картинку на свой сервер. Ну вот, в общем и все. Осталось только позаботиться, что-бы у нас были необходимые картинки.

Тут можно решать разными путями, например, при создание оригинальной картинки создавать ее "обработанный" вариант. Но мне больше нравится ленивая загрузка, которую я, когда-то давно, делал в iCacher, основная идея проста: при попытке запроса "обработанной" картинки, если ее нету, управление передается скрипту, который проверяет ее оригинал и делает ее "обработанную" копию, которая отдается пользователю. При повторном обращение, запрос не дойдет до скрипта и пользователю отдастся статический файл. Таким образом мы получаем генерацию изображений по требованию. Еще можно добавить крон скрипт, который будет удалять "обработанные" картинки через 30 дней.

Я не уверен, что моя реализация хороший пример и буду рад если вы ее покритикуете. Плюс, я так и не придумал как избавиться от if в данном случае ( вариант хранения файлов в images_ok/1/ считаю уебским ).


banners, cache, images, nginx