Страница 1 из 1

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

Добавлено: 2007-08-21 12:32:01
weec
пишу скрипт для осуществления сабжа на системах FreeBSD
заметка: есть возможность реализовать тоже самое на Linux (audit trails / LAuS)
http://people.redhat.com/sgrubb/audit/
- назначение: Применяется для отслеживания изменений (конфигурационных) файлов

- требуемое ПО: OpenBSM, Subversion (либо любая другая SCM), Perl

- принцип работы perl-скрипта: В качестве источника данных для работы Perl-скрипта выступает псевдо-устройство /dev/auditpipe (OpenBSM).
В реальном времени perl-скрипт перехватывает данные с потока, выводимого псевдо-устройством /dev/auditpipe, о проводимых операциях изменения файлов в системе. На основе получаемых данных и списка контролируемых файлов(filelist.conf) perl-скрипт отслеживает все операции изменения контролируемых файлов и отдает команды на внесение изменений в репозиторий Subversion-серверу (коммитт). Данные о проведенном коммитте заносятся в файл журнала (commit.log) в виде строчки, которая содержит следующие данные: дата и время проведения коммита, адрес хоста пользователя, путь к закоммиттченному файлу, имя пользователя, номер ревизии коммитта. В этот файл журнала так же попадают сообщения об ошибках в работе perl-скрипта.

пример данных получаемых с псевдо-устройства /dev/auditpipe:

Код: Выделить всё

header,133,10,execve(2),0,Mon Sep 25 15:58:03 2006, + 384 msec
exec arg,finger,doug
path,/usr/bin/finger
attribute,555,root,wheel,90,24918,104944
subject,robert,root,wheel,root,wheel,38439,38032,42086,128.232.9.100
return,success,0
trailer,133
пример файла журнала (commit.log):

Код: Выделить всё

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-скрипт работает на клиент-системах, машина с Subversion-сервисом является сервером и хранит репозитории с конфигурационными файлами систем клиентов
авторизация на SSH-туннеле проходит с использованием ключей
описание работы OpenBSM (система аудита событий безопасности), а так же руководство по настройке содержится на странице http://freebsd.org.ua/doc/ru_RU.KOI8-R/ ... audit.html

ссылки на сайты проектов используемого ПО:
http://www.trustedbsd.org/openbsm.html
http://subversion.tigris.org
http://www.perl.org

код скрипта

Код: Выделить всё

#!/usr/bin/perl -w

use warnings;
use diagnostics;
use strict;
use POSIX;
use IO::Handle;
use IPC::Open2;
use Cwd qw(abs_path); # convert path with symlink to absolute path
use Fcntl qw(:flock :DEFAULT);

# задаем переменные
#$| = 0;
my $daemon_mode = "on"; # on/off daemon mode
my $lock_set = "on"; # on/off lock repeat_start
my $workpath_set = "/usr/local/libexec/audit_pipe";
my $filelist_set = "filelist.conf";
my $commit_log_set = "/usr/local/libexec/audit_pipe/commit.log";
my $pidfile_set = "/usr/local/libexec/audit_pipe/audit_pipe.pid";
my $cfg_glob_lock;
my $zombie_lock_flag;
my $lock_pid;
my $pid;

my $number = 0;
my $date_set;
my $ipaddres_set;
my $username_set;
my $path_set;
my $pipe_log;
my $file_line;
my $dir_set;
my $temp_data;
my $line = "";
my $line_buf;
#my $line2 = "";
my @data_line;
my @commit_out;
my $tmp_volume = 0;

#включаем режим даемона
#daemon_mode();

# отключаем буферизацию
#use IO::Handle; $pipe_read->autoflush(1);
#$|=1;
if ($lock_set eq "on") {

    # ПРОЦЕДУРА предотвращения повторного запуска скрипта
    $cfg_glob_lock = $pidfile_set;

    # Проверяем lock.
    if (-f $cfg_glob_lock){
        # Lock присутствует. Проверяем не дохлый ли процесс.
        my $lock_pid = 0;
        open(LOCK,"<$cfg_glob_lock");
        # Если удалось заблокировать, значит процесс мертв.
        my $zombie_lock_flag = flock(LOCK,  LOCK_EX|LOCK_NB);
        $lock_pid = <LOCK>;
        close (LOCK);
        chomp ($lock_pid);

        if ($lock_pid > 0 && $zombie_lock_flag == 0){
            # Реакция на зависший процесс.
            die "Proccess locked (pid=$lock_pid)";
        } else {
            # Лок от мертвого процесса.
            unlink("$cfg_glob_lock");
            warn("DeadLock detected ($lock_pid)$!\n");
        }
    }
}

