Как проксировать файлы с S3 через приложение rails, чтобы избежать пиявки?

Чтобы избежать горячих ссылок, потери пропускной способности S3 и т. д., я хотел бы сделать свою корзину приватной и обслуживать файлы через приложение Rails. Концепция в целом звучит очень просто, но я не совсем уверен, какой подход будет лучшим в данной ситуации.

Я использую скрепку для общего управления активами. Есть ли какой-либо встроенный способ для достижения этого типа прокси?

В общем, я могу легко разобрать URL-адреса из скрепки и указать их обратно на свой собственный контроллер. Что должно произойти с этого момента? Должен ли я просто использовать Net::HTTP для загрузки изображения, а затем передавать его с помощью send_data? Между ними я хочу зарегистрировать реферер и установить правильные заголовки Control-Cache, так как у меня есть обратный прокси-сервер перед приложением. Подходит ли Net::HTTP + send_data в этом случае?

Может быть, целые идеи действительно плохи по каким-то причинам, о которых я в данный момент не знаю? В общем, я считаю, что использование прямых ссылок S3 на общедоступную корзину опасно и приводит к серьезным проблемам в случае пиявки / горячей ссылки...

Обновлять:

Если у вас есть какие-либо другие идеи, которые могут уменьшить расходы на S3 и в любом случае предотвратить хотлинкинг, пожалуйста, поделитесь ими, даже если они не имеют прямого отношения к Rails.


person mdrozdziel    schedule 27.10.2010    source источник
comment
У вас сейчас проблемы с пиявками? Я бы не хотел делать что-то, что резко замедлит работу моего приложения, просто чтобы решить проблему, которая может возникнуть в будущем.   -  person mikerobi    schedule 28.10.2010
comment
Дело не только в решении потенциальной проблемы. Я просто не хочу проснуться в один прекрасный день с огромным счетом за S3, который я не могу позволить себе оплатить... Я не уверен, сильно ли это замедлит работу приложения, когда активы будут храниться в кэше памяти / обратном прокси.   -  person mdrozdziel    schedule 28.10.2010


Ответы (4)


Используйте (частное ведро | личные файлы) и используйте подписанные URL-адреса для файлов, хранящихся на S3.

Подпись включает время истечения срока действия (например, через 10 минут, что бы вы ни хотели установить), а также криптографический хэш. S3 откажется обслуживать файлы, если подпись недействительна или истек срок ее действия.

Это полезно, потому что только вы можете создавать действительные URL-адреса для ваших личных файлов в S3, и вы можете контролировать, как долго URL-адреса остаются действительными. Это предотвращает личинг, потому что личеры не могут подписывать свои собственные URL-адреса, и, если они получат URL-адрес, который вы подписали, срок действия этого URL-адреса истечет очень скоро, и после этого его нельзя будет использовать.

person yfeldblum    schedule 06.12.2010

Поскольку выше не было подробного ответа, вот небольшой пример кода о том, как передать файл, хранящийся на S3.

render :text => proc { |response, output|
   AWS::S3::S3Object.stream(path, bucket) do |segment|
     output.write segment
     output.flush # not sure if this is needed
   end
 }

В зависимости от вашего веб-сервера это может (ублюдок) или не может (вебрик) работать, так что не расстраивайтесь, если он не транслируется в разработке.

person Justin    schedule 22.07.2011

Укажите временные предварительно подписанные URL-адреса:

   def show
      redirect_to Aws::S3::Presigner.new.presigned_url(
         :get_object, 
         bucket: 'mybucket', 
         key: '/folder/file.pdf'
         expires_in: 60)
    end

S3 по-прежнему распределяет контент, поэтому вы перегружаете работу с Rails (который работает очень медленно), обрабатывает кэширование HTTP, операции HEAD и использует Amazon CDN.

person Brian Low    schedule 21.04.2016
comment
Это умное перенаправление, поэтому, если вы разместите ссылки в электронных письмах или где-то еще, они всегда будут получать новую ссылку с новым сроком действия после перенаправления. - person JP Silvashy; 27.06.2018

Я бы, наверное, избегал этого — по крайней мере, до тех пор, пока у меня не будет другого выбора.

Вы должны принять во внимание, что вы, вероятно, также добавите счет за пропускную способность, если будете каждый раз загружать изображение. Кроме того, при обработке каждого изображения с помощью сценария вам также потребуется больше процессора и оперативной памяти, необходимых для этого. Не самая лучшая перспектива - ИМХО.

Я бы, наверное, включил журналы доступа для Amazon S3 и напишите небольшой инструмент для анализа использования и изменения разрешений для корзины/объекта в случае, если использование выходит за рамки. Запускайте это как cronjob каждые 10 минут или около того, и вы должны быть сохранены?

Вы также можете использовать s3stat. Они также предлагают бесплатный план.

Редактировать: В соответствии с моей рекомендацией для Varnish я добавляю ссылку на запись в блоге о предотвращении хотлинкинга с помощью Varnish.

person Till    schedule 02.11.2010
comment
Конечно, я знаю недостатки, поэтому я прошу идею для решения. В общем не все так плохо. Имейте в виду, что в большинстве случаев изображения можно обналичить. Проведя некоторые исследования, я пришел к выводу, что наиболее эффективным способом будет использование обратного прокси-сервера перед приложением S3 вместо приложения rails. Там я тоже могу все сделать - проверить реферера, провести обширный анализ логов. Такой внешний интерфейс значительно уменьшит стоимость S3, и производительность в конечном итоге не должна быть ниже. - person mdrozdziel; 02.11.2010
comment
Да, звучит неплохо — я бы порекомендовал лак. :) Просто имейте в виду, что, несмотря на то, что изображения кэшируются, вы также запускаете более сложную настройку, добавляя другую службу. И, возможно, также требуют большей вычислительной мощности (например, экземпляра или, по крайней мере, ресурсов) для прокси. - person Till; 02.11.2010