161

Пример маленькой автоматизации zabbix-Mikrotik-ELK

Итак, в прошлом посте читатель узнал, что у меня завелось 55 микротиков. За прошедшее время, по заветам комментаторов, был развернут ELK Stack. Это такая штука для сбора логов со всего, что может эти логи слать. ELK = Elasticsearch + Logstash + Kibana.

Настраивала вот по этим двум статьям, в принципе там всё понятно. Раз и два.


Но помним, что микротиков сильно больше пары штук – это раз. Второе, если прописывать все их в фильтры сборщика логов, то появляется ещё одно место, куда надо что-то писать руками при вводе микротика в эксплуатацию, что не есть хорошо. Да и лень мне было прописывать их все. Короче, во мне стал зарождаться DevOps.


Задача - чтобы в заббиксе мы микротик завели – а логи с него автоматом бы полились и уже с меткой mikrotik.


Я слегка погружусь в теорию, чтобы было понятнее, что мы делаем. Итак, развернут ELK – изначально логи попадают в logstash, где с ними можно что-то сделать. Например, мы отбираем по некоторым критериям логи микротиков и вешаем на них метку «Mikrotik». Этим критерием у меня является IP – то есть «если ip из вот этого перечисления, то это микротик». Если бы у нас был ELK только для микротиков – мы бы просто вешали метку на весь трафик или обошлись без неё, но мы потом хотим добавлять еще логи всякого, например, виндовых серверов. После обработки логи попадают в elasticsearch, где мы их просматриваем с помощью Kibana (это типа веб-морда).


Для начала нам надо получить список микротиков из zabbix. Я использую для этого скриптик на питоне, который получает ip по группе и сразу генерирует кусок конфига, который будет в logstash filter.


Сперва надо установить модули zabix для питона:

apt install python3-pip

pip3 install pyzabbix


Теперь нам надо получить id группы в zabbix – его можно посмотреть в адресной строке браузера на странице группы – там в конце будет что-то типа groupid=65


Cам скрипт ниже. Мне не захотелось заморачиваться и один первый хост у меня всегда дублируется, вы можете заморочиться.

Получается строка вида «if [host] in ["10.1.1.254", “10.2.2.254”]{»


Теперь её надо вставить в правильное место конфига logstash. Чтобы этого добиться, я ставлю метку #MIKMIKMIK туда, куда будет вставлена получившаяся строка.

Вставлять будем с помощью Ansible, один раз вставится, потом будет проверяться на соответствие. Собственно из-за этого и выбран Ansible – он сам будет проверять наш конфиг на соответствие и вносить изменения только, если они есть.


Вот так выглядит /etc/logstash/conf.d/filter.conf до первой работы анзибля

Теперь собираем котлету вместе. Делаем playbook в ansible, который запустит нам скрипт, потом получившийся конфиг вставит в конфиг logstash, и если зафиксированы изменения – перезапустит службу. Со службой я долго не могла понять – почему перезапуска не происходит и ansible отваливается по timeout – ему просто не хватало прав.

write_logstash.yml:

Ну и запихиваем скрипт в крон делаться каждый час.

15  *  *  *  * ansible-playbook /usr/scripts/write_logstash.yml


Опытный читатель спросит – и что же, нам теперь на 55 микротиках настраивать логирование? И мы возвращаемся к предыдущему моему посту (и понимаем, зачем нам это было надо). Вот пример настройки лог-сервера, при этом в команде к каждому микротику указывается его IP в качестве источника данных. Без этого у меня автоматом выбирался служебный ip с интерфейса ip-ip туннеля и это было неудобно.

Ну и уровень логирования настраивается так же, только команду заменить.


В итоге мы получили что хотели – достаточно добавить микротик в заббикс и настроить на нем пересылку логов, а в ELK оно попадёт автоматом с нужной меткой.


Получился маленький кирпичик автоматизации, но путь в DevOps иногда начинается с одного шага..


Код текстом.

Лига Сисадминов

2.3K постов18.9K подписчиков

Правила сообщества

Мы здесь рады любым постам связанным с рабочими буднями специалистов нашей сферы деятельности.

3
Автор поста оценил этот комментарий
Девопс это про сферу деятельности. Это ответвление админов, в помощь непосредственно разрабам, грубо говоря.
А собирать с микротов логи, пусть и таким навороченым инструментом - админство.
раскрыть ветку (1)
2
Автор поста оценил этот комментарий

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

показать ответы
3
Автор поста оценил этот комментарий

Я могу быть не прав, да скорее всего так и есть, но думаю, что связка ELK для 55 рутеров избыточна и проще использовать было какой-нибудь SNMP-trapper.

Каждый в целом сам принимает те или иные решения)

Хорошего пинга и горящего линка, плюсик за трудолюбие))

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Одна из целей была собственно пощупать ELK. Жили раньше все без логов и дальше бы в принципе жили)

