Создание зоны обновлений на UNIX сервере для Windows машин

Материал из wiki.drweb.com
Перейти к: навигация, поиск


В статье рассмотрен способ создания зоны обновления антивируса Dr.Web на Linux для обновления windows-машин в локальной сети.

Введение

Антивирус Dr.Web обновляется при помощи программы DrWebUpW.exe, которая находится в каталоге %programfiles%\DrWeb. При запуске DrWebUpW читает последовательно файлы custom.drl и update.drl, лежащие с ним в одной папке. В этих файлах прописаны зоны обновления Dr.Web. Затем программа обновления скачивает с первой доступной зоны файл drweb32.lst, в котором хранятся хэши, расположение и команды установки всех файлов для обновления. Также необходимо знать, что существует ряд серверов, на которых Dr.Web выкладывает в свободном доступе антивирусные базы и движки, например, http://new-download.drweb.com/bases.

Скрипт

Скрипт, написанный на языке Perl, позволяет обновлять базы, движки и компоненты Dr.Web. Для обновления компонентов необходим действующий лицензионный ключевой файл от любого продукта Dr.Web. Также может понадобиться модуль Zlib для Perl

#!/usr/bin/perl -w
use Digest::MD5;
use LWP::UserAgent;
use Compress::Zlib;
use strict;
my $basedir  = '/tmp/update/500'; # папка, откуда обновляются виндовые агенты
my $drwebkey = '/home/axel/drweb32-betatesting.key'; # путь к ключу drweb
my $tmpdir   = '/tmp'; # директория для временных файлов 
my $url      = 'http://update.drweb.com/500/sspace/windows'; # одна из зон обновления Dr.Web
 

# get MD5 hash of key-file
open(FILE, $drwebkey) or die "Can't open '$drwebkey': $!";
binmode(FILE);
my $md5 =  Digest::MD5->new->addfile(*FILE)->hexdigest;
print "MD5 of key-file $drwebkey = $md5\n";
# get Key Number of User 
my $userkeynumber = parsekey();
print "Key Number of User $drwebkey = $userkeynumber\n";

# download drweb32.lst
download("$url/drweb32.lst",$basedir.'/drweb32.lst'); 

# parse drweb32.lst and download
open LST, '<'."$basedir/drweb32.lst" or die "can't open $basedir/drweb32.lst ($!)\n";
    	 while (<LST>) {
            s/\r?\n$//; # remove \r\n, \n
            /^\[[\w ]+\]$/ and next;
            /^[-]/ and next; #skip delete;
            my ( $filename, undef,$crc) = /^[\+\=\@\!].*?([_a-zA-Z0-9\.\-]+)?[, \s](\|.+)?[, \t]+([a-fA-F\d]+)?[, \t]*(\d+\.\d+)?/o
               or print STDERR "unknown line \"$_\" in lst\n";
            if (checkcrc32("$basedir/$filename",$crc) eq 0){
            print "download $url/$filename, $crc\n"; #what try to download
            my $ret unless download("$url/$filename","$basedir/$filename",$crc);
            }
            else  {
                print "skip $url/$filename, $crc CRC match\n"
            }
          }
close LST;

sub checkcrc32 {
    my ($file,$crc)=@_;
    my $crcf=0;
    open FHC, '<'.$file or return 0;
    $crcf=crc32($_,$crcf) while <FHC>;
    return 0 if hex($crc) != $crcf;
    close FHC;
    return 1;
}
sub download {
    my ($url,$file,$crc)=@_;
    my $ua = LWP::UserAgent->new;
    $ua->agent("DrWebUpdate-5.00.6.06011 (windows: 6.00.6001)");
    $ua->default_header('X-DrWeb-KeyNumber' => $userkeynumber);
    $ua->default_header('X-DrWeb-Validate' => $md5);     

    my $req = HTTP::Request->new(GET => $url);
    my $res = $ua->request($req);

    if (! $res->is_success) {
        print STDERR $res->status_line, " (file $url)\n";
        return 0;
    }
    if ($crc and hex($crc) != crc32($res->content)) {
        printf STDERR "file $url with frong crc: %X (expects $crc)\n",crc32($res->content);
        return 0;
    }
    if ( ! open FH, '>'.$file) {
        print STDERR "can't open $file ($!)\n";
        return 0;
    }  
    print FH $res->content;
    close FH;
    return 1;
}

sub parsekey {
    my @massivekey;
    my $userkeynumber;
    open KEY, '<'."$drwebkey" or die "can't open $drwebkey ($!)\n";
       while (<KEY>) {
          s/\r?\n$//; # remove \r\n, \n
          push (@massivekey,$_);
    }
    close KEY;
    my $stringkey = join "",@massivekey;
    if ($stringkey =~ /\[User\]Number=(\d+)/i){
    $userkeynumber =  $1;
    };
    return $userkeynumber;
}

Для тех кто за прокси: в блок sub download { требуется дописать прокси явным образом (из переменных оно не отдается) $ua->proxy(['http'], 'http://address:port');

Crontab

Теперь добавим задание в crontab, выполнив команду crontab -e:

# drweb update
0 */1 * * * /home/user/drwebupw.pl

также для мониторинга крона во время тестовых запусков полезно сделать

[min] [hour] * * * /home/user/drwebupw.pl > /home/user/drwebupw.log 2>&1

и там смотреть вывод работы скрипта

Обновление windows-машин

DrWebUpW.exe /URL <UNC путь к папке $basedir>

Ссылки