Exim - Clamav
1. Exim и clamav может проверять проходящий SMTP-трафик двумя с методами:
- clamd
- clamscan
Остановимся поподробнее на этих методах.
Первый способ предполагает работу демона clamd. Exim может напрямую общаться с clamd через сокет. Демону clamd можно передать либо путь к файлу для проверки, либо само содержимое файла. Вариант с передачей пути к файлу приводит к меньшим накладным расходам, по сравнению со вторым. Однако при этом, по понятным причинам, clamd и exim должны находиться на одной машине.
В случае clamscan, exim делает канал, делает fork и затем запускает clamscan. В качестве параметров передается путь к файлу, в котором находится проверяемое письмо. Здесь все просто. Clamscan проверил файл, вернул статус exim-у и завершился.
Однако производительность при этом значительно страдает, т.к. clamscan должен считать с диска в память базу вирусов и проинициализировать структуру cl_engine. Эта процедура стоит нескольких секунд времени. Поэтому при большом почтовом трафике clamscan не удобен.
Иначе обстоит дело с clamd. Инициализация базы вирусов происходит один раз при загрузке демона. Clamd - многопоточный демон, поэтому издержки должны быть минимальными. Однако с момента появления проекта Clamav до настоящего времени clamd работает под FreeBSD очень не стабильно. Особенно под большими нагрузками.
2. Разработчики Clamav позаботились о возможности создания собственных программ, использующих clamav. API LibClamAV относительно прост. Работу процесса использующего libclamav можно разделить на ряд стадий:
- Загрузка базы.
- Инициализация структуры cl_engine.
- Сканирование файла/дескриптора.
- Освобождение памяти/завершение процесса.
Также достаточно часто используются функции перегрузки базы.
Приводить описание функций, используемых на той или иной стадии, не имеет смысла, т.к. они хорошо описаны в документации. Так же пример использования можно посмотреть в директории example исходных текстов clamav. Подробнее об API LibClamAV можно узнать на сайте проекта Clamav.
3. В отличие от Clamav код Exim за более чем 10 лет сильно запутался. Однако при определенной сноровке в нем легко разобраться. Ниже приведен патч для exim-4.66 для работы с libclamav, а так же основные принципы его работы.
Функция init_clam_engine() загружает вирусную базу и инициализирует cl_engine. Функция вызывается единожды при старте exim. После вызова init_clam_engine() процесс exim использует около 30 Mb памяти. При приходе нового SMTP-соединения exim делает fork. В результате у каждого дочернего процесса есть своя проинициализированная структура cl_engine. После завершения проверки память освобождать не обязательно, т.к. процесс через некоторое время завершится сам (вариантов не много: доставить письмо, положить его в очередь или отвергнуть).
В конфиге exim следует указать:
av_scanner = libclamav:local
Возможность работы exim с libclamav была реализована в весьма сжатые сроки, поэтому работает только проверка входящего SMTP-трафика.

