Рассмотрим пример реализации защиты сетевого периметра с использованием Opensource-решений на базе:
— Snort — система обнаружения\предотвращения вторжения (в контексте данной статьи будет рассматриваться как IDS);
— OSSEC — хостовая IDS (Host-based intrusion detection system);
— Prelude\Prewikka — SIEM-система для обработки и управления событиями (Security information and event management).
В предыдущих статьях, посвященных обеспечению безопасности веб-сайта и сетевого периметра были рассмотрены инструменты nginx-naxsi (web application firewall), fail2ban (сервис блокировки доступа) и snort (IDS). Давайте попробуем соединить все подсистемы воедино, снарядив в довесок SIEM, позволяющей просматривать и анализировать события в удобном виде. Кроме этого, использование подобной системы позволит подготовиться к соответствию со стандартом PCI DSS.
Далее в примерах будут использоваться 3 сервера:
Сервер R — сетевой шлюз;
Сервер WAF — веб-сервер с установленным Nginx-Naxsi и Fail2ban;
Сервер SIEM — сервер просмотра и обработки событий.
Итак, приступим!
Установка и настройка Snort
Сервер R
В репозиториях Debian есть уже готовые сборки Snort и Snort-mysql, простые в установке и уже содержащие стандартный набор правил. Минус заключается в том, что правил довольно мало. Расширенный набор правил можно скачать с официального сайта (рекомендуется использовать правила, предоставляемые по платной подписке, содержащие наиболее актуальные сигнатуры атак). Устаревшие версии Snort, находящиеся в репозитории Debian, нам не подойдут, поэтому произведем установку из исходников:
# mkdir -p /opt/src
# cd /opt/src
Установим зависимости. Библиотеку libdnet, необходимую для работы Snort, придется также установить из исходников.
# apt-get install libdaq-dev libpcap-dev libssl-dev libpcre3-dev checkinstall
# wget http://sourceforge.net/projects/libdnet/files/libdnet/libdnet-1.11/libdnet-1.11.tar.gz/download -qO- | tar xvzpf - -C /opt/src
# cd libdnet-1.11 && ./configure && make && checkinstall
Установим Snort:
# wget https://www.snort.org/downloads/snort/snort-2.9.7.3.tar.gz -qO- | tar xvzpf - -C /opt/src
# cd /opt/src/snort-2.9.7.3 && ./configure --enable-sourcefire
# make && checkinstall
Отлично. Теперь необходимо скачать и подключить расширенный набор правил с сайта, предварительно зарегистрировавшись на Snort.org и получив oinkode:
# mkdir -p /etc/snort
# wget https://www.snort.org/rules/snortrules-snapshot-2962.tar.gz?oinkcode=038c3ee32c10a975b466522d823d9e9fa3ffbd2f -qO- | tar xvzpf - -C /etc/snort
# mv /etc/snort/etc/* /etc/snort/ && rm -rf /etc/snort/etc
# cat /etc/passwd | grep snort || useradd snort
# mkdir /var/log/snort && chown -hR snort /var/log/snort
Готово. Переходим к настройке. Укажем диапазон нашей внутренней подсети, пути доступа к правилам и т.д.:
# nano /usr/local/snort/etc/snort.conf
# Setup the network addresses you are protecting ipvar HOME_NET 192.168.0.0/16 var RULE_PATH ./rules var SO_RULE_PATH ./so_rules var PREPROC_RULE_PATH ./preproc_rules var WHITE_LIST_PATH ./rules var BLACK_LIST_PATH ./rules # path to dynamic preprocessor libraries dynamicpreprocessor directory /usr/local/lib/snort_dynamicpreprocessor # path to base preprocessor engine dynamicengine /usr/local/lib/snort_dynamicengine/libsf_engine.so # path to dynamic rules libraries dynamicdetection directory /etc/snort/so_rules
Подготовим все необходимо для запуска Snort:
# touch /etc/snort/rules/white_list.rules
# touch /etc/snort/rules/black_list.rules
# chown snort:snort /etc/snort/rules/*.rules
# mkdir -p /var/log/snort
# chown snort:snort /var/log/snort
Проверим конфигурацию:
# snort -T -c /etc/snort/snort.conf
В случае появления ошибки:
snort: error while loading shared libraries: libdnet.1: cannot open shared object file: No such file or directory
сделаем симлинк библиотеки:
# cd /usr/lib/ && ln -s /usr/local/lib/libdnet.1.0.1 libdnet.1
Запускаем Snort:
# snort -c /etc/snort/snort.conf -D -i eth1 -u snort -g snort
Не забудем написать скрипт автозапуска и активизировать его. На этом установка и первичная настройка Snort завершена. Продолжаем.
Установка и настройка SIEM
Сервер SIEM
Произведем настройку Prelude SIEM:
# apt-get install apache2 libmysqlclient-dev make gcc libssl-dev
# apt-get install prelude-manager libprelude-dev
Произведем настройку автозапуска при старте системы:
# nano /etc/default/prelude-manager
RUN=yes
# update-rc.d prelude-manager defaults
И установим Prewikka — веб-интерфейс для удобства просмотра и анализа событий:
# apt-get install prewikka
Теперь нам необходимо настроить vhost на веб-сервере:
# cd /etc/apache2/sites-enabled/
# mv 000-default prewikka
<VirtualHost *:80> ServerName siem.example.com Setenv PREWIKKA_CONFIG "/etc/prewikka/prewikka.conf" <Location "/"> Options ExecCGI <IfModule mod_mime.c> AddHandler cgi-script .cgi </IfModule> Order allow,deny Allow from all </Location> Alias /prewikka/ /usr/share/prewikka/htdocs/ ScriptAlias / /usr/share/prewikka/cgi-bin/prewikka.cgi </VirtualHost>
а также установить права доступа для www-data:
# chown -hR www-data:www-data /etc/prewikka
Перезапускаем веб-сервер:
# /etc/init.d/apache2 restart
По-умолчанию Prewikka производит резолвинг хостов, что не всегда бывает полезным (особенно, если речь идет о секции SRC IP). Чтобы отключить резолв, необходимо выставить параметр -1 в секции dns_max_delay в файле /etc/prewikka/prewikka.conf.
Проверяем работу веб-интерфейса, открыв в браузере http://web_server_ip. Логин\пароль: admin\admin.
Установка и настройка OSSEC HIDS
Сервер SIEM
OSSEC HIDS является хостовой системой обнаружения вторжений, позволяя выявлять и пресекать подозрительную активность на хосте. Скачаем последнюю версию с официального сайта и произведем установку:
# apt-get install make gcc libssl-dev -y
# wget http://www.ossec.net/files/ossec-hids-2.8.2.tar.gz --user-agent=Mozilla -qO- | tar xvzpf - /tmp
# cd /tmp/ossec-hids-2.8.2/src && make setprelude && ../install.sh
Ответим на вопросы. Рекомендуется отключить active-response, позже, при необходимости, мы всегда сможем его активировать:
1- What kind of installation do you want (server, agent, local, hybrid or help)? server - Server installation chosen. 2- Setting up the installation environment. - Choose where to install the OSSEC HIDS [/var/ossec]: - Installation will be made at /var/ossec . 3- Configuring the OSSEC HIDS. 3.1- Do you want e-mail notification? (y/n) [y]: n --- Email notification disabled. 3.2- Do you want to run the integrity check daemon? (y/n) [y]: - Running syscheck (integrity check daemon). 3.3- Do you want to run the rootkit detection engine? (y/n) [y]: - Running rootcheck (rootkit detection). 3.4- Active response allows you to execute a specific command based on the events received. For example, you can block an IP address or disable access for a specific user. More information at: http://www.ossec.net/en/manual.html#active-response - Do you want to enable active response? (y/n) [y]: n - Active response disabled. 3.5- Do you want to enable remote syslog (port 514 udp)? (y/n) [y]: n
Интегрируем OSSEC с Prelude:
# nano /var/ossec/etc/ossec.conf
<global> <prelude_output>yes</prelude_output> <email_notification>no</email_notification> </global>
Теперь нужно подключить OSSEC к Prelude. Для этого нам потребуется одновременный доступ к двум консолям. Это можно сделать утилитой screen (запустите screen, CTRL+A CTRL+C создасть новое окно, переключение между окнами осуществляется комбинацией CTRL+A).
Запустим в первой консоли:
# prelude-admin registration-server prelude-manager
а во второй:
# prelude-admin register OSSEC "idmef:w" 127.0.0.1 --uid ossec --gid ossec
Введя одноразовый пароль, получим сообщение об успешной интеграции OSSEC:
Registration request for analyzerID="ХХХХХХХХХХХХХХХХХ" permission="idmef:w". Approve registration? [y/n]: y 127.0.0.1:56460 successfully registered.
Запустим сервисы:
# /etc/init.d/prelude-manager start
# /etc/init.d/ossec start
Добавление OSSEC-агентов
Существует, как минимум, два способа добавить агента OSSEC — сгенеровать ключ авторизации на сервере или же активировать агента удаленно. Рассмотрим оба варианта.
Вариант 1. Генерация ключа на сервере
На сервере SIEM выполним:
# /var/ossec/bin/manage_agents
- Adding a new agent (use '\q' to return to the main menu). Please provide the following: * A name for the new agent: ИМЯ_АГЕНТА * The IP Address of the new agent: ИП_АГЕНТА * An ID for the new agent[001]:
Если процедура производится в первый раз, необходимо перезапустить OSSEC-сервер, чтобы он начал слушать UDP-port 1514:
# /etc/init.d/ossec restart
Извлечем сгенерированный ключ для клиента с помощью опции «E»:
# /var/ossec/bin/manage_agents
укажем ID агента (в данном случае 001) и получим ключ:
Agent key information for ‘001’ is:
MDAxIFIzIDEwLjEuNC4xZZZZZZZZZZjU1NGZhNzY3NmI5N2RiYTU4YjMyZDk1MTEzNTcwMTcZZZZZZZZZZZZZZZZZZZZhhZjY=
Сервер R
Установим и настроим OSSEC-агент:
# wget http://www.ossec.net/files/ossec-hids-2.8.2.tar.gz --user-agent=Mozilla -qO- | tar xvzpf - -C /tmp
# /tmp/ossec-hids-2.8.2/install.sh
1- What kind of installation do you want (server, agent, local, hybrid or help)? agent 3.1- What's the IP Address or hostname of the OSSEC HIDS server?:Укажем IP адрес сервера 3.2- Do you want to run the integrity check daemon? (y/n) [y]: - Running syscheck (integrity check daemon). 3.3- Do you want to run the rootkit detection engine? (y/n) [y]: - Running rootcheck (rootkit detection). 3.4 - Do you want to enable active response? (y/n) [y]: n
# /var/ossec/bin/manage_agents
Добавим ключ через опцию «I» и перезапустим OSSEC:
# /etc/init.d/ossec restart
Перейдем на сервер SIEM и убедимся, что агент подключился:
# /var/ossec/bin/agent_control -l
OSSEC HIDS agent_control. List of available agents: ID: 000, Name: siem.pentestit.ru (server), IP: 127.0.0.1, Active/Local ID: 001, Name: R3, IP: 10.1.4.1, Active
Вариант 2. Удаленное подключение агента
Установим на сервере R OSSEC-агент, как это было описано в первом варианте. На сервере SIEM запустим сервис аутентификации агентов с опцией -i (опция при регистрации агента сохраняет его IP-адрес, не допуская подключения с других IP адресов для данного агента):
/var/ossec/bin/ossec-authd -i
Вернемся на сервер R и запустим клиент аутентификации с указанием IP-адреса сервера OSSEC:
/var/ossec/bin/agent-auth -m OSSEC_SERVER_IP
Агент должен успешно пройти аутентификацию на сервере. Обратите внимание, что для приема событий OSSEC слушает подключения на 1514 UDP порту, в то время как модуль авторизации на сервере (при аутентификации вторым методом используется порт 1515 TCP.
Настройка профилей OSSEC
Гибкость OSSEC обеспечивается, в том числе, за счет использования профилей — набора правил для хоста или группы хостов, объединенных по определенным критериям, таких как операционная система, роль и т.д. Рассмотрим пример создания профиля для серверов, использующих Snort в качестве IDS. Для этого создадим на OSSEC-сервере файл, описывающий политику мониторинга логов для подобных серверов.
Сервер SIEM
# nano /var/ossec/etc/shared/agent.conf
<agent_config profile="snort"> <localfile> <log_format>snort-fast</log_format> <location>/var/log/snort/alert</location> </localfile> </agent_config>
Мы указали, что для профиля snort необходимо анализировать файл /var/log/snort/alert, имеющий формат snort-fast. Подключим профиль клиенту:
Сервер R
# nano /var/ossec/etc/ossec.conf
<client> <server-ip>10.1.4.11</server-ip> <config-profile>snort</config-profile> </client>
# /etc/init.d/ossec restart
Отлично, теперь события Snort будут поступать на сервер SIEM.
По умолчанию, при установке OSSEC-агента, конфиг ossec.conf уже содержит список файлов для мониторинга. Для OSSEC версии 8.1 доступны различные форматы журналов событий, имеющих интуитивно понятное название. С полным списком форматов можно ознакомиться здесь. Помимо стандартных файлов журналов Linux-систем и приложений, доступны такие форматы, как:
snort-full, snort-fast — формат журнала Snort;
eventlog — стандартный формат журнала Windows;
eventchannel — формат журнала Windows, позволяющий обрабатывать не только классические Windows-логи, но и данные из Application and Services (для Windows Vista и старше);
command, full_command — выполнение команды в системе. Выполняется только при указании в ossec.conf на каждом агенте, нельзя передать через agent.conf;
multi-line — позволяет работать с журналами приложений, использующие несколько строг для генерации событий.
Кроме этого, по умолчанию ossec.conf содержит секции по анализу контроля целостности файлов.
События, поступающие от OSSEC-агентов на сервер, сначала проходят обработку пре-декодером, декодером, а после к ним применяется набор правил. Правила расположены в каталоге /var/ossec/rules и должны быть подключены в конфигурационном файле ossec.conf. Все конфигурационные файлы OSSEC имеют формат XML. На этапе пре-декодинга извлекается такая информация, как имя хоста, приложения, сгенерировавшего событие, источник события и т.д.
Декодер событий
Обработка события декодером (/var/ossec/etc/decoder.xml) производится на основе паттернов. Давайте попробуем создать декодер для событий fail2ban.
Оригинальное событие имеет следующий вид:
2015-06-19 00:39:35,920 fail2ban.actions: WARNING [some_waf_rule] Ban 94.XX.8.XX
Чтобы убедиться, что декодера для данного события не существует, обработаем его утилитой ossec-logtest:
# echo '2015-06-19 00:39:35,920 fail2ban.actions: WARNING [some_waf_rule] Ban 94.ХХ.8.ХХ' | /var/ossec/bin/ossec-logtest -a
и получим пустой результат:
2015/06/22 00:18:20 ossec-testrule: INFO: Reading local decoder file. 2015/06/22 00:18:20 ossec-testrule: INFO: Started (pid: 3153).
Опция -a для ossec-logtest выводит только алерт (если паттерн будет найдет в декодере и в правиле), в то время как опция -v/-d предоставит больше информации об обработке.
Создадим декодер, извлекающий из правила Source IP, название правила и действия утилиты fail2ban (Ban\Unban):
# nano /var/ossec/etc/decoder.xml
<decoder name="fail2ban"> <!-- 2015-06-19 01:08:21,688 fail2ban.actions: WARNING [some_waf_rule] Ban 94.ХХ.8.ХХ --> <prematch>^20\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d+ fail2ban.actions: WARNING </prematch> <regex>[(\S+)]\s+(\S+)\s+(\S+)</regex> <order>extra_data, status, srcip</order> </decoder>
и повторим обработку:
# echo '2015-06-19 00:39:35,920 fail2ban.actions: WARNING [some_waf_rule] Ban 94.XX.8.XX' | /var/ossec/bin/ossec-logtest -v
... **Phase 2: Completed decoding. decoder: 'fail2ban' extra_data: 'some_waf_rule' status: 'Ban' srcip: '94.XX.8.XX' ...
Отлично. Перейдем к созданию правил.
Итак, мы уже создали декодер для событий fail2ban, давайте попробуем разобраться с правилами OSSEC.
Каждое правило OSSEC имеет свой уникальный идентификатор, правила сгруппированы по их назначению. Более подробную информацию о правилах и о назначении идентифкаторов можно прочитать здесь. Таким образом мы можем использовать идентификаторы в диапазоне от 100000 до 109999 для собственных правил. Кроме этого, правила содержат уровень критичности (level) от 0 до 15. Значение 0 игнорируются, а 15 означает максимальный уровень критичности.
Давайте попробуем создать правило для событий fail2ban:
# nano /var/ossec/rules/local_rules.xml
<rule id="100003" level="15"> <decoded_as>fail2ban</decoded_as> <match> Ban </match> <description>Fail2ban Ban</description> </rule> <rule id="100004" level="3"> <decoded_as>fail2ban</decoded_as> <match> Unban </match> <description>Fail2ban Unban</description> </rule>
Первое правило будет сообщать о блокировки, поэтому мы назначили ему максимальный уровень критичности (в Prewikka будет отображаться красным), второе (о разблокировки) с уровнем 3 (синий цвет).
Давайте попробуем создать правило для обработки событий Naxsi, который мы рассматривали в статье, посвященной обеспечению безопасности сайта. Событие имеет следующий вид:
2015/06/19 00:14:11 [error] 1569#0: *8948 NAXSI_FMT: ip=94.XX.8.XX&server=XXX.ru&uri=/wp-admin/admin-ajax.php&learning=1&vers=0.54&total_processed=158&total_blocked=30&block=1&cscore0=$XSS&score0=20&zone0=BODY|NAME&id0=1311&var_name0=data[clef]&zone1=BODY|NAME&id1=1311&var_name1=data[wp-refresh-post-lock][post_id]&zone2=BODY|NAME&id2=1311&var_name2=data[wp-refresh-post-lock][lock], client: 94.XX.8.XX, server: XXX.ru, request: "POST /wp-admin/admin-ajax.php HTTP/1.1", host: "XXX.ru", referrer: "https://XXX.ru/wp-admin/post.php?post=484&action=edit"
Проверим работу правила утилитой ossec-logtest:
# echo '2015/06/19 00:14:11 [error] 1569#0: *8948 NAXSI_FMT: ip=94.ХХ.8.ХХ&server=ХХХ.ru&uri=/wp-admin/admin-ajax.php&learning=1&vers=0.54&total_processed=158&total_blocked=30&block=1&cscore0=$XSS&score0=20&zone0=BODY|NAME&id0=1311&var_name0=data[clef]&zone1=BODY|NAME&id1=1311&var_name1=data[wp-refresh-post-lock][post_id]&zone2=BODY|NAME&id2=1311&var_name2=data[wp-refresh-post-lock][lock], client: 94.ХХ.8.ХХ, server: ХХХ.ru, request: "POST /wp-admin/admin-ajax.php HTTP/1.1", host: "ХХХ.ru", referrer: "https://ХХХ.ru/wp-admin/post.php?post=484&action=edit"' | /var/ossec/bin/ossec-logtest -a
и убедимся, что событие обрабатывается верно:
2015/06/19 00:19:31 ossec-testrule: INFO: Reading local decoder file. 2015/06/19 00:19:31 ossec-testrule: INFO: Started (pid: 19607). ** Alert 1434662371.1: - apache, 2015 Jun 19 00:19:31 siem->stdin Rule: 31301 (level 3) -> 'Nginx error message.' Src IP: 94.ХХ.8.ХХ ...
Вывод сообщает нам, что событие после обработки декодером в конечном итоге попадает под правило с идентификатором 31301. Рассмотрим его:
# nano /var/ossec/rules/nginx_rules.xml
<rule id="31301" level="3"> <if_sid>31300</if_sid> <regex>^\S+ \S+ [error] </regex> <description>Nginx error message.</description> </rule>
и дополним новым правилом:
# nano /var/ossec/rules/local_rules.xml
<rule id="100001" level="5"> <if_sid>31301</if_sid> <match>NAXSI_FMT:</match> <description>NAXSI message.</description> </rule>
Перезапустим OSSEC:
# /etc/init.d/ossec restart
Проверим:
# echo '2015/06/19 00:14:11 [error] 1569#0: *8948 NAXSI_FMT: ip=94.XX.8.XX&server=XXX.ru&uri=/wp-admin/admin-ajax.php&learning=1&vers=0.54&total_processed=158&total_blocked=30&block=1&cscore0=$XSS&score0=20&zone0=BODY|NAME&id0=1311&var_name0=data[clef]&zone1=BODY|NAME&id1=1311&var_name1=data[wp-refresh-post-lock][post_id]&zone2=BODY|NAME&id2=1311&var_name2=data[wp-refresh-post-lock][lock], client: 94.XX.8.XX, server: XXX.ru, request: "POST /wp-admin/admin-ajax.php HTTP/1.1", host: "XXX.ru", referrer: "https://XXX.ru/wp-admin/post.php?post=484&action=edit"' | /var/ossec/bin/ossec-logtest -a
2015/06/19 00:31:25 ossec-testrule: INFO: Reading local decoder file. 2015/06/19 00:31:25 ossec-testrule: INFO: Started (pid: 20111). ** Alert 1434663085.1: - local,syslog, 2015 Jun 19 00:31:25 siem->stdin Rule: 100001 (level 5) -> 'NAXSI message.' Src IP: 94.XX.8.XX ...
Отлично. Теперь события Naxsi будут иметь идентификатор 100001 с уровнем критичности 5.
Предположим, что наш веб-сервер обслуживает несколько виртуальных хостов и мы хотим игнорировать все сообщения Naxsi для виртуального хоста ХХХ1.ru. Такую задачу можно реализовать с помощью правила c уровнем критичности 0:
# nano /var/ossec/rules/local_rules.xml
<rule id="100002" level="0"> <if_sid>100001</if_sid> <match>server=ХХХ1.ru</match> <description>NAXSI for XXX1.ru.</description> </rule>
Заключение
Snort не умеет работать с SSL трафиком в нативном режиме. Для контроля SSL-соединений можно использовать дополнение к Snort в виде viewssld.
OSSEC достаточно гибкий инструмент, позволяющий обрабатывать события из различных источников и различного содержания, а также реализовать гибкую политику парсинга событий. К OSSEC-серверу можно подключать как управляемые агенты, так и agentless-устройства, такие как коммутаторы и прочие сетевые устройства, не поддерживающие OSSEC-агенты. Кроме этого, сервер OSSEC можно использовать для удаленного хранения log-файлов. Помимо анализа и обработки событий, OSSEC умеет работать в режиме IPS (используя «active response»): блокировать доступ или же выполнять иные действия.
Prelude SIEM позволяет организовать прием, обработку и мониторинг событий с удобным веб-интерфейсом. В случае необходимости можно подключать дополнительные модули, такие как Prelude-LML, позволяющих обрабатывать расширенные журналы событий.
Существует множество бесплатных решений, способных обеспечить безопасность корпоративных сетей и систем, однако основной проблемой, на мой взгляд, является правильность обработки событий — минимизировать поток обрабатываемой информации, при этом не упустив важные события.
С конфигурацией понятно, все тривиально — гайдов в интернете полно. Будет ли продолжение? Когда начинается самое интересное — false positives, false negatives, correlation rules.
А вариант с suricata не расматривали? Ну и Snorby вроде тоже удобная веб морда к Snort/Suricata. Мы у себя используем так как она поддерживает CUDA и на довольно слабом железе с офисной nVidia карточкой может прожевать довольно много трафика
Хотелось бы описание настройки модуля viewssld и совместной работы с snort.
mv 000-default prewikka
мне надо было поменять «mv 000-default prewikka» на «mv 000-default.conf prewikka.conf» видимо зависит от версии. Ещё была проблема с тем что не виделся агент после регистрации, но сообщения приходили (проверить можно так cat /var/ossec/logs/alerts/alerts.log), решилось тем что заново связал OSSEC и Prelude (то что через две консоли делается)