qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (фига)
[personal profile] qkowlew
...он с любопытством ковырялся в пойманном проклятии, всё ещё колебавшемся на кончике палочки, вытягивал пальцами красные искры и отщёлкивал их в стороны, разбирая заклинание на части, словно детскую игрушку-конструктор...

Домен зареган 1 ноября 2013.

Сайт залит на хостинг 6 ноября 2013.

8 ноября 2013 в него добавлено минимум три закладки формата "приход с запросом POST на определённый URI сотворяет и исполняет PHP код" и одну формата "создаём ежеминутное задание в кронтаб, исполняющее созданный 1.sh который творит бинарные файлы libworker.so и /usr/bin/host, причём их содержимое зависит от архитектуры. :)

В 2014 и в 2015 годах, явно по случаю продления домена, админы хостинга просыпались и обращали внимание, что сайт что-то делает не то. На тему чего его блокировали и частично очищали от говна (но часть говна, особенно бинарник /usr/bin/host, жила неизменно).

Cледы этого - в тикет-системе хостера, с датами блокировок

24 января (неизвестно, правда, каким кодом, и мне откровенно лень искать) в корне сайта было нагенерено около 80 тысяч статических .html, представляющих собой фишинговые страницы, имитирующие страницы магазинов японоязычного содержания, при этом сделанные как "якобы вы сюда пришли с результатов поиска в Yahoo", но формочки при этом отправляют POST с интересными данными на разные странные адреса.

25 января хостер написал ругательство - исправьте в течение недели а то заблокируем.
Примерно вчера заблокировали.

Иными словами, в течение 2 с лишним лет сайт не столько служил его заказчику, сколько помогал зарабтывать бабло целой пачке злоумышленников.

Сегодня я всего лишь копаюсь в коде этого угробища.

Date: 2016-Feb-19, Friday 17:29 (UTC)
From: [identity profile] besm6.livejournal.com
Вопрос о платформе - это вопрос о врожденных дырах в ней, о ее типичном применении, или о ее применении в данном экземпляре?

Дыру-то можно оставить в чем угодно, и практически в любом скриптовом языке (т.е. в языке, в котором есть штатный eval, совмещенный с read), оставить ее - раз плюнуть.

Ну, если eval внешних данных применяется в самой платформе, то это, конечно, однозначный крест на платформе. Если в типичном применении - неоднозначный, но тоже крест...

А так-то я такую дыру могу даже на хаскеле оставить. На хаскеле, правда, специально постараться придется...

Date: 2016-Feb-19, Friday 18:06 (UTC)
From: [identity profile] qkowlew.livejournal.com
1. Типичное применение идиотом-вебмастером.

Причём для Джумлы, по моим наблюдениям, "порог вхождения" получается минимальным. Все прочие массовые CMS (Друпал, Битрикс, Wordpress) в настоящее время требуют от уеб-мастера хотя бы чуть чуть более сложных умственных усилий для получения того же результата. Джумловоды-идиоты периодически меня поражают в пятку.

2. Для этого продукта характерна жуткая мешанина файлов всех типов по многим каталогам, не позволяющая применить хотя бы жёсткое разбиение на "тут код может что-то писать, но записанное не будет в дальнейшем ниоткуда исполнено/инклюднуто/eval-нуто" и на "тут лежит только код, и каталоги и сам код в RO". Количество +w на подкаталогах безобразно велико.

Date: 2016-Feb-19, Friday 18:52 (UTC)
From: [identity profile] beldmit.livejournal.com
Я в своё время фалломорфировал от того, что типичная инструкция на PHP-поделие содержит фразу "не работает - выполните chmod 0777".

Date: 2016-Feb-19, Friday 20:06 (UTC)
From: [identity profile] besm6.livejournal.com
Ну вот, кстати, сейчас я на работе вожусь с redmine. Так, чтобы код и конфиги принадлежали одному юзеру, а работал от другого, и оба не руты. ruby не системный, он там ровесник мамонтов, и тоже не хочу ставить от рута, благо rvm позволяет.

Нет, с ним все гораздо лучше, вроде как всего три дерева директорий надо обработать chown и chmod, но тоже, в общем, тонкая работа. При том, что я живу под линуксом, а не под виндой, и в юниксовой системе прав на файлы разбираюсь куда лучше, чем типичный веб-программист. В смысле, не в общих чертах, а в деталях...

Date: 2016-Feb-19, Friday 23:00 (UTC)
From: [identity profile] qkowlew.livejournal.com
На самом деле от языка очень слабо зависит.
Это именно была принята ошибочная парадигма массового сайта "исполнение содержательного кода на сервере происходит ровно под тем же пользователем, под которым происходит управление файлами с этим кодом и (в случае MySQL) управление даными и их частью - тоже.

Все. Абсолютно все CMS на базе этой ошибочной парадигмы так или иначе вводят минимум две сущности - администратора и посетителя сайта (на эти две градации хватает понимания всех вебмастеров, замечу. Но не более).

И вместо того, чтобы сделать изначально деление на уровне unix users, chroot/jail (я перечисляю дешёвые по ресурсам варианты, если что), следование описанной парадигме и приводит к безнадёжной ситуации просто из-за нарастания сложности CMS.

Edited Date: 2016-Feb-19, Friday 23:03 (UTC)

Date: 2016-Feb-20, Saturday 05:57 (UTC)
From: [identity profile] besm6.livejournal.com
В том, что это ошибочная парадигма, согласен. Но кстати, вот так вот сходу совершенно не вижу, как можно без дикого переусложнения обеспечить, чтобы управление данными происходило не от имени сайта (того unix user, от чьего имени код исполняется).

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

