Redis и разделение на разные аккаунты

alekciy

Новичок
Я понимаю, что для начинающих вопрос в принципе не возникает, а продвинутые используют один_сервер_(дедик/виртуальный)-один_проект и им вопрос не актуален, но тем не менее решил озадачить таким вопросом.

Представим контекст из двух сайтов и двух независимых разработчиках (фрилансеры, люди сторонние, т.е. потенциально ненадежные) каждый из которых работает только со своим сайтом и не должен иметь возможности вмешаться в работу другого. Доступа к конфигурированию самого сервера ни кто из них не имеет. У каждого свой ftp аккаунт находящийся в chroot внутри директории сайта, но сам php за-chroot-тен выше директорий сайтов, т.е. php доступа к серверу не имеет, но потенциально из php скрипта можно залезть в директорию чужого сайта. По сути - схема шаред хостинга.

Связка nginx и php-fpm с прописанным для каждого пула системным юзером + правильная настройка прав на файлы позволяет разграничить файлы двух сайтов с тем, что бы системный юзер одного сайта не мог править или даже видеть файлы (к примеру, файл конфигурации) другого. Ни какой suhosin патч для обеспечения безопасности не требуется, все срабатывает на уровне ОСи и прав доступа к файлам. Т.е. php скрипт одного сайта не может прочесть скрипты другого сайта.

Используя redis можно получить неплохой кэш кроме того в нем можно хранить сессии. Но в контексте предшествующего абзаца и отсутствия в самом redis возможности задания привязки аккаунта к определенной базе получается, что имеем дыру. Даже если сайты будут находится каждый в своей redis базе, ни что не мешает сделать SELECT, выбрать базу другого сайта и копаться в ней.

Возникает вопрос, как их максимально безопасно разграничить. На вскидку возникает только два варианта.

Вариант 1. Каждому сайту запускать свою копию redis-а. Соответственно в init.d скриптах заводить по отдельному скрипту с запуском отдельной копии redis. Плюсы и минусы:
+ полное разделение каждого сайта (все права доступа вполне настраиваемы до уровня привязки к конкретному системному юзеру);
- "усложнение" администрирования, в кавычках потому как условно ибо можно создать скрипт генерации нужного init скрипта;
- большее потреблении ОЗУ, понятно, что для двух сайтов не критично, но если их со временем станет несколько сотен? (хотя если я не ошибаюсь, ОС linux сама в ОЗУ занесет только одну копию кода redis сервера и реальное потребление ОЗУ будет меньше, чем количество_сайтов*количество_ОЗУ_под_redis);

Вариант 2. Для всех сайтов работает одна копия redis. Но через rename-command в файле конфигурации команда SELECT переименовывается. Реквизитов доступа к redis разработчики сайтов не знают и используют класс-прослойку код которого зашифрован через Zend Encoder и в этом классе захардкожено новое имя для SELECT. Класс сам выбирает требуемую базу. Соответственно разработчики самостоятельно не смогут выбрать чужую redis базу. Плюсы и минусы:
+ с точки зрения администрирования практически ни каких изменений;
- потенциально возможность смены базы остается ибо ограничена только незнанием разработчиков нового имени команды SELECT;
- логика класса-прослойки по сути сосредоточена в двух местах, в самом классе и в файле конфигурации redis, если нужно будет еще раз сменить имя команды, то правку нужно будет не забыть внести в два места;
- при добавлении новых сайтов нужно будет править и код класса-прослойки.

Вариант 1 видится более предпочтительным, но смущает увеличение потребления ОЗУ под такую схему. Вариант 2 более "привычен", т.к. один сервис - один процесс, но потенциально видится не совсем безопасным. Опять же, если linux будет гарантированно держать в ОЗУ одну копию кода сервера в случае запуска нескольких инстансов, то следует использовать без раздумий вариант 1, имхо.