показать ответы
0
Автор поста оценил этот комментарий

Жили раньше все без логов и дальше бы в принципе жили)
обалденная фраза, которая характеризует всю вашу компанию, где у вас там 55 микротиков завелось. ну и заодно it-руководителя, если таковой имеется.

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Ну вы реально думаете, что компания рождается сразу с крутым стеком технологий самых ей подходящих? В какой-то момент в компании этого нет и оно внедряется.

показать ответы
0
DELETED
Автор поста оценил этот комментарий

Вся фишка в веб-интерфейсе - KIBANA.

Только из-за нее можно ставить ELK.

Я в 2017 году установил ELK и переложил на других поиск в логах - почему же почта не ходит. В итоге меня премировали, время поиска ошибки значительно сократилось.

В 2018 программистам объяснил, что они не правы и нужно правильно формировать логи, тогда и понятнее будет, что происходит с программой.

Основная прибыль - теперь администратор может переложить задачу по анализу на других.

Топик-стартеру замечания:

0. Молодец. Но есть возможность улучшить.

1. Вы ужасно пишете на python. Надо это улучшить.

2. Зачем вам этот скрипт? Почему бы сразу не отправить запрос в Elasticsearch, индекс mikrotik, где хранили бы записи о своих микротиках, к каждой записи добавили бы еще и ttl, тогда не нужно удалять записи в ручную. И тогда у вас ansible опрашивал бы elasticsearch, получал бы в ответ json, проходился по json массиву.
https://www.elastic.co/blog/ttl-documents-shield-and-found
3. Если у вас стоит современная система, то там всегда есть systemd, а значит есть и systemd-timer. Забудь-те про cron.
4. Вам пора уже осваивать hashicorp vault + consul. Многие вещи станут лучше.
5. Нужно еще при настройке загружать дашборды и пайплайны в Elasticsearch. Это было сделано?

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Это примерно второй мой скрипт на питоне, первым был hello world лет 10 назад. Спасибо, я попробую разобраться и улучшить)

показать ответы
0
Автор поста оценил этот комментарий

Суреката/Suricata. Есть готовое решение - вот его и пробовал завести
И сразу приношу извинения - Stamus Networks Open Source - SELKS (Suricata, Elasticsearch, Logstash, Kibana and Stamus Scirius Community Edition )

Немного неправильно написал :-(

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Может и попробую)

1
Автор поста оценил этот комментарий

Главное понимать, чем девопс от админа отличается, может с этого начать?

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Девопс - это про методологию. А не как тут кто-то написал "про CI/CD"

показать ответы
0
Автор поста оценил этот комментарий

Оценивал я) Мне показалось , на основании вашей публикации, что знаний и навыков у вас достаточно, а главное желание разбираться во всем этом. Ну ладно, я не рекрутер не буду уговаривать.

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо за оценку, я пока останусь где есть, есть обстоятельства. Но мне приятно, что кто-то готов рекомендовать настолько джунов.

0
Автор поста оценил этот комментарий

Речь идёт о позиции Джуниор девопс а не обслуживать бухгалтерию))

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо, я трезво оцениваю свои силы и даже на джуниор девопса пока не тяну)

показать ответы
1
Автор поста оценил этот комментарий

И  что такого интересного в логах микротиков ?
У меня их за сотню, но с такой потребностью я не сталкивался.

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Ну например я сразу увидела переборы паролей и прикрыла, где не было прикрыто. Еще на одном увидела ошибки ospf.

показать ответы
5
Автор поста оценил этот комментарий
Автоматизация действий, это грамотное админство, а не девопс.
раскрыть ветку (1)
1
Автор поста оценил этот комментарий

В общем, грамотное админство и девопс - это одно и то же. Вы зря раздялаете понятия. Девопс - админство на более высоком уровне в том числе

показать ответы
Автор поста оценил этот комментарий
О какой методологии речь? Типа, если для работы используется что-то сложнее блокнота и ping, то это девопс, или что?
раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Подход infrastructure as a code. Я могла бы вручную вписать список микротиков в конфиг логстеша и это не девопс. А вот собрать конфиг автоматически и раскатать анзиблем - девопс, так как фактически кусок инфраструктуры генериться кодом и сам себя документирет.

показать ответы
0
Автор поста оценил этот комментарий

@virrasha, logstash не обязательно перезапускать у него в конфиге есть настройка что бы он сам перечитывал конфиг


# Periodically check if the configuration has changed and reload the pipeline

# This can also be triggered manually through the SIGHUP signal

#

config.reload.automatic: true

#

# How often to check if the pipeline configuration has changed (in seconds)

# Note that the unit value (s) is required. Values without a qualifier (e.g. 60)

# are treated as nanoseconds.

# Setting the interval this way is not recommended and might change in later versions.

#

config.reload.interval: 10s