Если говорить за какую-нибудь bug-tracking system (довольно типичный пример не вполне тривиальной CMS), там рядовой посетитель, порой даже не авторизованный, создает тикеты, загружает файлы к ним (файлы хранятся в файловой системе), меняет состояние тикетов... И workflow такой, что на уровне пользователей что БД, что ОС, хрен разнесешь, что можно делать админу, а что рядовому пользователю.

С ОС пример сходу: право на создание и на удаление файла в UNIX - одно и то же право, а в workflow это с большой вероятностью разные права. Ну, с БД и того понятнее - разные переходы между состояниями тикетов (изменение одного и того же поля в одной и той же таблице, только в зависимости от того, что там было и что стало) допустимы для разных посетителей.

Я не вижу вменяемого способа растащить это по разным unix users и database users.

Есть, конечно, сайты, где посетитель может только читать, но даже сделать заказ - это уже workflow, который по разным юзерам БД достаточно просто не разнесешь. Наверное, еще можно, но уже сложно, и не факт, что не просядешь на порядок в производительности.

Date: 2016-Feb-20, Saturday 15:55 (UTC)
From: [identity profile] qkowlew.livejournal.com
управлять данными нужно вне зависимости от того, пришел к нам через веб-интерфейс администратор или рядовой посетитель.

Разными частями данных.
На данный момент самая хитрожопа конструкция у меня на хостинге имеет 4 части:
- Администраторов (RW на всё)
- Модераторов(RW на большую часть таблиц)
- Зарегистрированных посетителей не-модераторов (RW на малую часть таблиц)
- Анонимных посетителей (Read-Only на всё, статистика собирается из лога вебсервера, не компостируйте мозг сбором статистики в базу)

4 пользователя одной базы данных, соответствующие этим уровням доступа, "разведены" путём давания прав по отдельным группам ТАБЛИЦ базы.

Я не вижу вменяемого способа растащить это по разным unix users и database users.

В рамках накопленного к настоящему времени кода - и я не вижу, в общем-то. :)

Идейно "как можно было бы сделать правильно" - вижу вполне:

Для сайта делается "jail" - контейнер, в котором

1. Код, исполняемый для анонимного пользователя сайта, исполняется под спец юзером nobody с обязательным чрутом, соотв каталогами и квотами.
2. Всякий залогиненный пользователь - это пользователь в рамках unix системы авторизации с выдачей оному коду домашнего каталога и всех сопутствующих товаров, с (возможным) чрутом и квотами. И кодом, который ему доступен для исполнения, но не для правки.
3. Всякий "администратор сайта" - это пользователь, имеющий судо в рамках оного "контейнера" и соответствующий код, доступный ему для исполнения.

Почему, по твоему, эта логика НЕ применима для доступа к unix системе по http[s] протоколу,чем он таким СЕЙЧАС отличается от любого другого доступа к unix системе? :)
Edited Date: 2016-Feb-20, Saturday 15:56 (UTC)

Date: 2016-Feb-20, Saturday 17:54 (UTC)
From: [identity profile] besm6.livejournal.com
И как у тебя в этой хитрожопой конструкции обеспечено, чтобы один зарегистрированный пользователь не мог попортить в тех же таблицах данные другого зарегистрированного пользователя? В предположении, что в коде есть дыра, и он сумел ее, намеренно ли или нечаянно, проэксплойтить.

Что до твоей идеи "как правильно"... Я вижу резкое проседание по производительности и резкий подскок по требованиям к железу. Потому что

- общую базу данных сразу отказать, данные каждого пользователя храним у него.

- поэтому любой запрос, касающийся более чем одного пользователя - шерстить данные каждого, каждый раз с проверкой на уровне ядра, есть ли у данного конкретного тебя право читать данные конкретные данные, т.е. прорва переключений user space - kernel space (пример такого запроса - набор сообщений для модерирования в хронологическом порядке).

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

Сложные иерархический структуры доступа (типа менеджер группы пользователей или членство в группе A по факту членства в группе B) становятся невпихуемыми вообще, потому что в юниксовую модель прав они не лезут.

Сложные workflow, скорее всего, тоже невпихуемы, потому что конфигурация sudo далека от Тьюринг-полной. И вообще, я вижу что-то нездоровое в том, чтобы организовывать workflow через sudoers.

Не говоря уже о том, что дыра в логике, записанной в sudoers, по сути не отличается от дыры в sudo. А ты просто все дыры в безопасности из кода сайта предлагаешь унести в sudoers. Ты хорошо подумал?

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

В целом, конечно, идея эшелонированной обороны хороша. Но для сайта я не вижу ничего более эффективного, чем запуск движка от нерутового пользователя, у которого нет возможности писать туда, где хотя бы потенциально исполняемый код, плюс TLS для стаффа. Всё хотя бы минимально более защищенное в теории при переходе к практике оказывается как минимум сам-себе-DoS (а это тоже угроза), а скорее всего, и с дополнительными дырами в безопасности. Ну, часто еще можно добавить TLS для всех неанонимов, хотя на нагруженном сайте это тоже сам-себе-DoS.

Date: 2016-Feb-20, Saturday 23:32 (UTC)
From: [identity profile] qkowlew.livejournal.com
В этой конкретной хитрожопости - на одном уровне доступа никак не поделишь. Там главная задача была "не допустить выхода на уровень выше", который происходил (из-за древности движка) слишком часто и помногу, а шансов найти ВСЕ такие косяки, как показывает мой горький опыт, просто нет.