Есть ли другие варианты? Ну пустил ли я чего для приведенных вариантов? Вообще, есть ли какие либо комментарии?
 

fixxxer

К.О.
Партнер клуба
1) redis не предоставляет средств аутентификации. все подобные способы обходялся элементарно - берем и работаем с нужным инстансом вручную. да хоть через fsockopen.
2) раз смог установить redis, значит это точно не shared hosting - что мешает разнести все на две виртуалки?
 

alekciy

Новичок
1) redis не предоставляет средств аутентификации. все подобные способы обходялся элементарно - берем и работаем с нужным инстансом вручную. да хоть через fsockopen.
2) раз смог установить redis, значит это точно не shared hosting - что мешает разнести все на две виртуалки?
1) Хм... да, но:
а. если каждый инстанс работает через unix socket, то можно выставить права на сокет и залезть в чужой redis не получится (понятное дело не прокатит для схемы через tcp);
б. по умолчанию выбирается база 0, если сайт-1 висит на базе 1, а сайт-2 на базе 2 и SELECT переименован через rename-command, то даже в случае самостоятельного коннекта сменить базу не получится.

2) Да, не шаред, чистый дедик, но по сути сейчас работает как шаред. Там просто есть общий кусок движка кроме того виртуалки как ни крути это большие накладные расходы в том числе по ОЗУ (хотя на сколько я помню тот же OpenVZ код серверов шарит между виртуалками что немного выправляет ситуацию). Опять же на каждую виртуалку свой IP, а на сервер в целом можно только 3 адреса получить. Опять же, зачем связываться с более сложной схемой, если и по схеме шареда может работать. Поэтому вопрос больше в создании максимально защищенного окружения которое можно реализовать в текущих условиях.

P.S. Вообще для кэша и сессий было бы очень круто заюзать кэшер на SH через IPC, права как и на файлы настраиваемы, но я ни чего подходящего мне не нашел. Вариант написания своего отложен пока в todo, т.е. хз когда дойдут руки да и в redis устраивает все, кроме изложенного в топике аспекта.
 

Yoskaldyr

"Спамер"
Партнер клуба
Если ядро линкуса из последних, то можно поднять легкие виртуалки на базе linux containers (lxc).
Если не поднимать виртуальную систему полностью, а делать зеркало основной в ридонли режиме только с собственными var и etc каталогами, то накладные расходы минимальны.
Сам пробовал на Oracle Linux + UEK2 ядро. Поднял 3 изолированных php-fpm, каждый со своими настройками + каждый со своим редисом (да редис мне тоже нужен ;))
Почему надо было полностью изолированные пхп, т.к. не устраивал стандартный функционал пулов php-fpm, где не все настройки можно менять для каждого пула (тот же xcache по любому будет общий для всех пулов)
 

Yoskaldyr

"Спамер"
Партнер клуба
Главный плюс lxc что ничего не надо пересобирать, т.к. идет в составе ванильного ядра (если конечно оно из последних)

И еще, забыл написать, что мануалов насчет Lxc в инете много, но все они по полной виртуализации системы, а не изолировании конкретного процесса.
Поэтому надо смотреть пример изолирования sshd, который идет в стандартных шаблонах lxc (предустановок для виртуальных систем).
Используя этот пример в качестве заготовки, запускаем вместо sshd какой-либо шелл скрипт который стартует нужные сервисы внутри виртуального окружения. У меня это редис, php-pfm и sshd
 

alekciy

Новичок
Судя по описанию что-то похожее на фрибсдшный jail. Да, вариант, нужно будет опробовать.
 

alekciy

Новичок
Почему надо было полностью изолированные пхп, т.к. не устраивал стандартный функционал пулов php-fpm, где не все настройки можно менять для каждого пула (тот же xcache по любому будет общий для всех пулов)
Сколько такая связка берет под себя ОЗУ? Наверное на начальном этапе lxc не было и потом лишь пришли к нему? Т.е. если ли моменты о которых можно сказать "до" и "после".
 

