пишу скрипт для осуществления сабжа на FreeBSD системах | Цитата | - назначение: Применяется для отслеживания изменений конфигурационных файлов администраторами
- требуемое ПО: Базовая система аудита (OpenBSM), Subversion (сервер, клиент), perl-скрипт (ядро системы мониторинга изменений конфигурационных файлов).
- принцип работы perl-скрипта: В реальном времени perl-скрипт перехватывает данные с потока, выводимого псевдо-устройством (/dev/auditpipe) системы аудита, о проводимых операциях записи файлов в системе. На основе получаемых данных и списка, контролируемых файлов, perl-скрипт в реальном времени отслеживает все операции записи контролируемых файлов и отдает команды на их коммитт Subversion-серверу. Для выполнения операции коммитта perl-скрипт подключается к удаленной системе посредством SSH-туннеля, после чего запускает временный процесс Subversion-сервера и отдает ему команду на коммитт измененного файла. Данные о проведенном коммитте заносятся в файл журнала (commit.log) в виде строчки, которая содержит следующие данные: дата и время проведения коммита, адрес хоста пользователя, путь к закоммитченному файлу, имя пользователя, номер ревизии коммитта. В этот файл журнала так же попадают сообщения об ошибках в работе perl-скрипта.
пример файла журнала: ------------------------------------------------------------------------------------------------------------------------------------------ Tue Sep 11 13:44:27 2007 192.168.0.64 john /etc/make.conf Committed revision 151 Tue Sep 11 14:07:41 2007 0.0.0.0 zen /etc/rc.conf Committed revision 152 ------------------------------------------------------------------------------------------------------------------------------------------
- описание алгоритма perl-скрипта: скрипт постоянно следит за потоком данных поступающих с псевдо-устройства (/dev/auditpipe) и перехватывает все данные попадающие в этот поток, затем он отфильтровывает их на наличие удачных операций записи в файлы локальными пользователями. После этого perl-скрипт сверяет пути к измененным файлам, содержащиеся в отфильтрованных данных, со списком путей к контролируемым файлам. Так perl-скрипт узнает какие файлы нужно отправлять на коммитт Subversion-серверу. После чего скрипт проверяет доступность SSH-сервиса, на удаленной системе с репозитариями и используя SSH-туннель запускает, на удаленной машине, временный процесс SVN-сервера для проведения операции коммитта определенного файла.
заметка: perl-скрипт работает на клиент-системах, машина с Subversion-сервисом является сервером и хранит репозитарии с конфигурационными файлами систем клиентов авторизация на SSH-туннеле проходит с использованием ключей |
описание работы системы аудита событий безопасности, а так же его настройки содержится тут http://freebsd.org.ua/doc/ru_RU.KOI8-R/boo...book/audit.htmlдля отключения pipe-буфера в приложении praudit следует пропатчить исходники (приём работает на 6.2-RELEASE и 7.0-CURRENT) | Код | Index: praudit.c =================================================================== RCS file: /usr/src/contrib/openbsm/bin/praudit/praudit.c,v retrieving revision 1.1.1.3 diff -u -r1.1.1.3 praudit.c --- praudit.c 16 Apr 2007 15:36:57 -0000 1.1.1.3 +++ praudit.c 21 Aug 2007 14:26:43 -0000 @@ -107,6 +107,7 @@ free(buf); if (oneline) printf("\n"); + fflush(stdout); } return (0); } |
код скрипта | Код | #!/usr/bin/perl -w
# специально для конвертации путей с симлинками -> в итоге получаются абсолютные пути (тобишь без симлинков) require Cwd;
# задаем переменные $data_host = "localhost";
#включаем режим даемона daemon_mode();
# отключаем буферизацию #use IO::Handle; FH->autoflush(1); $|=1;
open (FID, "praudit -l /dev/auditpipe |") || die;
while ($line = <FID>) { if ($line =~ /- write,0/) { @data_line = split /,/ => $line; # print "$data_line[12] $data_line[21]\n";
# проверка по списку файлов open (FILE_LIST, "filelist.conf"); while (defined ($file_line = <FILE_LIST>)) { chomp ($file_line);
if (Cwd::abs_path($data_line[12]) eq Cwd::abs_path($file_line)) { # сверяем пути к файлам
$data_path = $data_line[12]; $data_path =~ s/\/[A-Z.a-z]+$//;
if(check_ssh()) { #@commit_out = readpipe("svn commit --force-log --file /dev/null $file_line"); @commit_out = readpipe("cd $data_path && svn commit -m 'committer $data_line[21]'"); # коммиттим изменения
$temp_data = scalar(@commit_out); # проверка выполнения коммита if ($temp_data != 0) { chomp ($commit_out[2]); $commit_out[2] =~ tr/./ /;
# пишем данные в файл open (FILE_LOG,">> commit.log"); select (FILE_LOG); print "$data_line[5] $data_line[29] $data_line[21] $data_line[12] $commit_out[2] done \n"; close (FILE_LOG); }
} else { # пишем данные в файл open (FILE_LOG,">> commit.log"); select (FILE_LOG); print "ssh: connect to host port 22\: Operation timed out \n"; close (FILE_LOG); } } }
close (FILE_LIST) || die;
} }
close (FID) || die;
sub daemon_mode { use POSIX;
#включаем режим даемона if (fork()) { exit; }
# пишем pid процесса open(PID,">audit_pipe.pid")|| die "Can not create pid file\n"; print PID getpid(); #. "\n"; close(PID);
# отключаем основные дискрипторы close(STDIN); close(STDOUT); close(STDERR);
}
sub check_ssh { my $data_host = $data_host;
use Socket; use Fcntl; use Errno; use strict;
my $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "socket: $!"; my $sin = sockaddr_in(22, inet_aton($data_host));
# переводим сокет в non-block mode fcntl(SOCK, F_SETFL, O_NONBLOCK) or die "fcntl: $!";
unless (connect(SOCK, $sin)) { Errno::EINPROGRESS == $! or Errno::EWOULDBLOCK or die "connect: $!";
vec(my $win = '', fileno(SOCK), 1) = 1;
# таймаут соединения unless (select(undef, $win, undef, 2)) { close (SOCK); # die "Time is out!\n"; return 0; }
if (defined (my $ret = getsockopt(SOCK, SOL_SOCKET, SO_ERROR))) { return 0 if $! = unpack('i', $ret); } elsif (!getpeername(SOCK)) { return 0; } }
fcntl(SOCK, F_SETFL, 0); }
|
буду рад здоровой критике, замечаниям, советам, дополнениям ... за perl-скрипт просьба не особо не ругать, это вообще мой первый самописный ... правда подпрограмма проверки доступности порта на удаленной машине спёрта с сайта http://www.opennet.ruвообще хотелось бы поставить все возможные блокировки и отточить их работу в общем, очень нуждаюсь в советах от профессиональных Perl-программистов Это сообщение отредактировал(а) weec - 13.9.2007, 10:26
|