Сложные иерархический структуры доступа (типа менеджер группы пользователей или членство в группе A по факту членства в группе B) становятся невпихуемыми вообще, потому что в юниксовую модель прав они не лезут.

"Вы или крестик наденьте, или трусы снимите"

Я говорю НЕ о "сложной системе отношений всех частй данных", которая при даже очень адекватной реализации всё равно будет за пределом униксовых прав на каталоги и групп и ACL. Оная система отношений нужна настолько единичным сайтам из всей сети, что для её реализации СЛЕДУЕТ нанимать программиста, и пусть реализует. И ничто не мешает работать даже такой сложной системе отношений НАД системой прав unix-like, описанной мной.

Я говорю о той БАЗОВОЙ части unix-безопасности (rwxrwxrwx, группы, пользователи и их пространства данных), которая существовала в операционке и была ПОХЕРЕНА при реализации вебсерверов на некоем изначальном этапе их сотворения. А нужна она при этом буквально ВСЕМ пологовно сайтам, существующим в сети.
Edited Date: 2016-Feb-20, Saturday 23:33 (UTC)

Date: 2016-Feb-21, Sunday 20:12 (UTC)
From: [identity profile] besm6.livejournal.com
Погоди насчет ВСЕХ. Давай рассмотрим бизнес-модель гипотетической разработки движка на такой парадигме. Памятуя о том, что разработчик тоже кушать хочет. Целевая аудитория кто?

Хостеры, которые могут быть заинтересованы в предоставлении такого движка клиентам (и могут поучаствовать если не деньгами, то разработчиками)?

Масс-хостинги, предоставляющие конечному юзеру готовую CMS, типа WordPress, отпадают. Их не устроит неизбежная просадка производительности. Им давно уже юникс-логин каждому клиенту - непозволительная роскошь, не то что каждому пользователю каждого клиентского сайта.

Дешевые хостинги, предоставляющие клиенту один юникс-логин и возможность поднять сайт на любом из предлагаемых движков, тоже отпадают. Им логин для клиента - позволительная роскошь, а контейнер - уже нет. Он сразу недешевым станет.

Хостеры, которые предоставляют целый контейнер, сами по себе не клиенты. Они могут предложить клиенту шаблон контейнера с таким движком, но сами по себе не вносят никакого вклада в разработку.

Заказчики сайтов?

Владелец бизнеса сам по себе, если строит сайт лично, пойдет на один из масс-хостингов с готовой CMS, см. выше. Отпал.

"Компьютерщик" из конторы-заказчика? Ему сайт - не профильное занятие, ему нужно как можно проще. Любое, самое минимальное, усложнение - и привет, он не твой клиент. Он тоже для начала ткнется в масс-хостинг (и 90% там и останутся), а кому не хватит - будет заказывать сайт у веб-программиста. Чесаться о безопасности он будет только когда его взломают, и то, во-первых, не сразу, а во-вторых, безуспешно, поскольку квалификации один хрен не хватает.

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

Остается собственно веб-программист. Вклад в разработку может внести только достаточно квалифицированный. Дешевый не осилит ни участия в кодировании (не хватит квалификации), ни дотирования разработки (его ниша - это дешевые решения, пытаясь хотеть денег с заказчика, он проигрывает конкуренцию). Разных странных плагинов либо будет мало, либо те, что будут, будут, как в случае с PHP, хотеть chmod 0777. Потому что квалифицированному программисту оно в норме неинтересно, и даже он если будет делать, то "на отвяжись", т.е. в конкретной инсталляции работает, а работоспособностью в более общем случае никто с достаточной квалификацией не занимался.

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

(хвост не влез, продолжение следует)

Date: 2016-Feb-21, Sunday 20:12 (UTC)
From: [identity profile] besm6.livejournal.com
(хвост)


Я вот на себя примеряю. И свою задачу. http://www.suntimes.ru, если интересно. Дешевый хостинг с контейнером. Неапгрейдабелен (ядро слишком древнее). Релиз ОС был oldstable в момент установки. Что-то более серьезное - в России дорого, а зарубежный хостинг сопряжен с рядом проблем политэкономического характера.

Машинка слабенькая, по процессу на каждого юзера не потянет однозначно. На несколько порядков. Лучшее, что можно сделать - это фокус типа описанного тобой. Отдельный инстанс для стаффа, отдельный для личного кабинета зарегистрированного юзера, отдельный для публикации. Статистика и так считается по логам. Это, к счастью, не интернет-магазин, функциональность, одинаковая для анонима и юзера, проста и базы не требует. Но мне там платят не столько, чтобы я ради чуть более серьезной защиты тратил гораздо больше своих времени и сил на обеспечение безопасности. Я и функциональность-то не особо успеваю, у меня это не единственная и даже не основная работа. Будь вышеописаное обеспечено фреймворком из коробки, я бы пользовался, но не обеспечено. Но в любом случае, по сравнению с твоей концепцией, это паллиатив, а то, что реализует твою концепцию на моей задаче, не потянет моя машина.

А сайт, на котором есть безопасность, но нет нужной функциональности, никому не нужен. А тот, где есть функциональность, но не хватает безопасности, все же нужен.

Date: 2016-Feb-22, Monday 00:54 (UTC)
From: [identity profile] qkowlew.livejournal.com
бизнес-модель гипотетической разработки движка на такой парадигме. Памятуя о том, что разработчик тоже кушать хочет. Целевая аудитория кто?

В современных условиях - нет работающей бизнес модели на "правильной парадигме".

