Задумался тут над одной сугубо юниксовой задачкой (не-юниксоедам не читать;))
Представим себе MTA (mail transfer agent) доставляющий в том числе и на системные локальные аккаунты, который в состоянии отрабатывать разнообразные /etc/aliases, ~$user/.forward*, а в них конструкции вида :include: и доставку в файлы и на вход программ. Доставка в файлы должна делаться от прав того, кто написал соответствующее правило доставки, то есть кто владелец соответствующего файла форварда, алиасов или включаемого из них файла. Всё бы ничего, но есть ещё задача группировки доставок: например, письмо шло на a и b, a через /etc/aliases развёрнуто на x и y, b через файл включенный из ~b/.forward - на y и z, z доставляется пайпом на программу. Чтобы на y поступила только одна копия, кто-то должен объединить адресные списки. Предположим, что управляющий процесс для надёжности работает не от рута (у него очень много разной информации перерабатывается, и сделать ошибку в логике или просто переполнить буфер нефиг делать). Принимать от него любые утверждения вида "это письмо доставляем на вход программе /uuu/vvv запущенной от юзера ttt" стрёмно. Какие есть выходы из ситуации?
- Вообще не обрабатывать алиасы и форварды недоступные управляющему юзеру. Метод конечно хорош для отделённых хранилищ вроде cyrus или CGate, но не соответствует условиям задачи.
- Запускать управляющий доставкой процесс от рута и делать проверку прав вручную (ручной развёрткой путей, проверкой прав доступа на них, и так далее). Метод sendmail и exim. Проблемы: большая опасность пробоя через рутовый код; замена системной отработки на свою нивелирует часть системных возможностей (например, acl'ей на FS).
Можно это частично лечить через setreuid() с установкой effective uid на проверяемого сейчас, но вероятность эксплойта при пробое это не сильно снижает.
- Плюнуть на контроль дупов вообще и доставлять на один адрес столько раз сколько получится (на файлы адресов и прочие вложенности вызывая дочерний процесс). Это путь postfix. Проблемы с защитой нет, но получать одно письмо много раз не сильно приятно;(
- Информацию доставки подписывать криптографически, а на этапе реальной доставки письма проверять подпись. Безопасно, но может процессор сожрать так что мало не покажется.
- Информацию доставки складывать в "куки" с длинным случайным именем, передавая управляющему процессу только имя этой куки. Безопасно, но сожрёт дисковую подсистему.
- Процесс, отрабатывающий локальные алиасы/форварды, живёт не только этот этап, но и последующую фактическую доставку и запоминает список целевых адресов в себе. Плохо тем, что если доставка на такого получателя (который может быть в виде vasya@:prog:/home/vasya/lib/incoming_filter) срывается, то на следующий раз запомнить получателя уже не получится - потребуется новое раскрытие.
Какие ещё могут быть идеи?
Пока что мне кажется что если подпись сделать максимально дешёвой (например, md5 от конкатенации строки кодированного направления с фиксированной строкой) - это составит минимум потребления процессора и в то же время даст достаточный уровень защиты. Подбирать md5 в условиях влома в работающий процесс вряд ли кто будет, а если будет - там и sha256 подоспеет;)
Представим себе MTA (mail transfer agent) доставляющий в том числе и на системные локальные аккаунты, который в состоянии отрабатывать разнообразные /etc/aliases, ~$user/.forward*, а в них конструкции вида :include: и доставку в файлы и на вход программ. Доставка в файлы должна делаться от прав того, кто написал соответствующее правило доставки, то есть кто владелец соответствующего файла форварда, алиасов или включаемого из них файла. Всё бы ничего, но есть ещё задача группировки доставок: например, письмо шло на a и b, a через /etc/aliases развёрнуто на x и y, b через файл включенный из ~b/.forward - на y и z, z доставляется пайпом на программу. Чтобы на y поступила только одна копия, кто-то должен объединить адресные списки. Предположим, что управляющий процесс для надёжности работает не от рута (у него очень много разной информации перерабатывается, и сделать ошибку в логике или просто переполнить буфер нефиг делать). Принимать от него любые утверждения вида "это письмо доставляем на вход программе /uuu/vvv запущенной от юзера ttt" стрёмно. Какие есть выходы из ситуации?
- Вообще не обрабатывать алиасы и форварды недоступные управляющему юзеру. Метод конечно хорош для отделённых хранилищ вроде cyrus или CGate, но не соответствует условиям задачи.
- Запускать управляющий доставкой процесс от рута и делать проверку прав вручную (ручной развёрткой путей, проверкой прав доступа на них, и так далее). Метод sendmail и exim. Проблемы: большая опасность пробоя через рутовый код; замена системной отработки на свою нивелирует часть системных возможностей (например, acl'ей на FS).
Можно это частично лечить через setreuid() с установкой effective uid на проверяемого сейчас, но вероятность эксплойта при пробое это не сильно снижает.
- Плюнуть на контроль дупов вообще и доставлять на один адрес столько раз сколько получится (на файлы адресов и прочие вложенности вызывая дочерний процесс). Это путь postfix. Проблемы с защитой нет, но получать одно письмо много раз не сильно приятно;(
- Информацию доставки подписывать криптографически, а на этапе реальной доставки письма проверять подпись. Безопасно, но может процессор сожрать так что мало не покажется.
- Информацию доставки складывать в "куки" с длинным случайным именем, передавая управляющему процессу только имя этой куки. Безопасно, но сожрёт дисковую подсистему.
- Процесс, отрабатывающий локальные алиасы/форварды, живёт не только этот этап, но и последующую фактическую доставку и запоминает список целевых адресов в себе. Плохо тем, что если доставка на такого получателя (который может быть в виде vasya@:prog:/home/vasya/lib/incoming_filter) срывается, то на следующий раз запомнить получателя уже не получится - потребуется новое раскрытие.
Какие ещё могут быть идеи?
Пока что мне кажется что если подпись сделать максимально дешёвой (например, md5 от конкатенации строки кодированного направления с фиксированной строкой) - это составит минимум потребления процессора и в то же время даст достаточный уровень защиты. Подбирать md5 в условиях влома в работающий процесс вряд ли кто будет, а если будет - там и sha256 подоспеет;)
no subject
Date: 2005-12-25 05:51 pm (UTC)(no subject)
From:no subject
Date: 2005-12-26 03:19 pm (UTC)(no subject)
From:no subject
Date: 2005-12-27 12:58 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:На то и смайлики
From:Re: На то и смайлики
From:Re: На то и смайлики
From:Re: На то и смайлики
From:no subject
Date: 2005-12-29 11:58 pm (UTC)no subject
Date: 2008-05-15 10:52 am (UTC)Не подскажете, как сделать, чтобы почтовые сервера могли проверять у exim подлинность пользователя? А то когда они ломятся "напрямую", то их отрубают по Autorization Required :(