Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> Мелочи —> ClamAV mirror

Создание неофициального зеркала обновлений ClamAV

Автор: lissyara.


    В связи с тем, что внезапно и как-то резко расплодились филиальные сервера с почтой, встал вопрос о своеврменном обновлении антивирусов на них. Использовался ClamAV, причём исключительно для проверки почты. Поиски по инету со словами 'clamav mirror' дали инструкцию, прочёв которую я не понял одного - зачем так извращённо - надо региться, надо белый IP и т.п. Дальнейшие поиски привели вообще к полному непониманию происходящего - авторы не поддерживают и не хотят чтобы были закрытые зеркала. Зато рекомендуют тем, у кого много машин во внутренних сетях, использовать кэширующий прокси, настроив его в конфиге freshclam.
   Идея с прокси меня нифига не вдохновляла, зато идея зеркала - ещё как. Поэтому, перечитав инструкцию по созданию официального зеркала, приступил к созданию своего, приватного. Для начала был сделан виртуалхост в апаче, на одной из незагруженных машин:
#

<VirtualHost *:80>
        ServerAdmin     admin@lissyara.su
        DocumentRoot    /shares/sites/clamav_mirror/data
        ServerName      clamav.my-domain.local
        ServerAlias     clamav
        CustomLog       /shares/sites/clamav_mirror/log/access.log      combined
        ErrorLog        /shares/sites/clamav_mirror/log/error.log
</VirtualHost>

   После прописания имени в DNS, полез на один из серверов, рихтовать конфиги - по дефолту freshclam у меня нигде не был включен. Поэтому, прописываем его в автозапуске:
grep lam /etc/rc.conf
# ClamAV
clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"

   Правим в конфиге имя зеркала на то, которое у виртуалхоста в апаче:
grep Mirror /usr/local/etc/freshclam.conf
#DatabaseMirror db.XY.clamav.net
DatabaseMirror clamav.my-domain.local

   Запускаем:
/usr/local/etc/rc.d/clamav-freshclam start
Starting clamav_freshclam.

   Тутже наблюдаем в логах апача такое:
[Fri Oct 05 09:14:50 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:50 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:50 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:50 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main.cvd
[Fri Oct 05 09:14:56 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:56 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:56 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:14:56 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main.cvd
[Fri Oct 05 09:15:01 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:15:02 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:15:02 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main-44.cdiff
[Fri Oct 05 09:15:02 2007] [error] [client 172.30.102.18] File does not exist: /shares/sites/clamav_mirror/data/main.cvd

   Ну, а далее немного лирики и скрипт. Вначале я решил, что тут всё просто - тупо парсим логи, ищем имена файлов которые оно хочет, их вытаскиваем с удалённого сервера. Тут же был написан скрипт, который успешно эксплуатировался ровно сутки:
cat /shares/sites/clamav_mirror/clamav_update.sh
#!/bin/sh

# даннынй скрипт парсит логи апача для заданного
# виртуалхоста, и ищет файлы, на которые апач дал
# 404 ответ. Т.к. на этот хост ходят тока филиальные
# сервера - за обновлениями, то это и будут файлы обновлений.
# тупо скачиваем их с одного из зеркал, и всё.

# переменные
home_dir="/shares/sites/clamav_mirror"
http_err_log="log/error.log"
http_root_dir="data"
clamav_mirror="database.clamav.net"
clamav_version_server="current.cvd.clamav.net"

# приложения
cat="/bin/cat"
grep="/usr/bin/grep"
awk="/usr/bin/awk"
sort="/usr/bin/sort"
uniq="/usr/bin/uniq"
fetch="/usr/bin/fetch"
host="/usr/bin/host"
tr="/usr/bin/tr"

# достаём имена файлов, что просили клиенты
${cat} ${home_dir}/${http_err_log} | ${grep} "File does not exist" \
        | ${awk} -F "${http_root_dir}/" '{print $2}' | ${sort}  \
        | ${uniq} |
{
while read file_name
do
        # топем в диру для обновлений
        cd ${home_dir}/${http_root_dir}
        # качаем обновление
        ${fetch} "http://${clamav_mirror}/${file_name}"
done
}

# очищаем лог апача
echo -n > ${home_dir}/${http_err_log}

   Через сутки до меня допёрло - файлы daily.cvd и main.cvd при такой схеме обновляться не будут - у них имена останутся те же самые, а значит на них не будет ругани в логах, и новые версии скачиваться не будут. Удалять планировщиком и качать заново - не метод. К этому моменту, благодаря ковырянию логов и вербозного вывода freshclam я знал - он, в первую очередь, работает через DNS - просит TXT запись определёного домена, парсит её, и достаёт оттуда версии файлов. После пары часов мучений было рождено такое:
#!/bin/sh

# даннынй скрипт достаёт версии файлов из TXT записи
# домена 'current.cvd.clamav.net', скачивает их, а также,
# проверяет обновление файлов daily.cvd и main.cvd,
# также, скачивая их в случае необходимости.

# переменные
home_dir="/shares/sites/clamav_mirror"
http_root_dir="data"
clamav_mirror="database.clamav.net"
clamav_version_server="current.cvd.clamav.net"

# приложения
cat="/bin/cat"
grep="/usr/bin/grep"
awk="/usr/bin/awk"
sort="/usr/bin/sort"
uniq="/usr/bin/uniq"
fetch="/usr/bin/fetch"
host="/usr/bin/host"
tr="/usr/bin/tr"

# Новую версию кламав получает из DNS.
# выглядит это так:
# host -t txt current.cvd.clamav.net
# current.cvd.clamav.net descriptive text "0.91.2:44:4474:1191572941:1"
# значения полей, в общем-то понятны, но не все (мало что понял
# из исходников), те что понял - вот:
# 0.91.2 - текущая версия ClamAV
# 44 - версия main.cvd
# 4474 - версия daily.cvd
# 1191572941 - штамп веремни чтоли
# 1 -
# соответственно - парсим и достаём её - частота работы скрипта выше чем
# частота срабатываний freshclam - следовательно файл будет скачан
# заранее, и удасться избежать части 404 ошибок
# да и вообще - решение более красивое :)

# достаём TXT запись
txt_records="`${host} -t txt ${clamav_version_server} | \
                        ${tr} -d '"' | ${awk} '{print $4}'`"

# разбираем на известные поля
main_cvd_ver="`echo ${txt_records} | ${awk} -F ':' '{print $2}'`"
daily_cvd_ver="`echo ${txt_records} | ${awk} -F ':' '{print $3}'`"

# проверяем наличие соответтсвующих файлов
if ! test -f ${home_dir}/${http_root_dir}/daily-${daily_cvd_ver}.cdiff
then
        # качаем файл
        cd ${home_dir}/${http_root_dir}
        ${fetch} "http://${clamav_mirror}/daily-${daily_cvd_ver}.cdiff"
fi

if ! test -f ${home_dir}/${http_root_dir}/main-${main_cvd_ver}.cdiff
then
        cd ${home_dir}/${http_root_dir}
        ${fetch} "http://${clamav_mirror}/main-${main_cvd_ver}.cdiff"
fi

# Зеркалируем прочие файлы, что удалось вычислить (флаг -m у fetch)
cd ${home_dir}/${http_root_dir}
# daily.cvd
${fetch} -m "http://${clamav_mirror}/daily.cvd"
# main.cvd
${fetch} -m "http://${clamav_mirror}/main.cvd"

# ставим права
${chmod} -R 644 ${home_dir}/${http_root_dir}/*

   Ну и всё. В крон его, раз в 10 минут, и маразм разрабочиков удалось обойти :)



размещено: 2007-10-05,
последнее обновление: 2009-08-25,
автор: lissyara


Никита, 2007-10-05 в 17:01:13

Делается одной строчкой фаервола или какого-то там rinetd :) Благо трафика мизер

DmA, 2007-10-05 в 17:18:14

ну как бы прога(freshclam) опенсурсе и посмотреть ,что она делает в исходниках - сам бог велел

lissyara, 2007-10-05 в 17:27:35

>Делается одной строчкой фаервола или какого-то там rinetd :) Благо трафика мизер
Что делается? Для машин глубоко внутри локалки и не имеющих роута наружу?
Есть разные ситуации - и плохо что их непонимают многие люди, в т.ч. и разработчики ClamAV

lissyara, 2007-10-05 в 18:52:52

от блин....
ты его хоть читал, радной?
Или статью, хотя бы, если с аглицким плохо?
Или, накрайняк, первый абзац статьи?

Sultan, 2007-10-05 в 19:21:25

Приношу глубочайшие извинения. С вниманием туго... Без выходных работал...

PavelR, 2007-10-06 в 7:55:36

Я у себя использую для "этого дела" скрипт на perl. Скачать можно на

http://nikolas.ru/nginx/update.pl

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

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

cvd-шки качаются freshclam, сам скрипт вызывается также через freshclam опцией

Checks 48
OnUpdateExecute /var/db/clamav/update.pl

dynax60, 2007-10-09 в 11:36:22

Лисяра, не обязательно описывать путь к каждой команде, достаточно описать PATH (это безопасно):
PATH=/bin:/usr/bin

(8 строчек экономим) :-)

Денис, 2007-10-16 в 17:22:27

Извините за мою глупость, но почему нельзя натравить rsync на официальный ftp сервер ?

lissyara, 2007-10-16 в 18:05:44

Адресок не подскажете?

VX, 2007-10-21 в 21:57:59

Файлики вида daily-4545.cdiff будут накапливаться....

Smile, 2009-01-13 в 12:15:12

Товарищи! Кто нибудь создавал зеркало для DRWEB...

BMf, 2009-06-17 в 6:56:43

статья понравилась... скрип чуть чуть переделал под ubuntu... что файлы будут накапливаться это не проблема)))... зато вопрос в другом скрипт качает самые последние версии файлов daily-****.cdiff и чтобы ни одного не пропустить для этого забивается в cron такая частая проверка на их наличие на сервере((... может как то подправить скриптик чтоб он работал к примеру один раз в день сверяясь с со своими логами и добавлял несколько файлов которые добавились за день???...

Silnt, 2011-03-16 в 12:19:45

"0.97:53:12843:1300265648:1:60:27986:142"
из freshclam.log
0.97 - версия clamav
53 - версия main.cld
12843 - версия daily.cld
1300265648 - дата обновления
1 - ???
60 - нужный f-level
27986 - ???
142 - версия bytecode.cld

Silnt, 2011-03-16 в 13:06:28

Ну и http://wiki.clamav.net/Main/CvdPrivateMirror

А статья пригодилась... :)

Дым, 2011-08-02 в 12:35:35

Осмелюсь привести собственный модифицированный, дополненный и в некоторой степени самодокументированный скриптец /etc/cron.hourly/clamav (работает под фрёй, дебианом и альтом):

##############################################
#!/bin/bash # (для фряхи - симлинк на /usr/local/bin/bash)
## Директива freshclam'у, откуда брать обновки
## (в своём ДНС пропишите CNAME'ы для clamav.<your.domains>):
# DatabaseMirror clamav.<internal>.<dom>

## Пример апачевого конфига для каталога, куда их класть
## (переменную ${Target} см. ниже; здесь же - заменить на реальный путь):
#<VirtualHost *>
#       ServerAdmin admin@<external>.<dom>
#       ServerName clamav.<internal>.<dom>
#       ServerAlias clamav.<external>.<dom>
#       DocumentRoot "${Target}"
#       ErrorLog /var/log/apache2/clamav/error.log
#       TransferLog /var/log/apache2/clamav/access.log
#       <Directory ${Target}/>
#               AllowOverride Options FileInfo
#       </Directory>
#</VirtualHost>

Target="/var/www/clamav" # Куда складывать обновки - меняйте под себя.
Source="current.cvd.clamav.net"
Mirror="http://database.clamav.net"
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

for tool in host wget awk tr; do # Проверим, есть ли чем работать.
       which $tool &>/dev/null || {
               echo "'$tool' not found. Install it first."
               exit 1
       }
done

## Распилим TXT-запись домена по нужным полям и по частоте обновки:
v=(`host -t txt ${Source} | tr -d \" | awk -F":" '{print $3,$8,$2'}`)
## Результат примерно таков: "0.97.1:53:13330:1311053341:1:60:30914:144"
## Не все поля известны, но и любопытны не все:
## 1)   0.97.1          - версия самого ClamAV
## 2)   53                      - версия main.cvd
## 3)   13330           - версия daily.cvd
## 4)   1311053341      - штамп времени
## 5)   1               - X3
## 6)   60              - нужный f-level
## 7)   30914           - X3
## 8)   144                     - версия bytecode.cvd

i=0
for f in daily bytecode main; do # Скачаем свежие версии, если есть.
       echo -n "$f-${v[$i]} "
       [ -r ${Target}/$f-${v[$i]}.cdiff ] || {
               rm -f ${Target}/$f-*.cdiff
               wget -qNP ${Target} ${Mirror}/$f-${v[$i]}.cdiff
               wget -qNP ${Target} ${Mirror}/$f.cvd
       }
       let i++
done && echo

## Если запускать скрипт чаще freshclam'a (например, через cron.hourly),
## новые файлы сольются заблаговременно, благодаря чему избежим Error 404.
#####################################3

Дым, 2011-08-02 в 12:42:41

Для ДрВеба скрипта нет, но есть для Нод32 - также работает под любыми из испробованных *никсов.
Правда, поскольку он собирает обновки "не вполне легально", здесь его привести не могу.

Дым, 2011-08-02 в 12:49:31

Забыл упомянуть. Ежечасные скрипты во фре вызываются из /etc/periodic/hourly/ после соответствующей правки /etc/crontab - типа такой:

# Perform hourly/daily/weekly/monthly maintenance.
1 * * * * root periodic hourly

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



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.164 секунд
Из них PHP: 55%; SQL: 45%; Число SQL-запросов: 77 шт.
Исходный размер: 34704; Сжатая: 9476