Не потому даже, что ресурсов не хватит (чушь собачья, анонимных посетителей основная масса, а на них ресурсы тратятся СТРОГО ТЕ ЖЕ, что в нынешней парадигме! Я же вроде ясно написал).

Просто из-за шаблонов поведения.
Из-за которых сайт-визитку, информация на котором меняется реже, чем продлевается домен, делают на node.js в отдельном контейнере (у меня один клиент с сайтом из 14 страничек съехал от меня из-за того, что решил, что node.js - это круто!), даже не генеря статик html для отдачи.

Date: 2016-Feb-22, Monday 01:17 (UTC)
From: [identity profile] qkowlew.livejournal.com
Берём твой проект. Читаем.

Обновление сайта — каждый четверг в 12:00 по московскому времени.

Иными словами - у тебя есть на самом сайте:
1. workflow с накоплением очереди.
И обработка очереди заявок раз в сутки, изменяющая статический контент базы и отображения сайта раз в сутки.
2. onclick="acquire_contacts(arguments[0]) - на что выдаётся всё равно статический (в смысле содержимого базы) результат.
3. Генератор workflow с личными кабинетами.

Если бы это реализовывалось в "правильной" парадигме - поект состоял бы из:
- юзера nobody, которому отдаётся контент только на чтение приложением /home/nobody/app_read_site с владельцем nobody и правами 0100 (права на каталоге /home/nobody 500), от статик html отличается только наличием отдаваемого по acquire_contacts
- инструментов администрирования сайта /root/app_admin с правами (грубо говоря - на слабой машине с единственным сайтом почему бы так и не сделать) root
- частей личного кабинета для каждого заведённого пользователя - .../userapp_money и .../userapp_zayavka - которые исполняются от имени пользователей user_nnnnn и в конечном итоге атомарно генерят элементы в единственной доступной этой группе пользователей на добавление элементов таблице базы данных - queue (как реализуемой - а пофиг, хоть в сислог писать, а при логротейт обрабатывать). А все контактные данные, тексты, доступные этому узеру на свободное изменение - лежат и меняются прямо в домашнем каталоге /home/user_nnnnn пользователя.

ВСЕ действия на запись в таблицы, кроме той, что очередь заявок - из кода админки.

http тут, https, ssh, rsync... а не так уж и важно какой протокол.
В правильной парадигме - залогиненный всегда остаётся в рамках своего домашнего каталога с данными и ограниченного набора кода, каким бы он ни был и НА КАКОМ БЫ (вплоть до компилируемых) языке ни был написан.
Edited Date: 2016-Feb-22, Monday 02:11 (UTC)

Date: 2016-Feb-22, Monday 08:36 (UTC)
From: [identity profile] besm6.livejournal.com
Ты не вполне угадал. Очередь - да. Но с обработкой fulltime и с обратной связью в рабочее время в течение нескольких минут, так что никакого раз в сутки и обработки при logrotate. Там workflow тот еще. Даже с точки зрения владельца объявления. Ой, мне поправить, ой нет, я платно не готов, давайте я изменю так, чтобы бесплатно проходило, и т.п.

В итоге у владельца в личном кабинете ссылки на штук пять-восемь (лень считать, сколько именно) списков вида "объявления, готовые к публикации", "объявления, которые требуется оплатить", "объявления, по которым требуется уточнение".

Что веселее, у оператора таких больше десятка.

В выпуске раз в неделю порядка 10 тысяч объявлений. Ну, допустим, процентов 20 подаются через сайт, но перспектива - ближе к 100, народ постепенно сдвигается в интернет. В основном в последние два дня перед закрытием приема в выпуск. На обработку одного объявления уходит в среднем штук семь запросов (4, кажется, минимум). Из них чуть больше половины - операторские, т.е. с подсчетом актуального состояния подготовительной информации по всем пользователям.

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

Не, в принципе можно сделать конструкцию, где процесс, работающий от имени юзера, вообще не будет ходить к базе, и будет написан на C, чтобы минимизировать время на инициализацию. А синхронизацию между основной базой, серьезной, и индивидуальными базами юзеров (эти хоть plain text) делать отдельным демоном. Тогда можно будет уложиться примерно в те же ресурсы по железу. Зато потребности в разработчиках на порядок выше.

То есть я за такое вообще не возьмусь ни за какие деньги, мне нервы дороже.

Date: 2016-Feb-22, Monday 09:13 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ты не вполне угадал.

Ну так у меня не было той дополнительной информации, что ты сейчас выдал. То, что я написал - по результатам БЕГЛОГО осмотра сайта, его структуры и его ЗАЯВЛЕННЫХ на нём самом ТТХ.

Там workflow тот еще. Даже с точки зрения владельца объявления. Ой, мне поправить, ой нет, я платно не готов, давайте я изменю так, чтобы бесплатно проходило, и т.п.

В итоге у владельца в личном кабинете ссылки на штук пять-восемь (лень считать, сколько именно) списков вида "объявления, готовые к публикации", "объявления, которые требуется оплатить", "объявления, по которым требуется уточнение".


Это не меняет сути нарисованной мной схемы.
Усложняет генератор задания от пользователя в очередь - да.
Требует выделения пользователю "песочницы" доступных только ему и root данных со сложной структурой обработки оных - да. Про демона и про висящие в памяти процесы юзеров (опять ты рисуешь этот ужас своих каких-то личных снов) - нет, ты бредишь.

НЕ требует такая постановка задачи обязательного перехода к парадигме "код, исполняемый для действий пользователя с информацией в личном кабинете пользователя, следует исполнять с правами root и с разрешением править всю базу, и только отсутствие ошибок и тщательное программирование каждой ветки защищает от пиздеца", в рамках которой ты приступил к работе ИЗНАЧАЛЬНО. :)