if ($daemon_mode eq "on") {
    #включаем режим даемона
    daemon_mode();
}

if ($lock_set eq "on") {
    # Записываем pid в новый lock-файл.
    sysopen(PID, $cfg_glob_lock, O_CREAT|O_EXCL|O_WRONLY) or die "Can not create pid file: $!\n";
        print PID "$$\n";
    close(PID);

    # Открываем lock.
    open(GLOB_LOCK,"<$cfg_glob_lock");
        flock(GLOB_LOCK,  LOCK_EX);

} else {
    open(PID,"> $pidfile_set") || die  "Can not create pid file: $!\n";
        print PID getpid();
    close(PID);
}

# BASIC PART OF CODE
open(PIPE_LOG, "/dev/auditpipe") || die;

    $pid = open2( my $pipe_read, my $pipe_write, "praudit", "-lp");

    while (1) {
        sysread PIPE_LOG, $pipe_log, 65536;
        $number++; # cycle_counter

        print $pipe_write "$pipe_log"; # && close ($pipe_write) or die "Error writing to pipe_write: $!\n";

        #if ( $pipe_log =~ /\// || $pipe_log =~ /flags/ ) {

        sysread $pipe_read, $line_buf, 65536;

#print "stage1 ".$number."\n $line_buf \n";
        my @data_string = split /\n/ => $line_buf;
        my $quantity_strings = scalar(@data_string);

        foreach $line (@data_string) {
            if (($line =~ /- write,creat,0/) || ($line =~ /- write,creat,trunc,0/)) {
                @data_line = split /,/ => $line; # распределяем строку $line в массив


                if ($line =~ /- write,creat,0/) {
                    $date_set = $data_line[6];
                    $ipaddres_set = $data_line[34];
                    $username_set = $data_line[26];
                    $path_set = $data_line[17];
                } else {
                    $date_set = $data_line[7];
                    $ipaddres_set = $data_line[35];
                    $username_set = $data_line[27];
                    $path_set = $data_line[18];
                }

                # проверка по списку файлов
                open (FILE_LIST, "$workpath_set/$filelist_set");
                        while (defined ($file_line = <FILE_LIST>)) {
                            chomp ($file_line);
                            if (Cwd::abs_path($path_set) eq Cwd::abs_path($file_line)) { # сверяем пути к файлам
                                $dir_set = $path_set;
                                $dir_set =~ s/\/[A-Z.a-z]+$//;

                                #@commit_out = readpipe("svn commit --force-log --file /dev/null $file_line");

                                # коммиттим изменения
                                unless (@commit_out = readpipe("cd $dir_set && svn commit -m 'committer $username_set'")) {
                                    open (FILE_LOG,">> $commit_log_set") || die "cannot append: $!";
                                        #select (FILE_LOG);
                                        print FILE_LOG "$date_set not committed: $! \n";
                                    close (FILE_LOG);
                                }

                                $temp_data = scalar(@commit_out); # проверка выполнения коммита

                                if ($temp_data != 0) {
                                    chomp ($commit_out[2]);
                                    $commit_out[2] =~ tr/./ /;

                                    # пишем данные в файл
                                    open (FILE_LOG,">> $commit_log_set") || die "cannot append: $!";
                                    #select (FILE_LOG);
                                        print FILE_LOG "$date_set $ipaddres_set $username_set $path_set $commit_out[2] done \n";
                                    close (FILE_LOG);
                                }
                            }
                        }

                close (FILE_LIST) || die "$!";

            }
        }
    }

# close (FID) || die "$!";

close ($pipe_write);
close ($pipe_read);
#close WRITE_PIPE;
#close READ_PIPE;
waitpid($pid, 0);
close(PIPE_LOG);

if ($lock_set eq "on") {
    # кусок кода процедуры предотвращающей повторный запуск скрипта
    # Закрываем и удаляем lock
    flock(GLOB_LOCK, LOCK_UN);
    close(GLOB_LOCK);
    unlink("$cfg_glob_lock");
}

sub daemon_mode {

    #включаем режим даемона
    if (fork()) {
        exit;
    }

    # пишем pid процесса
#    open(PID,"> $pidfile_set")|| die  "Can not create pid file: $!\n";
#    print PID getpid(); #. "\n";
#    close(PID);

    # отключаем основные дискрипторы
#    close(STDIN);
#    close(STDOUT);
     close(STDERR);
}
- на контролируемой машине добавляем пользователя svn и генерируем открытый и закрытый ключи
добавляем имена контролируемых пользователей в конфигурационный файл /etc/security/audit_user (OpenBSM)

