Добро пожаловать на форум, Гость!
Войдите или зарегистрируйтесь!
Имя пользователя:   Пароль:  
Запомнить меня 




Начать новую тему Ответить на тему   [ Сообщений: 3 ] 
Автор Сообщение
СообщениеДобавлено: 10 июл 2013, 16:20 
Бородатый сис
Аватар пользователя
Статус: Не в сети

GeoIP: Kyrgyzstan

Сообщений: 2902
Откуда: Из серверной
Зарегистрирован: 03 мар 2010, 15:12
Благодарил (а): 19 раз.
Поблагодарили: 122 раз.
ОС: RHEL 6.7
Понадобилось недавно сделать хитрожопый финт ушами - наши чудо-программисты написали супер-пупер крутую прогу, которой в обязалову потребовалось работать через собственный прокс (ибо в обязательном порядке SSL ннада!) на кучу серваков в локалке . Часть отвечающую за передачу динамического контента они написали сами, на PHP с использованием curl (держись прокся - северный пушной зверек крадется медленно, но верно), отдачу статики же было решено поручить веб-серверу. В общем самая хитрость заключалась в следующем - url выглядят следующим образом:
Код:
http://frontend.tld/?url=http://backend.tld/some/path/file.ext


То есть адрес файла вместе с адресом сервера передается в качестве аргумента к url= . Чтож, mod_rewrite в помощь, закручиваем хорошую самокрутку манов и курим-курим-курим! Я в итоге накурил до:

Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса apache
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^url=(.*)$ [NC]
RewriteRule .* %1 [P,L]
Обработано за 0.007 секунд, используется GeSHi 1.0.8.4


добавленное в .htaccess корневой директории домена оно в принципе справлялось достаточно хорошо. Однако вскоре случился затык - кое-где на бэкендах имелись файлы с пробелами в названии (криворукость итернет-пользователей заставляет подозревать что человеческая раса вымрет быстро). И естественно они не загружались. Оказалось что url содержащий пробел кодировался - пробел заменялся на '%20'. Казалось-бы, что в этом такого? Нормальное поведение браузера... Да не тут-то было! Веб-сервер при передаче запроса на проксирование, углядывал в запросе небезопасный по его мнению символ '%' и... кодировал его от греха подальше :-D Тупо заменял на '%25'! В конце-концов бедолага пробел выглядел уже как '%2520' и понять что это за покемон уже никто не был способен. В общем ситуацию удалось разрешить добавлением флага NE (NoEncode) в RewriteRule
Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса apache
RewriteRule .* %1 [P,L,NE]
Обработано за 0.007 секунд, используется GeSHi 1.0.8.4

Правда радости это много не принесло - аналогичная проблема всплыла и с закодированными слешами и др. спецсимволами. А причина вся вот в чем - правила rewrite составлены таким образом, что если url= имеет аргументы, то присваиваются переменной %1 и содержимое всего запроса меняется на нее и передается в прокси КАК ЕСТЬ! А прокси не разрешает использование закодированных символов в обозначении хоста - то есть можно использовать кодированные символы только в {REQUEST_URI}, {QUERY_STRING} - то есть после http://backend.tld/. У меня же кодировалась вся строка запроса http%3A%2F%2Fbackend.tld%2F.
Перекурив маны еще раз вдоль и поперек нашел весьма интересную директиву - RewriteMap, позволяющую запускать для рерайта внешние обработчики. Быстренько сообразив что к чему накатал простенький скрипт на perl
Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса perl
#!/usr/bin/perl

use URI::Escape;

$| = 1;
while (<STDIN>) {

    print uri_unescape($_);
}
Обработано за 0.004 секунд, используется GeSHi 1.0.8.4


Скрипт был назван decode.pl и помещен в папку с конфигами апача (заострю внимание на том, что скрипту требуется модуль URI::Escape, поставить можно через cpan).

далее в конфиге виртуалхоста добавляем строку
Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса apache
RewriteMap  decode prg:/usr/local/etc/apache22/decode.pl
 
Обработано за 0.007 секунд, используется GeSHi 1.0.8.4

а в .htaccess приводим правила рерайта к следующему виду:
Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса apache
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^url=(.*)$ [NC]
RewriteRule .* ${decode:%1} [P,L,NE]
 
Обработано за 0.007 секунд, используется GeSHi 1.0.8.4


то есть, прежде чем передать строку в прокси-сервер, рерайт прогоняет ее через перловый скрипт слушающий stdin и заменяющий все кодированные символы на обычные. Profit!

UPD: Не, не profit! На боевом сервере оказался ужасно старючий перл, который при попытке собрать модуль URI::Escape возжелал обновиться. Ждать пока сие чудо скомпилится на серваке эквивалентном PIII желания особого не было, но к счастью там обнаружился python, нормальной версии 2.6!!! Спасибо gen1us2k за за помощь в конвертировании скрипта в python - все воркает замечательно!
Синтаксис: [ Загрузить ] [ Скрыть ]
Используется подсветка синтаксиса python
#!/usr/bin/env python
from urllib2 import unquote
import sys

while 1:
    request = sys.stdin.readline().strip()
    sys.stdout.write('%s\n' % unquote(request))
    sys.stdout.flush()
Обработано за 0.006 секунд, используется GeSHi 1.0.8.4


Я не злопамятный, я просто часто ковыряю логи
Изображение


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 12 июл 2013, 10:18 
Бородатый сис
Аватар пользователя
Статус: Не в сети

GeoIP: Kyrgyzstan

Сообщений: 2902
Откуда: Из серверной
Зарегистрирован: 03 мар 2010, 15:12
Благодарил (а): 19 раз.
Поблагодарили: 122 раз.
ОС: RHEL 6.7
Да, кстати. Вот теперь вопрос - мож кто знает как отсечь передачу query_string в запросе к бэкенду? Просто проанализировав логи на серверах назначения обнаружил интересную картинку - запросы приходят в таком виде:
Код:
/some/path/file.ext?url=http://backend.tld/some/path/file.ext


Для серверов отдающих статику это конечно не очень критично, но тут уже чисто мои эстетические принципы - все должно быть чисто!


Я не злопамятный, я просто часто ковыряю логи
Изображение


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 13 авг 2013, 20:51 
Модератор
Аватар пользователя
Статус: Не в сети

GeoIP: Kyrgyzstan

Сообщений: 803

Зарегистрирован: 02 мар 2010, 16:13
Благодарил (а): 6 раз.
Поблагодарили: 12 раз.
Raven
try:
sys.stdout.write('%s\n' % unquote(request.split('?')[1]))
except Exception:
sys.stdout.write('%s\n' % unquote(request))


Изображение

Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
   Похожие темы   Автор   Ответов   Просмотров   Последнее сообщение 
Перенесенная ^_^

в форуме Linux

root

3

38

02 мар 2010, 16:15

Gen1us2k Перейти к последнему сообщению

Нет новых непрочитанных сообщений в этой теме Доступен клиент мгновенного обмена сообщениями Tkabber 1.0

в форуме Новости *nix

[Ботя]

0

449

25 янв 2014, 00:00

Гость Перейти к последнему сообщению

Нет новых непрочитанных сообщений в этой теме Выпуск проприетарного дистрибутива Альт Образование 8.1

в форуме Новости *nix

[Ботя]

0

223

09 ноя 2016, 21:30

Гость Перейти к последнему сообщению



Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Собрано Raven. Русская поддержка phpBB
phpBB SEO