То есть - в "моей" схеме от дыр класса "пользователь сумел править ему недозволенное" защищает сама логика "пользователь не запускает кода, которому что-то позволено лишнее".

А в "твоей" схеме - "всё работает от рута, и малейшая неаккуратность в коде - поле для эксплойта, в какой бы части кода эта неаккуратность ни располагалась".

Подчеркну - да, всегда есть тонкости хотя бы с той же оплатой, подтверждение которой наверняка может приходить с трёх, а то и более сторон, а задержки в обработке заданий очереди критичны. Это усложнит и обработчик заданий в очереди.

То есть сложность распределена по разному.

Тебе проще "ни за какие деньги" не строить песочницы, а работать "чтоб всегда под рутом" - верю. Это как раз универсальная парадигма современного мира "всем написанным идиотами пользовательским программам в винде зачем-то вдруг требуются права администратора", и она привычна и всосана со спермой Билла Гейтса всем пользовательским населением сети. :)

И так, "под рутом", творить ВСЕМ проще, быстрее, спокойнее.
Хуяк - и в продакшн.

И потому получается то, о чём я написал в посте.
Массово.
Edited Date: 2016-Feb-22, Monday 09:14 (UTC)

Date: 2016-Feb-22, Monday 11:44 (UTC)
From: [identity profile] besm6.livejournal.com
Ку, ты невнимателен.

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

И я довольно подробно изложил свою точку зрения на то, откуда берется это удорожание. Any ideas?
Edited Date: 2016-Feb-22, Monday 11:49 (UTC)

Date: 2016-Feb-22, Monday 15:06 (UTC)
From: [identity profile] qkowlew.livejournal.com
Это ты невнимателен. :)

Я не говорил, что "мой" путь дешевле или проще.
Я не говорил, что "мой" путь не потребует от разработчика компромиссов.

Я считаю, что если бы за первые реализации http серверов брались, СОБЛЮДАЯ логику "логиненный - анонимный" (замечу - в формате лога того же апача есть инфорация о http логине, и при http авторизации она туда гарантированно попадает) и исполнение кода от соответствующих юзеров и групп - то к нынешнему моменту в качестве базы для реализации любого движка был бы не уродский апач с suexec костылями, а намного более эффективный код, в котором проблема производительности для переключения контекстов, о котором ты плачешь - была бы решена.

Пример перед глазами, реализованный как вполне живой, используемый народом продукт (пусть и не в http, а в mail) - хотя бы qmail, где нет отдельных узеров для всех "почтовых ящиков" или "посетителей", но есть хотя бы чёткое деление процессов по пользователям и по их роли в процессе обработки почты.

Я утверждаю, что завоевание мира логикой "все работаем от рута" в случае http серверов так, как они сейчас массово написаны, УБИЛО самую возможность делать НОРМАЛЬНО безопасный код.

Ты сетуешь о ресурсах разработчика, которые требуются для того, чтобы написать эффективный код в "моей" парадигме. Так в том и дело, что СЕЙЧАС огромные ресурсы разработчиков (время, жизнь) тратятся на то, чтобы разгрести именно состояние "все работаем от рута".

Фишка в том, что рынок эти затраты сейчас только подстёгивают и наслаждают.

Разрабы нагло отвечают "Чтобы исправить эти недостатки нашей CMS - заплатите нам за работу по исправлению примерно столько же, сколько платили нам за разработку". Прекрасно зная, что они могут оставить ЛЮБОЕ количество недостатков в коде - и к ним снова придёт с баблом и протянутой рукой этот заказчик.

Я это наблюдал несколько раз. Причём два случая - сознательно такие, ибо код зашифрован Zend и обфусцирован до невменяемости. Так что и не проверишь. Причём в одном случае, если суметь раззендить и посмотреть на имена файлов - видишь MODX, а не самостоятельно написанный движок. :)

Date: 2016-Feb-22, Monday 15:59 (UTC)
From: [identity profile] besm6.livejournal.com
Мнээ... полуэльф...

Во-первых, куда могла бы деться проблема производительности для переключения контекстов, если для защиты ты полагаешься на ОС? В этом раскладе отдельный залогиненный юзер - отдельный процесс, и никак иначе. Здравствуй, задача инициализации каждого такого процесса. Дальше можно искать компромисс между количеством одновременно запущенных процессов и временем на инициализацию вновь запущенного, но проблема уже стоит, и это - поиск ее кое-какого решения.

Во-вторых, должен заметить, что когда брались за первые реализации HTTP-северов, аутентификации в HTTP еще и в проекте не было. Ну, что вменяемых до сих пор никто не поддерживает, да и нету их нифига, это уже как раз исторический вопрос. Пользовались бы HTTP аутентификацией - были бы и поддерживались бы.

qmail я, знаешь ли, ставил. Снес довольно быстро, и знаешь, почему? В его модели невозможно проанализировать содержимое письма на этапе SMTP-диалога. В результате не существует корректного работоспособного способа оповестить отправителя о том, что мы отказываемся принять это письмо на основании анализа его содержания. Ну, там и других тараканов хватает. Логика анализа служебной информации у него тоже, мягко говоря, не на высоте. Короче, пока на него реальных задач не вешают, он быстрый и секьюрный.