Yoskaldyr

"Спамер"
Партнер клуба
Судя по описанию что-то похожее на фрибсдшный jail. Да, вариант, нужно будет опробовать.
Да, очень похоже, только понавороченнее.
Сколько такая связка берет под себя ОЗУ? Наверное на начальном этапе lxc не было и потом лишь пришли к нему? Т.е. если ли моменты о которых можно сказать "до" и "после".
Да сначала у меня не было lxc. Было несколько вдс-ок.

Сначала для тестов надо было чтобы было несколько различных версий пхп (5.2, 5.3, 5.4).
Сделать по обычному все внутри одной системы можно, но очень это не удобно - нормально с репозиториев не поставишь не обновишься и вообще куча геморроя :(
Потом понадобилось для разработки создать и изолировать еще несколько окружений
Понял что покупать каждый раз виртуалку - нет никакого смысла, а проще все подлнять на собственном выделенном сервере и там поднимать сколько мне надо виртуалок и управлять как мне ими захочется.

Но были несколько условий:
Хотелось чтобы можно было использовать UEK ядро от оракла (без всяких патчей и пересборок) и хотелось чтобы были минимальные накладные расходы на виртуализацию.
UEK ядро автоматом отметало OpenVZ.
С другой стороны мне полная виртуализация не нужна - достаточно было по максимуму изолировать одни процессы от других и по возможности использовать какую-то свою виртуальную файловую систему. И случайно в оракл блогах наткнулся на пример использования lxc. И понял что это именно то что мне надо. Можно изолировать как процесс, так и виртуализировать систему полностью. По умолчанию при изоляции ничего не ограничивается, но при желании можно ограничить CPU, память, диск, сеть да и почти все что угодно.

Если по простому и очень упрощенно то lxc - это облегченный вариант OpenVZ, вариант который сразу есть в последних ванильных ядрах.

По тестам быстрее OpenVZ. Накладные расходы по памяти минимальны - до 100Кб однозначно (столько в памяти занимает скрипт инициализации контейнера). А сама изоляция делается за счет использования встроенного функционала ядра cgroups, так что на скорость работы скриптов изоляция никак не сказывается (вернее сказывается, но все в пределах погрешности измерения)

Основной минус - документации очень мало и почти вся по полной виртуализации системы (что конечно же куча накладных расходов по памяти). К тому же из-за того что сами утилиты администрирования постоянно пилятся, могут быть косяки с путями в конкретной системе. Разрабы lxc насколько я понял пишут исключительно под дебиан, поэтому пути часто захардкодены в скриптах и могут отличаться от путей на других системах. Например, даже установив lxc на OL6 из репов оракла, все равно были небольшие косяки с путями. С другой стороны все решается правкой пары шелл скриптов или изменением путей внутри контейнера и один раз настроив контейнер, делать копии по аналогии - дело пары минут.
 

Yoskaldyr

"Спамер"
Партнер клуба
alekciy, Я писал выше, но еще раз повторю - не все изолируется в пулах php_fpm. Например xcache точно один общий для всех пулов. Может и какие другие модули будут вести себя подобным образом. Так что если нужна полная изолированность между клиентами, то пулы php_fpm не совсем подходят и надо запускать независимые процессы php_fpm (или через разные конфиг файлы или через полную изоляцию)
 

fixxxer

К.О.
Партнер клуба
openvz ничего никуда не шарит, и вообще пора про него забыть, весь нормальный код оттуда уехал в lxc

шарит KSM
 

Yoskaldyr

"Спамер"
Партнер клуба
openvz ничего никуда не шарит
Ну я же такого и не говорил.
Просто когда искал решение, искал самое оптимальное в плане фич, удобства настроек и производительности, которое бы решило мою задачу. И если бы не было lxc, не знаю на чем бы остановился - может даже на OpenVZ.
 
Сверху