И еще я у себя сделал просто отдельный порт в logstash куда прилетают логи только в микротов и тогда не нужна вообще менять конфиг logstasg



input {

udp {

port => 5045

type => mikrotik

}

}

filter {

if [type] == "mikrotik" {

date {

match => ["message", "dd/MMM/YYYY:HH:mm:ss Z"]

target => "@timestamp"

}

grok {

match => {"message" => "%{NOTSPACE:topics}\s%{GREEDYDATA:log_message}"}

}

mutate {

split => ["topics", ","]

}

if "firewall" in [topics] {

grok {

match => { "log_message" => "(%{NOTSPACE:logprefix}\s)?%{DATA:logchain}:\sin:%{DATA:interface_in}\sout:%{DATA:interface_out}, src-mac\s%{NOTSPACE:src_mac}\,\sproto\s%{WORD:proto}(\s)?(\(%{DATA:con_state}\))?, %{IPV4:src_ip}(:%{INT:src_port})?->%{IPV4:dst_ip}(:%{INT:dst_port})?,(\s%{GREEDYDATA:NAT}\,)? len %{INT:length}" }

remove_field => ["log_message"]

}

if ("" in [NAT]) {

grok {

match => { "NAT" => "NAT %{GREEDYDATA:entry_point}->\(%{IPV4:nat_entry_ip}(:%{INT:nat_entry_port})?->%{IPV4:nat_dst_ip}(:%{INT:nat_dst_port})?\)" }

add_tag => [ "nat" ]

remove_field => ["NAT"]

}

}

}

if "system" in [topics] {

if "account" in [topics] {

grok {

match => {"log_message" => "user %{NOTSPACE:user} logged (?:out|in) from %{IP:src_ip} via %{WORD:src_type}"}

remove_field => ["log_message"]

}

}

if [log_message] =~ /^login failure/ {

grok {

match => {"log_message" => "login failure for user %{NOTSPACE:user} from %{IP:src_ip} via %{WORD:src_type}"}

add_tag => [ "failure" ]

remove_field => ["log_message"]

}

}

if [log_message] =~ /^'\w+' rule/ {

grok {

match => {"log_message" => "%{WORD:rule_type} rule %{WORD:rule_action} by %{NOTSPACE:user}"}

add_tag => [ "rule" ]

remove_field => ["log_message"]

}

}

}

if "ppp" in [topics] {

if "account" in [topics] {

grok {

match => {"log_message" => "%{NOTSPACE:user} logged (?:out|in), (?:%{IPV4:local_ip}|%{GREEDYDATA:OtherData}) from %{IPV4:src_ip}"}

add_tag => [ "vpn","account" ]

add_field => { "src_type" => "vpn" }

remove_field => ["log_message"]

}

}

if "info" in [topics] and [log_message] =~ /^\<\w+\-\S+\>\:/ {

grok {

match => {"log_message" => "<%{NOTSPACE:vpn_type}-%{NOTSPACE:user}>:\s%{GREEDYDATA:vpn_state}"}

add_tag => [ "vpn","state","pptp" ]

remove_field => ["log_message"]

}

}

}

if ("" in [src_ip]) {

cidr {

add_tag => [ "src_local" ]

address => [ "%{src_ip}" ]

network => [ "10.0.0.0/8" ]

}

if "src_local" not in [tags] {

geoip {

source => "src_ip"

}

geoip {

source => "src_ip"

default_database_type => "ASN"

target => "geoip_ASN"

}

}

}

mutate {

#add_tag => [ "mikrotik" ]

convert => {

"length" => "integer"

"src_port" => "integer"

"nat_entry_port" => "integer"

"nat_dst_port" => "integer"

"dst_port" => "integer"

}

rename => { "[geoip][country_name]" => "[geoip][country]" }

rename => { "[geoip_ASN][asn]" => "[geoip][asn]" }

rename => { "[geoip_ASN][as_org]" => "[geoip][as_org]" }

rename => { "[geoip][latitude]" => "[geoip][location][lat]" }

rename => { "[geoip][longitude]" => "[geoip][location][lon]" }

remove_field => [ "[geoip][timezone]","OtherData","geoip_ASN" ]

remove_tag => ["grokked","_geoip_lookup_failure","_dateparsefailure"]

}

}

}

output {

if [type] == "mikrotik" {

elasticsearch {

hosts => ["https://elk:9200"]

cacert => '/etc/elasticsearch/certs/CA.crt'

index => "mikrotik-%{+YYYY.MM}"

user => "logstash_internal"

password => "pass"

manage_template => false

}


}

}

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Спасибо!

0
Автор поста оценил этот комментарий

А пощупайте SELK - я пробовал, но не осилил пересылку логов. У вас скил вроде поболее.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

У меня скилл не более, так как я не знаю, что означает S в аббревиатуре. Просветите?

показать ответы