А разделение ролей по задачам как у qmail (именно как у qmail, а не как у твоей идеи) - ну, так его любой современный движок умеет. Вот рут, от него работает только accept(2) на 80 порту, вот владелец кода, который апгрейдит код сайта, а вот пользователь, от которого этот код выполняется. К сожалению, не то чтобы прям вот все стандартные инструкции заточены под разделение второго и третьего, но уже многие, чесслово. (Тут есть засада - не всегда у разработчика кода сайта есть два логина туда, где он этот код тестирует. В результате он вынужден разрабатывать, совместив этих юзеров.)

Про твою идею я тебе рассказываю примерно то же самое. Что годится она для достаточно узкого класса задач, далеко не покрывающего реальные потребности веб-сервисов. В нем она секьюрная, хотя далеко не быстрая. На глаз - практически применима для сайта с примитивным workflow и частотой запросов единицы в минуту. Ну, малые десятки на непродолжительном пике. Практически - это значит, что код, реализующий необходимую функциональность сайта, все же будет своевременно написан. Теоретически можно сделать лучше, но практически никто этого не потянет.

И кстати, рута-то она реально требует. И далеко не только для того, чтобы занять 80-й порт. Те же описываемые тобой движки работают от одного юзера, но не от рута, как ты тут пишешь. А при нормальном контроле за разработчиками - и не от владельца кода. А твоя идея требует использования рутовых полномочий движком. В полный рост и со сложной логикой. Упс... Дополнительный вектор атаки... Безопасность, говоришь...

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

Date: 2016-Feb-23, Tuesday 10:40 (UTC)
From: [identity profile] qkowlew.livejournal.com
когда брались за первые реализации HTTP-северов, аутентификации в HTTP еще и в проекте не было

А вот telnet/ssh уже была. Мыль понятна? Я говорю о том, что http реализовывать стали БЕЗ авторизации, хотя опыт разницы в работе "без авторизации" и "с авторизацией" уже вроде как был, хехе. :)

А твоя идея требует использования рутовых полномочий движком.

Нет. Она не требует этого.
Ты невнимательно прочитал.
В работающем сайте "по моей идее" настоящий, операционной системы рут не нужен на исполнение кода сайта нигде.

Чтоб тебя не пугать слово "рут" - заменим его на admin

Рут нужен вебсерверу, да. "Идеальный" вебсервер по "моей" концепции на машине с unix узерами
admin_1 nobody_1 user_1_1 user_1_2 для админа, анонима и узеров 1 сайта,
admin_2 nobody_2 user_2_1 user_2_2 для админа, анонима и узеров 2 сайта,

должен "развести" посетителей в код, исполняемый от соответствующих unix пользователей, причём структура на FS может быть примерно такой:
/www/
 +- admin_1/
     +- user_1_1/
     +- user_1_2/
     +- nobody_1/
     +- site_1_code/
 +- admin_2
     +- user_2_1
     +- user_2_2
     +- nobody_2
     +- site_2_code/

admin_1 работает в своём чруте и имеет доступ к каталогам узеров.
admin_2 работает в своём чруте и имеет доступ к каталогам узеров.

Потому что хотя бы бэкапы взломщик тронуть не сможет - прав не хватит.

О боже, я разговариваю с человеком, который считает допустимой логику "бекап в пределах одного сервера" 8-О.

Date: 2016-Feb-23, Tuesday 20:47 (UTC)
From: [identity profile] besm6.livejournal.com
> А вот telnet/ssh уже была. Мыль понятна? Я говорю о том, что http реализовывать стали БЕЗ авторизации, хотя опыт разницы в работе "без авторизации" и "с авторизацией" уже вроде как был, хехе. :)

Ну, ssh тоже еще не было. Но вообще-то тут правильная мысль не та, что HTTP начали без авторизации, а та, что HTTP стали применять не по назначению. Видишь ли, HTTP изначально вообще не был предназначен для иной раздачи, кроме публичной. PUT в нем заложили плюс-минус изначально, но он оказался мертворожденным. По сю пору его почти никто не умеет. Ну, DAV-клиенты вроде научились. Без году неделя... Про авторизацию-то сразу подумали, но сразу и решили, что не надо ее закладывать в протокол, кроме кода 401. Есть мнение, что правильно решили-то...

> Чтоб тебя не пугать слово "рут" - заменим его на admin

Ты сам сказал про sudo.

Ну да, при наличии ACL (что уже несколько выбивается за юниксовую модель прав, ну ладно) твоя схема с некоторыми изменениями годится. В смысле, as is она тоже годится, но для совсем уж тривиальных задач. А как только у тебя на сайте появляется две различных роли стаффа, так сразу подавай ACL. Потому что роль реализуется группой, а в юниксовой модели as is группа у файла одна. Ну, к счастью, процесс может разрешить доступ к группе, которой у него своей нет (иначе б облом). Если есть ACL. То есть возможность использовать твою модель у нас намного моложе, чем юникс и HTTP. ACL у нас появились, кажется, в начале 2000-х, хорошо если не в середине первой декады. А во FreeBSD даже и не знаю, есть ли вообще.

В общем, да, без рута можно обойтись. Правда, теперь уже просто файл не создашь, а надо непременно развешивать на него ACL по числу ролей. На каждый. Движком. Откуда, кстати, брать список ACL под данный конкретный файл - тот еще вопрос... Нет, понятно, что из конфига сайта. Только... Там будет уже настолько сложная логика, что это будет уже код. И рутовые права при апдейте этого конфига, поскольку доступ к файлу может поменять либо его владелец, либо рут, а у тебя будет дофига файлов с разными владельцами. Ты все еще полагаешь, что это безопаснее, чем то, что есть? Really?

