Комментарии 33
А не боитесь, что кто-то устроит перебор GET /yPkjPk_200x200.gif, GET /yPkjPk_200x201.gif, GET /yPkjPk_200x202.gif,… и или забъет кэш, что место на диске закончится или процессор устанет конверитирования выпонять?
+3
Боюсь :)
Считаю, это не ответственность сервиса, нужно делать защиту на уровне веб-сервера, разрешая или запрещая определенные URI.
Считаю, это не ответственность сервиса, нужно делать защиту на уровне веб-сервера, разрешая или запрещая определенные URI.
0
Так сервер можно положить только допустимыми URI — заставить его генерить все допустимые размеры для всех элементов. Если элементов немного, то это не проблема, но тогда и функционал такой не нужен. Если же элементов много, то над сервером можно круто поизмываться.
0
Не понял. Если разрешить, например, с десяток размеров изображений, то остальные генерироваться не будут. Проблема решена. Или нет?
0
А все разрешенные размеры для всех хранимых документов правда нужны, это штатная работа сервиса, после генерации они будут отдаваться как статический контент.
0
Не совсем штатная.
Как я понимаю цели сервиса:
допустим, есть у нас фотохостинг. Он предусматривает для каждого изображения, скажем, 10 разных размеров. Из них 2-3 являются востребованными, а остальные 7-8 являются экзотикой, которая далеко не для каждого изображения будет востребована (а значит и создана). Почему я считаю что это будет именно так? Потому что в противном случае имело бы смысл генерировать все размеры еще при загрузке оригинала. Так же мы экономим ресурсы и создаем нужные размеры только когда (если) в них возникнет необходимость. По сути, технология нам позволяет сократить занимаемое место до X*0.3, где X — полный объем всех возможных изображений.
Что делает злоумышленник? А делает он очень просто — запрашивает все возможные размеры для каждого изображения. В результате сервис изображений должен в стрессовом режиме создать и разместить 0,7*Х гигабайт изображений. Более того, даже если предположить что он выдержит этот стресс-тест, потом он должен будет хранить эти никем невостребованные Х гигабайт, вместо того чтобы хранить всего 0,3*Х.
Собственно, я не утверждаю что сама концепция изображений по запросу плохая, но хотелось бы какого-то решения как раз на вышеописанный случай…
Как я понимаю цели сервиса:
допустим, есть у нас фотохостинг. Он предусматривает для каждого изображения, скажем, 10 разных размеров. Из них 2-3 являются востребованными, а остальные 7-8 являются экзотикой, которая далеко не для каждого изображения будет востребована (а значит и создана). Почему я считаю что это будет именно так? Потому что в противном случае имело бы смысл генерировать все размеры еще при загрузке оригинала. Так же мы экономим ресурсы и создаем нужные размеры только когда (если) в них возникнет необходимость. По сути, технология нам позволяет сократить занимаемое место до X*0.3, где X — полный объем всех возможных изображений.
Что делает злоумышленник? А делает он очень просто — запрашивает все возможные размеры для каждого изображения. В результате сервис изображений должен в стрессовом режиме создать и разместить 0,7*Х гигабайт изображений. Более того, даже если предположить что он выдержит этот стресс-тест, потом он должен будет хранить эти никем невостребованные Х гигабайт, вместо того чтобы хранить всего 0,3*Х.
Собственно, я не утверждаю что сама концепция изображений по запросу плохая, но хотелось бы какого-то решения как раз на вышеописанный случай…
+4
Теперь понял.
У нас другая специфика. Если 100500 клиентов с документами. Мы их показываем на страницах сайта. И вдруг однажды у проекта меняется дизайн. Например лого компании на странице деталей теперь другого размера. Дизайнер меняет URI картинки — у вуаля! Проблемы нет.
А дискового места нам не жалко :)
У нас другая специфика. Если 100500 клиентов с документами. Мы их показываем на страницах сайта. И вдруг однажды у проекта меняется дизайн. Например лого компании на странице деталей теперь другого размера. Дизайнер меняет URI картинки — у вуаля! Проблемы нет.
А дискового места нам не жалко :)
-1
Собственно, вы ушли от ответа.
0
Так нет решения, предлагайте pull request :) Я просто рассказал как у нас дела.
Если придумывать на ходу, я бы сделал какой-нибудь сборщик мусора, если правда памяти жалко.
Если придумывать на ходу, я бы сделал какой-нибудь сборщик мусора, если правда памяти жалко.
0
К сожалению, ресайз картинки — это медленная процедура, а уж если добавить sharp, чтобы она выглядела получше… Мы пробовали на, кажется, 4-процессорном E5-2660 ресайзить картинки размера 1200х1200 вниз, с помощью imagemagick. Просто ресайз занимал порядка 100мс, ресайз с шарпом — уже больше 300мс.
С учётом того, сколько стоит процессор, а сколько диски — выгоднее сразу поресайзить на все размеры и их хранить. С коэффициентом 0.3 вы не совсем правы — если это фотохостинг, то надо оригиналы хранить, или хотя бы хайрез картинки. Оригинал современных мыльниц от 5мб, средний размер приближается к 10мб, ресайзы 1200х1200 и ниже в сумме (штук 7-10 размеров) меньше 2 мегабайт займут, а то и всего 1 мегабайт.
С учётом того, сколько стоит процессор, а сколько диски — выгоднее сразу поресайзить на все размеры и их хранить. С коэффициентом 0.3 вы не совсем правы — если это фотохостинг, то надо оригиналы хранить, или хотя бы хайрез картинки. Оригинал современных мыльниц от 5мб, средний размер приближается к 10мб, ресайзы 1200х1200 и ниже в сумме (штук 7-10 размеров) меньше 2 мегабайт займут, а то и всего 1 мегабайт.
0
НЛО прилетело и опубликовало эту надпись здесь
А есть защита от DDoS? В своё время хотел сделать тоже самое, но решил, что будет слишком легко положить сервер отправкой кучей запросов на изменение размеров изображений, например.
0
Как уже сказал выше, защита от DDoS должна быть на уровне веб-сервера.
0
А что считать DDoS в случае такого сервиса? Вариант если только новые картинки вылетают по таймауту, а старые выдаются как статика уже ддос?
0
Как уже написали выше, злоумышленник может найти картинки побольше и начать их активно запрашивать в разных размерах, что вызовет нагрузку на процессор нехилую. Или тоже самое с переконвертированием видео, через имеющийся плагин. Единственный видимый вариант — ограничить список размеров до статического (например, только 50х50 и 100х100, все остальные запросы считать невалидными) — но тогда смысл проекта, имхо, немного теряется.
0
Следует не забывать, что приложение — штука меняющаяся во времени. Это очень ценно, когда мы имеем оригиналы загруженных пользователями данных, чтобы легко менять то, как мы их показываем в новых версиях.
0
Ну так это можно делать средствами самого приложения — для rails, например, что paperclip, что carrierwave умеют прозрачно для пользователя генерировать из загруженного изображения несколько с разными размерами, без выставления уязвимых веб-сервисов наружу.
0
Просто нагрузка на ддос не тянет. Если, грубо говоря, nginx будет справляться с отдачей полноразмерных и уже обработанных картинок, то можно ли считать такую атаку удачной?
В общем, когда я думал над подобной системой, то пришел примерно к такой архитектуре:
— веб сервер проверяет есть ли точно запрошенный формат в кэше, если есть отдает (тут никакой новой опасности)
— запрос идет в приложение, оно отправляет задание на ресайз в независимую от контекста запроса очередь и делает временный редирект на оригинал, что-то более подходящее по формату или временную заглушку (тут нагрузка не сильно большая чем на «хелло ворлд» средствами php).
— демон очереди тупо шарит по заданиям на ресайз c минимальным приоритетом, объединяя одинаковые. Или это вообще скрипт по хрону. Количество процессов ресайза ограничено сверху.
По задумке сереверу конечно поплохеет, но ляжет он много позже чем при синхронном ресайзе, а пока не ляжет будет быстро отдавать то, что нужно на старых картинках, и чуть медленнее не совсем то, что нужно. А на обработку очереди можно вообще повесить целый кластер, в том числе и по получению админом аларма от мониторинга. Веб-часть от ресайза не зависит почти.
В общем, когда я думал над подобной системой, то пришел примерно к такой архитектуре:
— веб сервер проверяет есть ли точно запрошенный формат в кэше, если есть отдает (тут никакой новой опасности)
— запрос идет в приложение, оно отправляет задание на ресайз в независимую от контекста запроса очередь и делает временный редирект на оригинал, что-то более подходящее по формату или временную заглушку (тут нагрузка не сильно большая чем на «хелло ворлд» средствами php).
— демон очереди тупо шарит по заданиям на ресайз c минимальным приоритетом, объединяя одинаковые. Или это вообще скрипт по хрону. Количество процессов ресайза ограничено сверху.
По задумке сереверу конечно поплохеет, но ляжет он много позже чем при синхронном ресайзе, а пока не ляжет будет быстро отдавать то, что нужно на старых картинках, и чуть медленнее не совсем то, что нужно. А на обработку очереди можно вообще повесить целый кластер, в том числе и по получению админом аларма от мониторинга. Веб-часть от ресайза не зависит почти.
0
— запрос идет в приложение, оно отправляет задание на ресайз в независимую от контекста запроса очередь и делает временный редирект на оригинал, что-то более подходящее по формату или временную заглушку (тут нагрузка не сильно большая чем на «хелло ворлд» средствами php).
Это очень важный момент, который, как я понял, в представленном проекте не учитывается.
Это очень важный момент, который, как я понял, в представленном проекте не учитывается.
0
Да, такого протокола нет.
0
Это просто размышления на тему защиты от DoS подобных сервисов без особой потери функциональности. В принципе ещё можно совместить синхронную и асинхронную модель: если ответа долго нет (или очередь большая или еще как по косвенным признакам оцениваем, что ответа долго не будет)), то выдаем редирект на оригинал или заглушку. Но тут надо экспериментировать, а в предложенном изначально варианте (полностью асинхронном) прототип довольно быстро сделать должно быть, используя хотя бы встроенные в php очереди.
0
а интеграции с tinymce нету? удобно было бы, заливать медиа информацию на отдельный сервис
0
Видео тоже на ходу можно конвертировать? Не сильно ли это накладно?
0
Конечно накладно. Хочешь работать с видео — готовь ресурсы.
Видео плагин делал не я, вот тут видно какие команды он понимает:
github.com/ykovaleva/barberry-plugin-ffmpeg/blob/master/src/Barberry/Plugin/Ffmpeg/Command.php
Видео плагин делал не я, вот тут видно какие команды он понимает:
github.com/ykovaleva/barberry-plugin-ffmpeg/blob/master/src/Barberry/Plugin/Ffmpeg/Command.php
0
По поводу разрешенных форматов, имхо, дельное замечание. Я бы сделал что-то типа того:
* Ввести группы, каждый файл цепляется на группу (например «documents»)
* Для группы задаются доступные форматы (в будущем можно и другие настройки цеплять)
* При запросе проверять доступен ли формат
* Урлы сделать с группой (/documents/yPkjPk.jpg), дабы на вебсервере можно было просто сделать такое же ограничение по формату
* Настройки для вебсервера можно генерить прям апликейшеном.
Что касается кэширования, то как раз это лучше перенести на вебсервер. На nginx можно сделать простейшую схему с try_files и X-Accel-Redirect, полностью исключив отдачу файлом непосредственно апликейшеном — только генерация.
* Ввести группы, каждый файл цепляется на группу (например «documents»)
* Для группы задаются доступные форматы (в будущем можно и другие настройки цеплять)
* При запросе проверять доступен ли формат
* Урлы сделать с группой (/documents/yPkjPk.jpg), дабы на вебсервере можно было просто сделать такое же ограничение по формату
* Настройки для вебсервера можно генерить прям апликейшеном.
Что касается кэширования, то как раз это лучше перенести на вебсервер. На nginx можно сделать простейшую схему с try_files и X-Accel-Redirect, полностью исключив отдачу файлом непосредственно апликейшеном — только генерация.
0
А я уже во втором проекте использую для этих целей UploadCare, опыт оч. положительный.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Управление картинками и другим бинарным содержимым вашего веб-проекта