Код: Выделить всё

# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_user#3 $
# $FreeBSD: src/contrib/openbsm/etc/audit_user,v 1.2.2.1 2006/09/02 10:46:00 rwatson Exp $
#
#root:lo:no
# выводить только удачные попытки изменения файлов
john:+fw:no
zen:+fw:no
- на машине с SVN-сервером добавляем пользователя svn и добавляем, сгенерированный ранее, открытый ключ в файл /usr/home/svn/.ssh/authorized_keys

Код: Выделить всё

command="/usr/local/bin/svnserve -t -r /путь/до/svn-репозитория" тип_ключа код_открытого_ключа
так же требуется разрешить SHH-авторизацию по ключам

после создайте репозиторий на SVN-сервере, поместите в репозиторий конфигурационные файлы (с контролируемой системы) и создайте рабочую копию на стороне контролируемой машины
рабочая копия содержит файл (.svn/entries) с адресом SVN-сервера, а так же тип подключения

Код: Выделить всё

svn+ssh://127.0.0.1/etc
в принципе все ...

буду рад здоровой критике, замечаниям, советам, дополнениям ...

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

Добавлено: 2007-09-12 13:13:22
weec
дабы не создавать новый топик, поправил старый
в итоге выложил результат своей работы с момента появления проблемы с pipe-буфером в приложении praudit

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

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

Добавлено: 2007-10-24 14:56:19
weec
Synopsis: [openbsm] [patch] please add pipe-buffer switcher (On\Off) in /usr/sbin/praudit

State-Changed-From-To: open->patched
State-Changed-By: rwatson
State-Changed-When: Sun Oct 21 00:36:13 UTC 2007
State-Changed-Why:
This change has been applied to the OpenBSM tree in Perforce, and will
appear in OpenBSM 1.0. I plan to merge OpenBSM 1.0 into 8.x/7.x in the
next week, and MFC to 6.x once it has settled for some time. With any
luck, this change will appear in both FreeBSD 6.3 and FreeBSD 7.0.

Thanks for the report!

http://www.freebsd.org/cgi/query-pr.cgi?pr=115715

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

Добавлено: 2007-10-24 15:00:12
Alex Keda
поюзать чтоли...
=========
параноидальная штуковина...

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

Добавлено: 2007-10-24 17:11:04
kmb
по-моему rkhunter это тоже делает, хотя может и ошибаюсь...

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

Добавлено: 2007-10-24 17:22:41
weec
предназначение другое

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

Добавлено: 2007-11-21 11:24:32
weec
http://www.freebsd.org/cgi/cvsweb.cgi/s ... _6#dirlist
Merge OpenBSM 1.0 from HEAD to RELENG_6
хорошая новость )

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

Добавлено: 2007-11-21 11:39:13
kmb
пожалуй попробую, в сложившийся обстановке, очень пригодиться =)
Правда не совсем понял как оно работает.
Вот тут:

Код: Выделить всё

# задаем переменные
$data_host = "localhost";
тут указываем адрес машины на какой будет производиться:
После чего скрипт проверяет доступность SSH-сервиса, на удаленной системе с репозитариями и используя SSH-туннель запускает, на удаленной машине, временный процесс SVN-сервера для проведения операции коммитта определенного файла.
Что должна знать удаленная машина? Какое ПО туда устанавливать...
И что должно быть на машине где запускается это перл-скрипт?

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

Добавлено: 2008-02-19 17:36:55
weec
из требований по стороннему ПО для FreeBSD: Perl и SVN (на всех машинах)
обновил Perl-скрипт в шапке топика и добавил инструкцию

странно, что никто не интересуется скриптом и связкой OpenBSM + SCM (любая система контроля версий)

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

Добавлено: 2008-03-20 14:23:11
weec
http://www.freebsd.org/projects/ideas/#p-auditjail
идея добавить поддержку Jail в OpenBSM включена в список "Summer of Code 2008 project"
на данный момент OpenBSM регистрирует изменения происходящие в jail, но не выводит в журнал информацию о самом Jail

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

Добавлено: 2014-05-08 12:23:16
weec
знакомые ребята заинтересовались моей реализацией и на её основе написали свою, тоже на perl, но еще прикрутили mysql
реализована поддержка jail-ов

исходники и документация
https://bitbucket.org/weec/transparency ... /downloads