P.S. За бэкапы. Я реалист. Не всегда можно сделать, как у меня, когда база бэкапится на другую машину раз в час. Более вероятно, что бэкап за пределы хоста удастся делать довольно редко, а еще более вероятно - что такой бэкап будет максимум один, и всей системы целиком, хостеры если предоставляют бэкап, то только такого рода. А база-то немаленькая, в офис в Таганроге ее раз в час не особо забэкапишь. А там еще картинки, и вскоре их тоже станет немало.

Date: 2016-Feb-22, Monday 15:17 (UTC)
From: [identity profile] qkowlew.livejournal.com
И вот, наконец, САМЫЙ живой пример.

Unix системы в целом НЕ ушли от логики "тщательно разграничиваем пользователей". Несмотря на то, что это - по твоему - требует огромных затрат жизни и ресурсов разработчиков.

А виндовые системы, несмотря на появление (с windows NT 4 начиная) внятных средств деления прав пользователей и ACL на FS - массово живут в состоянии "все работаем из под админа, потому что очередная софтина так потребовала". Правда, поверх этой логики наворочены UAC, "переспрашивания - действительно ли пользователь хочет этого?" и тому подобная хуита, которая совершенн оничего по сути своей не меняет.

И сравни результат по безопасности, вирусам и прочая для этих двух групп систем :)

Примени не свои рассуждения, а ЭТОТ ОПЫТ - но к http протоколу. Что получится?
Edited Date: 2016-Feb-22, Monday 15:18 (UTC)

Date: 2016-Feb-22, Monday 16:17 (UTC)
From: [identity profile] besm6.livejournal.com
На задачах юниксов как таковых - нет, не требует. Покажи мне живой юникс, в котором одновременно залогинена пара сотен пользователей. На слабой машинке.

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

Задачи-то другие, блин. С другими требованиями к производительности. Это я на домашнем сервере могу спокойно отнестись к тому, что locate работает 2 с половиной минуты, и на ноутбуке больше секунды (не updatedb! locate!). Напрягает, но не очень сильно. А аналогичное действие на веб-сервере должно занимать не больше 1/100 секунды. Иначе оно просто не сможет решить поставленную задачу. На том, что оно занимало больше, погорел communiware. Вот, опыт.

Это mlocate, it indexes all the filesystem, but results of a search will only include files that the user running locate has access to. Безопасность...

Date: 2016-Feb-23, Tuesday 10:50 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ах, вот уже и разные задачи. :)
А как же "линукс способен заменить windows на десктопе", "микрософт офису есть реальные бесплатные альтернативы"?

Машинка, где w | wc -l давала бы результат около 30 - у меня лично давным давно стояла на Смольной на ip 213.134.196.7, и была 486SLC2-40/4M RAM/(не помню сколько размер харда), 10 Мбит сетевуха. Служила Primary DNS сервером для кучи доменов, а также для некоторого количества народу маленьким развлечением в шелле, без графики. sudo был только у меня. :)

Железка сейчас не работает, так как на ней умер onboard контроллер харда. Иначе я бы, пожалуй, постарался на ней поднять что-нибудь просто из принципа.
Edited Date: 2016-Feb-23, Tuesday 10:51 (UTC)

Date: 2016-Feb-23, Tuesday 18:46 (UTC)
From: [identity profile] besm6.livejournal.com
Это ты меня спрашиваешь насчет "заменить windows на десктопе"? Меня можно спрашивать насчет замены десктопой парадигмы на что-нибудь вменяемое. UI у меня линуксовый, если что. Винда поднимается только ради разработки под винду.

Но задачи действительно разные, что тебя удивляет? В смысле, разные не между виндой и линуксом, а между нормальной юзерской работой и работой нагруженного веб-сервера.

30 - это неинтересно. Интересно несколько сотен, и не развлечения в шелле, а хотя бы 20 запросов в секунду. На всех. Ок, без UI. Нет, не "Hello, world" на C. "Hello, world" на ruby в качестве теста кое-как сгодится, только с подгрузкой штук пяти хотя бы модулей. Тут как раз - либо много памяти, если много процессов одновременно, либо небыстрая инициализация.

Date: 2016-Feb-24, Wednesday 00:56 (UTC)
From: [identity profile] qkowlew.livejournal.com
30 - это неинтересно

Э. Ты правда считаешь, что неинтересно на машинке ЭТОГО класса?
Вообще-то это, напоминаю, процессор в корпусе 386SX, внешней шиной 20 МГц, внутренним кешем 1к и ядром, работающих на 40МГц. И 16-битная шина внешняя с 4-мя SIMM 40pin на ней. И ISA Only для периферии.

Я понимаю, что "эпоха сменилась", и "языки теперь почти только интерпретируемые и скриптовые", и "что такое 4 мегабайта?"

Для полноты картины - на какой конфигурации вертится твой проект?

Date: 2016-Feb-24, Wednesday 07:37 (UTC)
From: [identity profile] besm6.livejournal.com
Я правда считаю, что это неинтересно в рамках рассматриваемой задачи. В рамках некоторых других задач интересно, почему нет?

zsh% free
             total       used       free     shared    buffers     cached
Mem:      49961176     258924   49702252          0          0          0
-/+ buffers/cache:     258924   49702252
Swap:            0          0          0


Intel(R) Xeon(R) CPU E5430 @ 2.66GHz, 8-ядерный, но это виртуалка, и я там сильно не один.

Лимиты выставлены довольно приличные, в нынешней конфигурации близко не подходил. Но при заливке свежего выпуска и последующем набеге читателей на свежий выпуск проседает конкретно, до писем от яндекс-метрики, что за 10 секунд сайт не ответил. То есть фактического запаса-то нет, хотя формально вроде как есть, и большой.

