ФорумПрограммированиеPHP для идиотов → Отдача файлов. mod_rewrite и доступ по секретной ссылке

Отдача файлов. mod_rewrite и доступ по секретной ссылке

  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 16 апреля 2012 г. 22:43, спустя 2 дня 42 минуты

    update: поправил заголовок темы на более подходящий

    update: чтобы узнать почему symlink() доступен не везде, гуглите "php open_basedir symlink shared"


    Очередной раз пишу файловую свалку для форума. Была близкая тема здесь, но сейчас я ближе к реальности )))
    Интересует что можно улучшить и как можно взломать предложенную схему.

    Задача:
    давать только избранным. Нет цели повторить rapidshare или типа того. Саму отдачу надо переложить на сервер, а не прокачивать через скрипт. То есть ссылки оформляю на скрипт в виде download.php?id=###, он проверяет права и если все ок, редиректит на "секретную ссылку" реальной отдачи. Решение должно быть портабельным, т.к. эту штуку я оформлю как open source расширение к движку форума. Вариант с созданием симлинков отпадает, конфигурирование httpd.conf тоже. Должно работать на шаред-хостингах где есть mod_rewrite и на Windows.

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

    Пусть файлы на отдачу хранятся в реальной папке /upload/, имена как ####.ext (имя уникальное синтетическое, ext - реальное расширение файла)
    файлы-ключи лежат там же, имена как ####-####.acs (расширение "acs" от "access"-доступ)
    а секретная ссылка выглядит как
    mysite.xx/download/####-####/File.ext
    В корне сайта помещаем .htaccess

    RewriteEngine on
    #                         1.prefix        2.fileId    3.accessId   4.name    5.ext
    RewriteCond %{REQUEST_URI} (.*)/download/([0-9a-f]+)-([0-9a-f]+)/([^\.]+)\.([0-9a-z]+)
    RewriteCond %{DOCUMENT_ROOT}%1/upload/%2-%3.acs -f
    RewriteRule download/.* upload/%2.%5 [L]

    Второй RewriteCond проверяет существует ли файл-ключ.

    в папке /upload/ будет свой .htaccess

    #Deny from All
    Options -Indexes
    RewriteEngine on
    RewriteCond %{THE_REQUEST} !^.*/download/ [NC]
    RewriteRule .* - [F]

    К сожалению Deny from All я не могу включить, т.к. тогда вообще не получается качать из этой папки. Вместо этого я проверяю что ссылка на файл была "правильная", а не прямая. После первого .htaccess %{REQUEST_URI} содержит вместо /download/ уже /upload/, поэтому здесь я тестирую %{THE_REQUEST}, он по прежнему выглядит как "GET /download/####-####/File.ext HTTP…"

    Ваши комментарии?
    ιιlllιlllι унц-унц
  • ivanscm

    Сообщения: 1251 Репутация: N Группа: Джедаи

    Spritz 14 апреля 2012 г. 9:30, спустя 10 часов 47 минут 3 секунды

    думал о чем то похожем. но только думал. подобное решение еще не встречал.
    С возвращением, Пiха! hyperoff.ru - качественный хостинг php
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 10:30, спустя 1 час 3 секунды

    Уже сам нашел способ обхода ограничений. Т.к. THE_REQUEST в отличие от REQUEST_URI содержит и get-параметры, правило будет обмануто таким адресом: mysite.xx/upload/####.ext?q=/download/

    Решение: второй .htaccess должен выглядеть так:

    Options -Indexes
    RewriteEngine on
    RewriteCond %{THE_REQUEST} !^(GET|HEAD)\ ([^?]*)/download/
    RewriteRule .* - [F,L]

    ιιlllιlllι унц-унц
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 14 апреля 2012 г. 11:17, спустя 47 минут 14 секунд

    тащемта можно обойтись папками и симлинками типа

    files/
     bar.zip
    uploads/
     foo123/
       .htaccess
       bar.zip (симлинк на files/bar.zip)
     foo456/
       .htaccess
       bar.zip (симлинк на files/bar.zip)

    папка files закрыта от пользователей

    foo123, foo456 создаются под каждого пользователя и удаляются через сутки например

    раздаваемые файлы - это симлинки на хранимые файлы
    uploads/foo123/bar.zip -> files/bar.zip
    uploads/foo456/bar.zip -> files/bar.zip
    так можно раздавать 100500 файлов без ущерба для дискового места. не уверен насчёт занимаемой веб-сервером оперативы

    в .htaccess можно добавить фильтр по REMOTE_ADDR. если не совпадает - то 403 или редирект на страницу афторизации

    возможно будет работать в винде http://en.wikipedia.org/wiki/NTFS_symbolic_link
    не всё полезно, что в swap полезло
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 11:17, спустя 23 часа 59 минут 27 секунд

    блять, молодец, прочитай первое сообщение
    Решение должно быть портабельным, т.к. эту штуку я оформлю как open source расширение к движку форума. Вариант с созданием симлинков отпадает, конфигурирование httpd.conf тоже. Должно работать на шаред-хостингах где есть mod_rewrite и на Windows.

    ιιlllιlllι унц-унц
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 14 апреля 2012 г. 11:19, спустя 1 минуту 57 секунд

    artoodetoo, а чё так? идеологически не приемлешь простые решения?
    не всё полезно, что в swap полезло
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 11:23, спустя 4 минуты 19 секунд

    я люблю простые решения, есть разница для себя или public domain: на своем личном VPS я буду использовать другие решения.
    читай первый пост, мудило.
    ιιlllιlllι унц-унц
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 14 апреля 2012 г. 11:35, спустя 11 минут 39 секунд

    artoodetoo, так чем симлинки-то не вариант?
    не всё полезно, что в swap полезло
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 14 апреля 2012 г. 11:54, спустя 19 минут 18 секунд

    И ещё вопрос. Как при такой схеме:
    RewriteEngine on
    #                         1.prefix        2.fileId    3.accessId   4.name    5.ext
    RewriteCond %{REQUEST_URI} (.*)/download/([0-9a-f]+)-([0-9a-f]+)/([^\.]+)\.([0-9a-z]+)
    RewriteCond %{DOCUMENT_ROOT}%1/upload/%2-%3.acs -f
    RewriteRule download/.* upload/%2.%5 [L]

    ограничить скачивание по IP?
    не всё полезно, что в swap полезло
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 17:24, спустя 5 часов 30 минут 24 секунды

    сама схема ничего не делает по поводу IP, также как она не печет пирожное и не делает минет. это отдельные задачи.
    симлинки в общем случае не вариант, т.к. решение "…Должно работать на шаред-хостингах где есть mod_rewrite и на Windows. "
    в общем случае на шаредах нельзя создать симлинк из PHP, только в консоли или по SFTP. на винде вообще нет симлинков.
    дошло?
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 17:26, спустя 2 минуты 3 секунды

    Уже сам нашел способ обхода ограничений. Т.к. THE_REQUEST в отличие от REQUEST_URI содержит и get-параметры, правило будет обмануто таким адресом: mysite.xx/upload/####.ext?q=/download/

    IS_SUBREQ
    Will contain the text "true" if the request currently being processed is a sub-request, "false" otherwise. Sub-requests may be generated by modules that need to resolve additional files or URIs in order to complete their tasks.


    это не пашет?

    http://httpd.apache.org/docs/current/mod/mod_rewrite.html
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 17:38, спустя 11 минут 10 секунд

    надо подумать что это дает.
    помоему THE_REQUEST дает нам какраз нужную инфу — по какому конкретно адресу это отдается.
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 17:40, спустя 2 минуты 13 секунд

    помоему THE_REQUEST дает нам какраз нужную инфу — по какому конкретно адресу это отдается.

    ну одно дело эта инфа, другое - сабреквест))
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 17:57, спустя 17 минут 10 секунд

    ок, я подумаю как это можно использовать. сомнения такие: адрес может быть уже преобразован, но не по правилу /download/*, а, например, по правилу выбрасывания "www.", или по правилу разруливания под-доменов. это тоже будет вторичный запрос.
    ιιlllιlllι унц-унц
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 14 апреля 2012 г. 18:01, спустя 3 минуты 59 секунд

    artoodetoo, уе
    Сапожник без сапог

Пожалуйста, авторизуйтесь, чтобы написать комментарий!