LINUX.ORG.RU

мониторинг изменений конфигурационных файлов системы


0

0

пишу скрипт для осуществления сабжа на FreeBSD системах[quote]
- назначение: Применяется для отслеживания изменений конфигурационных файлов администраторами

- требуемое ПО: Базовая система аудита (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-туннеле проходит с использованием ключей[/quote]

описание работы системы аудита событий безопасности, а так же его настройки содержится тут http://freebsd.org.ua/doc/ru_RU.KOI8-R/books/handbook/audit.html

для отключения pipe-буфера в приложении praudit следует пропатчить исходники (приём работает на 6.2-RELEASE и 7.0-CURRENT)[code]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);
}[/code]

код скрипта[code]#!/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);
}
[/code]
буду рад здоровой критике, замечаниям, советам, дополнениям ...

за perl-скрипт просьба особо не ругать, это вообще мой первый самописный ...
правда подпрограмма проверки доступности порта на удаленной машине спёрта с сайта http://www.opennet.ru
вообще хотелось бы поставить все возможные блокировки и отточить их работу


Ответ на: комментарий от Teak

> Фигнёй страдаете, сэр. Импортируем /etc в svn и пользуемся.

для такой задачи лучше rcs. Тем более есть в базовой системе БСД.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.