А вот если начать делать по процессу на юзера, то уже придется заботиться о том, чтобы не упереться в лимит по количеству процессов. Впрочем, если писать не на чистом C, то сперва упремся в фактический лимит по памяти. В лимит по процессам - это если процессы почти не занимают память...

Date: 2016-Feb-25, Thursday 04:34 (UTC)
From: [identity profile] qkowlew.livejournal.com
сперва упремся в фактический лимит по памяти

Вот вот.
Я очень хорошо помню, как в процессе секспериментов с видеотрансляциями обнаружил, что видеосервера равной вроде функциональности могут кушать от 14К до 200М на 1 посетителя... :)

Date: 2016-Feb-29, Monday 12:17 (UTC)
From: [identity profile] qkowlew.livejournal.com
http://copy.sh/v86/ - по поводу. :)

Date: 2016-Feb-24, Wednesday 15:05 (UTC)
From: [identity profile] anonim-legion.livejournal.com
Вот как раз в виндовых серверах, на IIS, штатно используется запуск кода веб-приложения с правами авторизовавшегося на сайте пользователя, и обращения к БД будут идти из под его же аккаунта. Там оно прозрачно.

>результат по безопасности, вирусам

Линуксовых десктопов не бывает, там нет вирусов. На виндовых веб-серверах веб-зараза не водится, там для нее слишком некомфортно.

Date: 2016-Feb-22, Monday 01:25 (UTC)
From: [identity profile] qkowlew.livejournal.com
по процессу на каждого юзера не потянет однозначно. На несколько порядков.

Бред.
Постоянно запущенных процессов "на каждого узера" по http не требуется в принципе. Логин пользователя - создание сессии. Разлогинивание - убиение сессии. Отправка пользователем формы - запуск кода .../userapp_money или .../userapp_zayavka соответственно. Никак не больше, чем получается в классическом php движке.

Просто запуск соотв кода осуществляется не cо стандартного вебсерверного www - а с user_nnnn причём в рамках существующей парадигмы этого даже можно добиться через suexec-подобные решения ("стартовать код в соответствии с unix владельцем и правами файла, в котором он находится") и патчи nginx'a + cgi всяческое. В настоящее время эти костыли уже многократно услоджнены и перетяжелены, и проверок типа "а мы вообще в base directory попали, или погулять вышли..." насажено во все дыры.
Edited Date: 2016-Feb-22, Monday 02:13 (UTC)

Date: 2016-Feb-22, Monday 08:52 (UTC)
From: [identity profile] besm6.livejournal.com
Я не про то, что они все одновременно работают. Я про то, что их на каждый запрос надо запускать. Ну, если действовать по простой схеме. Пришел залогиненный юзер - запустили процесс от его имени. Потратили ресурсов на инициализацию, отработали запрос, заглушили. Через 10 миллисекунд он пришел за картинкой - снова запустили. Через 100 миллисекунд пришел другой - запустили от его имени. На пике - несколько десятков инициализаций в секунду.

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

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

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

Date: 2016-Feb-24, Wednesday 15:07 (UTC)
From: [identity profile] anonim-legion.livejournal.com
>Пришел залогиненный юзер - запустили процесс от его имени

В виндах не надо никаких процессов запускать, ImpersonateLoggedOnUser имеется. В линуксах наверняка есть аналог.

Date: 2016-Feb-24, Wednesday 22:06 (UTC)
From: [identity profile] besm6.livejournal.com
Никаких LoggedOn. В любого юзера, только при наличии соответствующей capability (в норме она есть только у рута), и главное, это билет в один конец.

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

Поэтому практика применения setuid() включает выполнение минимум одного exec() на каждый setuid() - либо незадолго до, либо сразу после.

login, sudo и su работают по схеме "сразу после" - авторизовали юзера, setuid() и сразу exec() команды, которая уже будет выполняться от юзера. При этом в памяти процесса гарантированно не будет данных, которые были в памяти родителя-рута, и которые юзеру знать не положено.

А всякие почтовки, веб-сервера и т.п., особенно когда надо SSL, предусматривают возможность некоторые данные прочесть под рутом и сохранить после setuid() - у них, соответственно, exec(), минимальная инициализация под рутом, setuid(), и только потом остальная инициализация.

Date: 2016-Feb-22, Monday 02:19 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ну и вот - я тоже "заражён шаблонами", когда писал первый вариант ответа на это твоё сообщение. :) Как-то забывается, что в нормальной ос ls в единственном экземпляре исполняется от любого пользователя с его правами, а класть код в каталог пользователя как раз не надо.

И вообще, у пользователя в рамках его домашнего каталога +x не должно быть вообще ни на каких файлах. А набор доступных бинарников - ессно, тоже "шаг вправо - шаг влево".

Date: 2016-Feb-20, Saturday 16:58 (UTC)
From: [identity profile] beldmit.livejournal.com
В базах кое-что можно сделать с помощью ROW LEVEL SECURITY.

Date: 2016-Feb-20, Saturday 17:11 (UTC)
From: [identity profile] besm6.livejournal.com
И что, реально можно ограничить на уровне "владельцу вон той записи из вон той таблицы можно в этом поле этой записи этой таблицы менять 1 на 3, но не на 4, а 2 вообще менять нельзя"? При том, что эта запись могла быть создана совершенно другим пользователем. Связь - по foreign key из этой таблицы в ту.

Фрагмент workflow, с точностью до конкретных значений, вполне реальный.

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