Skip to content

Instantly share code, notes, and snippets.

@ESGuardian
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ESGuardian/428953bdf64c0c0c7f0c to your computer and use it in GitHub Desktop.
Save ESGuardian/428953bdf64c0c0c7f0c to your computer and use it in GitHub Desktop.

Sorry. This is for Russians only, so no english text.

Этот гист исключительно для русской аудитории. Здесь я сведу все советы по кастумизации OSSIM для работы с русским языком в одну инструкцию, понятную тем, кто этим языком пользуется в работе и жизни.

Ура! 29.07.2015 Пройдена проверка апдейтами на бою. Сегодня автоматически обновился из веб-интерфейса на версию 5.1 и ничего не отвалилось. Кстати, версия посимапатичней :)

Некоторые предварительные пояснения:
Я буду использовать недокументированные фичи и некоторые собственные хаки, которые помогают бороться с уничтожением всех внесенных изменений при апдейте системы. Для реализации хаков существуют два основных скрипта, которые лежат в дирректории

/usr/local/bin
и называются
check_my_config.py
и
check_mysql_config.py
соответственно. А еще в этой же директории обязан лежать файл с именем
my_ParserUtil.tail
который должен начинаться строкой
# my ParserUtil tail
(регистр имеет значение). Это файл предназначен для реализации дополнительных функций в плагинах собственной разработки. По смыслу он именно то, как называется, хвост, который приклеивается к файлу
/usr/share/alienvault/ossim-agent/ParserUtil.py
Позже поясню, почему я так поступил.
Эти скрипты здесь выложены отдельнымы файлами обязательно поместите их на место и обязательно дайте права на исполнение:

chmod 755 /usr/local/bin/check_mysql_config.py
chmod 755 /usr/local/bin/check_my_config.py

Что делают эти скрипты? Первый проверяет, что файл

/etc/mysql/my.cnf
содержит директиву
!includedir /usr/local/etc/mysql/
и если ее нет, то дописывает в конец файла. Второй проверяет, что файл конфигурации плагинов содержит указание на использование кодировки для каждого из них и если его нет, то переписывает файл с указанием кодировки. По умолчанию ставится кодировка cp1251, но в файле есть "словарь исключений", где можно задать кодировки индивидуально. Вы можете поправить этот словарь, как вам надо. Кроме того, второй скрипт проверяет, что файл ParserUtil.py содержит "хвост" и если его там нет, то дописывает.

Начнем потихоньку ломать систему.
Первым делом мы должны установить в системе нужные нам русские локали, а именно UTF-8 и cp1251. Изначально они не установлены. Это делается легко и приятно с помощью команды
#dpkg-reconfigure locales 
не устанавливайте русские локали в качестве системных. Это совершенно не нужно и может вылезти боком. Достаточно, чтобы они просто были. Апдейты OSSIM не меняют эти настройки. Можно к этому больше не возвращаться.
Еще одна вещь, которую можно сделать один раз. Конфигурация FreeTDS. FreeTDS используется в качестве драйвера для доступа к внешним БД в плагинах, которые читают данные из баз (database type plugins) вы должны исправить общую секцию настроек в конфигурационном файле

#/etc/freetds/freetds.conf
[global]
tds version = 7.0
client charset = UTF-8

Этот файл также не изменяется при апдейтах.

Теперь приступим к поправке mySQL
Для начала создадим файл mysql.cnf в каталоге /usr/local/etc/mysql (каталог тоже нужно создать)

# /usr/local/etc/mysql/mysql.cnf
[client]
default-character-set=utf8

[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET collation_connection = utf8_unicode_ci'
character-set-server = utf8

Теперь самое время проверить, что мы поместили в нужное место скрипт check_mysql_config.py и назначили ему права на исполнение. Если проверили то редактируем файл

/etc/init.d/mysql
добавляем запуск нашего скрипта в секцию "start" как показано здесь. Не перепутайте место :)

#
# main()
#

case "${1:-''}" in
  'start')
	sanity_checks;
	# Start daemon
	log_daemon_msg "Starting MySQL (Percona Server) database server" "mysqld"
	if mysqld_status check_alive nowarn; then
	   log_progress_msg "already running"
	   log_end_msg 0
	else
        /usr/local/bin/check_mysql_config.py > /dev/null
  	    "${PERCONA_PREFIX}"/bin/mysqld_safe > /dev/null 2>&1 &

Готово дело. Можем дать с консоли команду /etc/init.d/mysql restart

Теперь займемся улучшением самого OSSIM.
Для этого в двух файлах

/etc/init.d/ossim-server и /etc/init.d/ossim-agent
вставляем одну строчку в одной и той же секции (они одинаковые):

d_start() {
   /usr/local/bin/check_my_config.py > /dev/null

Вот прямо так и ставим первой строкой в секции d_start().
Теперь достаточно дать команду /etc/init.d/ossim-agent restart

Зачем так сделано?
Дело в том, что по меньшей мере с версии 5 в файле конфигурации /etc/ossim/agent/config.cfg можно задать кодировку для каждого плагина простым добавлением конструкции |cp1251 в конце строки с декларацией плагина. Тогда русские буковки можно использовать как в самом тексте файла конфигурации данного плагина, напроимер в регулярных выражениях, так и в данных которые этот плагин обрабатывает. Но эта фича не только не документирована, но и не доделана до конца. При любом апдейте или при включении нового плагина с консоли, короче при любой операции ossim-reconfig, файл конфигурации перезапишется без указания параметра кодировки. По этой причине я и вставил такой вот хак. Последняя команда любого апдейта или реконфига это перезапуск сервисов, поэтому я вставил в скрипты инициации проверку и правку конфигурации. Это сильно облегчило мою жизнь.
Теперь о "хвосте".
Все дело в кастомных функциях, которые можно использовать в плагинах. Существует механизм создания файла с такими функциями и включения его в плагин. Однако он не документирован. В документации никак не описан допустимый синтаксис и только приведены примеры элементарных функций. Не ясно даже можно ли передать функции более одного параметра. Очень похоже, что нельзя. Не понятно, можно ли использовать в таких кастомных функциях объекты и методы из модулей питона, например открывать файлы. Позже я разберусь по исходному коду, как именно парсится файл с описанием кастомных функций и выясню эти вопросы, но пока я решил, что проще дописать собственные функции в файл ParserUtil.py, который содержит набор "стандартных" функций для плагинов.
Вот так и появился "хвост". С хвостом надо обращаться осторожно, все, что вы туда дописываете, надо тщательно отлаживать. И кстати, при написании кода, ни в коем разе не забывайте, что конец строки в linux - это lf, а не cr+lf, как в Windows. Это существенный вопрос. Если пишете код на компе с виндой, не забывайте убедиться в том, что файл сохранен с правильными концами строк. Это умеет делать и MS Visual Studio и FAR.

Пожалуй всё. Есть вопросы - задавайте.

Нет. Не всё. Забыл про геолокацию.
В OSSIM для данных геолокации используется модуль GeoIP и бесплатные базы данных geolite и geolite-city от Maxmind. PurserUtil.py содержит соответсвующие функции, которые можно использовать в плагинах, непосредственно в файлах plugin.cfg.
Но дело в том, что эти базы имеют "устаревший" формат. Maxmid сейчас поставляет базы в новом формате GeoIP2. Мне эти базы нравятся больше. Но в питоне на OSSIM нет модуля для работы с этим форматом. Совсем нет. Видимо это проблема лицензии. Насколько я понял Geolite разработчики могут распространять бесплатно, а Geolite2 - нет. Я не счел нужным прикручивать новые базы к ParserUtil, поскольку собственно в плагинах мне эта геолокация нафиг не нужна. А вот в некоторых отчетах очень даже полезна, например в отчете об удаленном доступе rarep.py. Поэтому, я добавил необходимый модуль. А еще внезапно обнаружилось, что в системе нет любимого всеми установщика пакетов для питона pip. Ну, заодно и его поставим.

 
wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate
python get-pip.py
pip install geoip2

Теперь надо загрузить саму базу вот отсюда

http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz

распаковать и положить в нужное место

/usr/share/geoip/GeoLite2-City.mmdb

Конечно, GeoLite2 - это не супер-пупер точные данные, но подробные базы GeoIP2 стоят совсем не маленьких денег. Я пока не написал скрипт для автоматического обновления базы. Подкладываю ее вручную.

#! /usr/bin/python
# -*- coding: latin1 -*-
import sys
#import codecs
import subprocess
cfg_path = '/etc/ossim/agent/config.cfg'
new_cfg_path = '/var/local/config.tmp'
encoding_exceptions = {'wmi-monitor':'utf8'}
my_encoding = 'cp1251'
with open (cfg_path,'r') as f:
conf = f.read()
f.close
start_flag = False
continue_flag = True
need_update = False
out_lines=[]
for line in conf.splitlines():
out_lines.append(line.strip())
if start_flag and continue_flag :
if not '=' in out_lines[-1]:
continue_flag = False
elif not '|' in out_lines[-1]:
key = out_lines[-1].split('=')[0]
need_update = True
if key in encoding_exceptions:
out_lines[-1] = out_lines[-1] + '|' + encoding_exceptions[key]
else:
out_lines[-1] = out_lines[-1] + '|' + my_encoding
if '[plugins]' in out_lines[-1]:
start_flag = True
if need_update :
with open(new_cfg_path,'w') as f:
for line in out_lines:
f.write(line + '\n')
f.close
cmd = '/bin/cp -f /etc/ossim/agent/config.cfg /etc/ossim/agent/config.cfg.myreconfig.bak'
p = subprocess.Popen (cmd, shell=True)
p_stutus = p.wait()
cmd = '/bin/cp -f /var/local/config.tmp /etc/ossim/agent/config.cfg'
p = subprocess.Popen (cmd, shell=True)
p_stutus = p.wait()
# check PerserUtil.py
pu_need_update = False
with open ('/usr/share/alienvault/ossim-agent/ParserUtil.py', 'r') as f:
pu=f.read()
f.close()
if not 'my ParserUtil tail' in pu:
cmd = 'cp -f /usr/share/alienvault/ossim-agent/ParserUtil.py /usr/share/alienvault/ossim-agent/ParserUtil.py.myreconfig.bak'
p = subprocess.Popen (cmd, shell=True)
p_stutus = p.wait()
cmd = 'cat /usr/local/bin/my_ParserUtil.tail >> /usr/share/alienvault/ossim-agent/ParserUtil.py'
p = subprocess.Popen (cmd, shell=True)
p_stutus = p.wait()
#! /usr/bin/python
# -*- coding: latin1 -*-
import sys
#import codecs
import subprocess
cfg_path = '/etc/mysql/my.cnf'
with open (cfg_path,'r') as f:
conf = f.read()
f.close
if not '!includedir /usr/local/etc/mysql' in conf:
cmd = 'cp -f /etc/mysql/my.cnf /etc/mysql/my.cnf.myreconfig.bak'
p = subprocess.Popen (cmd, shell=True)
p_stutus = p.wait()
with open (cfg_path,'a') as f:
f.write('\n!includedir /usr/local/etc/mysql\n')
f.close
# my ParserUtil tail
UNWANTED_URLS=[]
with open("/etc/my_ossim/unwanted_urls.list","r") as f:
UNWANTED_URLS=[line.rstrip() for line in f]
f.close()
def my_tmg_web_sid(bsent=0, breceived=0, url='0', uri=''):
if 'Microsoft-Server-ActiveSync' in uri and 'Cmd=Sync' in uri:
sid=2
return sid
sid = 1
if 'in-bank.ru' in url:
return sid
bsent = int(bsent)
breceived = int (breceived)
if bsent > 1000000:
return 2000
if bsent > breceived:
sid = sid + 10
if bsent > 200000:
sid = sid + 100
for elem in UNWANTED_URLS:
dot_elem="."+elem
if elem == url or dot_elem in url:
sid = sid + 1000
break
return sid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment