ElastAlert2 je nástroj určený pro monitorování událostí a vytváření upozornění na základě dat uložených v Elasticsearch. Hlavním účelem ElastAlertu 2 je umožnit uživatelům definovat pravidla a podmínky, které budou sledovat události v reálném čase v Elasticsearch indexech a upozornit je na důležité události.
OS:
Instalace byla prováděna na Ubuntu 22.04 LTS pro Elasticsearch 8.8.1. Vše konkrétně otestováno přes VirtualBox 7.0.8.
Implementace [1,2]:
Příprava virtuálního prostředí:
Aktualizace seznamu balíčků z repozitářů:
apt update
Nainstalovat balíček python3.10-venv a python3-pip. Balíček python3.10-venv obsahuje nástroje pro vytváření a správu virtuálních prostředí pro Python 3.10. Virtuální prostředí umožňuje izolovat balíčky Python v samostatném prostředí, což je užitečné při práci na projektech s různými závislostmi. Balíček python3-pip obsahuje správce balíčků pip pro Python 3.10. pip je nástroj pro správu balíčků Python a umožňuje jednoduchou instalaci, aktualizaci a odstraňování balíčků.
apt install python3.10-venv python3-pip -y
Vytvořit virtuální prostředí ve domovské složce ~/myvenv/:
python3 -m venv ~/myvenv/
Po úspěšném vytvoření virtuálního prostředí, aktivovat prostředí spuštěním příkazu:
source ~/myvenv/bin/activate
Pozn. Nyní by se mělo zobrazi (myvenv) před uživatelským jménem na řádku. Nyní by všechny příkazy níže měly být spouštěny pod virtuálním prostředím.
Instalace ElasticAlert2:
pip install elastalert2
Příkazem níže se nainstaluje balíček setuptools přes správce balíčku pro Python. Příkaz specifikuje minimální požadovanou verzi 11.3. Pokud je verze tato verze setuptools 11.3 stejná nebo vyšší, pip ji nainstaluje:
pip install "setuptools>=11.3"
Vytvoření konfigurace pro ElastAlert2:
Přejít do složky ~/myvenv/bin kde se nainstaloval ElastAlert:
cd ~/myvenv/bin
Ve složce ~/myvenv/bin vytvořit soubor config.yaml:
vi config.yaml
a vložit tento kód níže:
# This is the folder that contains the rule yaml files
# This can also be a list of directories
# Any .yaml file will be loaded as a rule
rules_folder: rules
# How often ElastAlert will query Elasticsearch
# The unit can be anything from weeks to seconds
run_every:
minutes: 1
# ElastAlert will buffer results from the most recent
# period of time, in case some log sources are not in real time
buffer_time:
minutes: 15
# Definovat IP adresu serveru Elasticsearch. IP adresu lze zjistit pomocí příkazu ip addr.
# Elastic server běží na stejném IP adrese jako bude běžet ElastAlert 2.
# V tomto případě je to IP adresa 192.168.0.162
es_host: 192.168.0.162
# The Elasticsearch port, defaultni port Elasticseach
es_port: 9200
# Connect with TLS to Elasticsearch - komunikace na portu 9200 probiha sifrovane
use_ssl: True
# Verify TLS certificates
verify_certs: True
# Option basic-auth username and password for Elasticsearch
# defaultni username je elastic
# temito prihlasujicimi udaji se pripojujete pres webove rozhrani elasticsearch
es_username: elastic
es_password: somepassword
# Use SSL authentication with client certificates client_cert must be
# a pem file containing both cert and key for client
# definice cesty k certifikatu ktery je potrebny, protoze komunikace probiha sifrovane
ca_certs: /etc/elasticsearch/certs/http_ca.crt
# The index on es_host which is used for metadata storage
# This can be a unmapped index, but it is recommended that you run
# elastalert-create-index to set a mapping
writeback_index: elastalert_status
writeback_alias: elastalert_alias
# If an alert fails for some reason, ElastAlert will retry
# sending the alert until this time period has elapsed
alert_time_limit:
days: 2
#definice emailového účetu ze kterého budou ElastAlerty přicházet
from_addr: odesilatel@gmail.com
#čas, od kterého začne ElastAlert vyhledávat události. V tomto případě je nastaveno na aktuální čas.
start_time: "now"
#adresa SMTP serveru pro odesílání emailů
smtp_host: "smtp.gmail.com"
#definující číslo portu TCP/587, který bude použit pro připojení k SMTP serveru.
smtp_port: 587
#je cesta určující umístění souboru obsahujícího autentizační údaje pro přihlášení k SMTP serveru. Soubor obsahuje uživatelské jméno a heslo pro přístup k SMTP serveru
smtp_auth_file: 'smtp_auth_file.yaml'
Spustit příkaz elastalert-create-index ve složce ~/myvenv/bin. ElastAlert využije souboru config.yaml a k připojí se tak k Elasticsearch serveru a vytvoří index s názvem elastalert_status pro pro ukládání stavu a informací o spouštění pravidel. Tento index je důležitý pro správnou funkčnost ElastAlert, protože v něm uchovává informace o stavu pravidel, naposledy vyhledaných událostech, časovém okně a dalších souvisejících informacích:
elastalert-create-index
Výstup příkazu elastalert-create-index by měl nakonci vyhodit hlášku Done!
Reading Elastic 8 index mappings:
Reading index mapping 'es_mappings/8/silence.json'
Reading index mapping 'es_mappings/8/elastalert_status.json'
Reading index mapping 'es_mappings/8/elastalert.json'
Reading index mapping 'es_mappings/8/past_elastalert.json'
Reading index mapping 'es_mappings/8/elastalert_error.json'
Deleting index elastalert_status.
Deleting index elastalert_status_status.
Deleting index elastalert_status_silence.
Deleting index elastalert_status_error.
Deleting index elastalert_status_past.
New index elastalert_status created
Done!
Vytvoření nového pravidla pro ElastAlert 2:
Ve složce ~/myvenv/bin vytvořit složku rules:
mkdir rules
Pro test bude vytvořeno pravidlo v souboru example_frequency.yaml, které bude nastaveno tak, že při určité události bude vygenerována notifikace na emailovou adresu.
Vytvořit nový souborexample_frequency.yaml ve složce rules/:
vi rules/example_frequency.yaml
a překopírovat do souboru example_frequency.yaml vše níže, kde
name: Example_rule – definuje libovolné jméno pravidla, v tomto případě Example_rule
type: frequency – definuje typ pravidla, v tomto případě se jedná o typ frequency, což spouští upozornění, pokud se překročí počet shodujících se události v určitém časovém úseku
index: filebeat-* – určuje vzor Elasticalert indexu ve kterém se budou hledat události. V tomto případě se budou vyhledávat události v filebeat-*, což znamená, že bude hledat ve všech indexech začínajících na „filebeat-„
num_events: 30 – nastavuje prahovou hodnotu počtu událostí, tomto případě 30
timeframe – definuje časové období, ve kterém se počítají události, v tomto případě je nastaveno 15 minut
filter – filtr, který se použije na logy (v tomto případě na logy v filebeat-), v tomto případě se filtruje řetezec host.os.platform: „ubuntu“
alert – definuje akci, co se ma provést při spustění pravidla, v tomto případě se odešle emailová notifikace
email: určuje emailové adresy, na které budou odeslány notifikační emaily
V příkladu výše pokud příjde 30 logů obsahující řetezec host.os.platform: „ubuntu“ v rámci 15 minut, měl by se vygenerovat email.
Pro test je možné si vyfiltrovat v Analytics > Discover logy filebeat-* s obsahující řetezec host.os.platform: „ubuntu“ za posledních 15 minut. Jak lze vidět počet hitů je 43.
Otestování nového pravidla pro ElastAlert 2:
Příkaz elastalert-test-rule ve složce ~/myvenv/bin provede test nového pravidla example_frequency.yaml vytvořeného ve složce rules/:
elastalert-test-rule rules/example_frequency.yaml
Výstup příkazu elastalert-test-rule rules/example_frequency.yaml zobrazuje, že došlo k „matchnutí“ pravidla example_frequency.yaml a počet hitů (což je 43 což je vidět na poslední řádeku elastalert_status – je potřeba použít posuvník. To koresponduje s logy ve webovém prohlížeči výše, kde je také číslo 43.
INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent.
To send them but remain verbose, use --verbose instead.
Got 3814 hits from the last 0 day
Available terms in first hit:
agent.name
agent.id
agent.ephemeral_id
agent.type
agent.version
process.name
process.pid
log.file.path
log.offset
fileset.name
message
tags
input.type
@timestamp
ecs.version
related.hosts
service.type
@version
host.hostname
host.os.kernel
host.os.codename
host.os.name
host.os.type
host.os.family
host.os.version
host.os.platform
host.ip
host.containerized
host.name
host.id
host.mac
host.architecture
event.ingested
event.original
event.timezone
event.kind
event.module
event.dataset
INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent.
To send them but remain verbose, use --verbose instead.
INFO:elastalert:1 rules loaded
INFO:apscheduler.scheduler:Adding job tentatively -- it will be properly scheduled when the scheduler starts
INFO:elastalert:Queried rule Example_rule from 2023-06-23 14:44 CEST to 2023-06-23 14:59 CEST: 43 / 43 hits
INFO:elastalert:Queried rule Example_rule from 2023-06-23 14:59 CEST to 2023-06-23 15:00 CEST: 0 / 0 hits
INFO:elastalert:Alert for Example_rule at 2023-06-23T14:54:53+02:00:
INFO:elastalert:Example_rule
At least 30 events occurred between 2023-06-23 14:39 CEST and 2023-06-23 14:54 CEST
@timestamp: 2023-06-23T14:54:53+02:00
@version: 1
_id: o2ZS6IgB_BxJTBvAnhGs
_index: filebeat-8.8.1-2023.06.23
agent: {
"ephemeral_id": "34b75006-cf3b-4cb9-b0d6-2ba2ab8ca619",
"id": "3066253e-3bed-4500-b778-c8e624feebb7",
"name": "sec",
"type": "filebeat",
"version": "8.8.1"
}
ecs: {
"version": "1.12.0"
}
event: {
"dataset": "system.syslog",
"ingested": "2023-06-23T12:55:08.716569167Z",
"kind": "event",
"module": "system",
"original": "Jun 23 14:54:53 sec filebeat[745]: {\"log.level\":\"info\",\"@timestamp\":\"2023-06-23T14:54:53.647+0200\",\"log.logger\":\"monitoring\",\"log.origin\":{\"file.name\":\"log/log.go\",\"file.line\":187},\"message\":\"Non-zero metrics in the last 30s\",\"service.name\":\"filebeat\",\"monitoring\":{\"metrics\":{\"beat\":{\"cgroup\":{\"memory\":{\"mem\":{\"usage\":{\"bytes\":132009984}}}},\"cpu\":{\"system\":{\"ticks\":6590,\"time\":{\"ms\":10}},\"total\":{\"ticks\":8370,\"time\":{\"ms\":20},\"value\":8370},\"user\":{\"ticks\":1780,\"time\":{\"ms\":10}}},\"handles\":{\"limit\":{\"hard\":524288,\"soft\":524288},\"open\":13},\"info\":{\"ephemeral_id\":\"34b75006-cf3b-4cb9-b0d6-2ba2ab8ca619\",\"uptime\":{\"ms\":11824041},\"version\":\"8.8.1\"},\"memstats\":{\"gc_next\":35078480,\"memory_alloc\":22064960,\"memory_total\":994613112,\"rss\":115884032},\"runtime\":{\"goroutines\":45}},\"filebeat\":{\"events\":{\"active\":0,\"added\":5,\"done\":5},\"harvester\":{\"open_files\":1,\"running\":1}},\"libbeat\":{\"config\":{\"module\":{\"running\":2}},\"output\":{\"events\":{\"acked\":5,\"active\":0,\"batches\":3,\"total\":5},\"read\":{\"bytes\":18},\"write\":{\"bytes\":3600}},\"pipeline\":{\"clients\":2,\"events\":{\"active\":0,\"published\":5,\"total\":5},\"queue\":{\"acked\":5}}},\"registrar\":{\"states\":{\"current\":3,\"update\":5},\"writes\":{\"success\":3,\"total\":3}},\"system\":{\"load\":{\"1\":0.9,\"15\":0.18,\"5\":0.33,\"norm\":{\"1\":0.9,\"15\":0.18,\"5\":0.33}}}},\"ecs.version\":\"1.6.0\"}}",
"timezone": "+02:00"
}
fileset: {
"name": "syslog"
}
host: {
"architecture": "x86_64",
"containerized": false,
"hostname": "sec",
"id": "0ffca90d37f84beab1286b5b71ce275d",
"ip": [
"192.168.0.153",
"fe80::a00:27ff:fea3:475a"
],
"mac": [
"08-00-27-A3-47-5A"
],
"name": "sec",
"os": {
"codename": "jammy",
"family": "debian",
"kernel": "5.15.0-75-generic",
"name": "Ubuntu",
"platform": "ubuntu",
"type": "linux",
"version": "22.04.2 LTS (Jammy Jellyfish)"
}
}
input: {
"type": "log"
}
log: {
"file": {
"path": "/var/log/syslog"
},
"offset": 2360565
}
message: {"log.level":"info","@timestamp":"2023-06-23T14:54:53.647+0200","log.logger":"monitoring","log.origin":{"file.name":"log/log.go","file.line":187},"message":"Non-zero metrics in the last 30s","service.name":"filebeat","monitoring":{"metrics":{"beat":{"cgroup":{"memory":{"mem":{"usage":{"bytes":132009984}}}},"cpu":{"system":{"ticks":6590,"time":{"ms":10}},"total":{"ticks":8370,"time":{"ms":20},"value":8370},"user":{"ticks":1780,"time":{"ms":10}}},"handles":{"limit":{"hard":524288,"soft":524288},"open":13},"info":{"ephemeral_id":"34b75006-cf3b-4cb9-b0d6-2ba2ab8ca619","uptime":{"ms":11824041},"version":"8.8.1"},"memstats":{"gc_next":35078480,"memory_alloc":22064960,"memory_total":994613112,"rss":115884032},"runtime":{"goroutines":45}},"filebeat":{"events":{"active":0,"added":5,"done":5},"harvester":{"open_files":1,"running":1}},"libbeat":{"config":{"module":{"running":2}},"output":{"events":{"acked":5,"active":0,"batches":3,"total":5},"read":{"bytes":18},"write":{"bytes":3600}},"pipeline":{"clients":2,"events":{"active":0,"published":5,"total":5},"queue":{"acked":5}}},"registrar":{"states":{"current":3,"update":5},"writes":{"success":3,"total":3}},"system":{"load":{"1":0.9,"15":0.18,"5":0.33,"norm":{"1":0.9,"15":0.18,"5":0.33}}}},"ecs.version":"1.6.0"}}
num_hits: 43
num_matches: 1
process: {
"name": "filebeat",
"pid": 745
}
related: {
"hosts": [
"sec"
]
}
service: {
"type": "system"
}
system: {
"syslog": {}
}
tags: [
"beats_input_codec_plain_applied"
]
Would have written the following documents to writeback index (default is elastalert_status):
silence - {'exponent': 0, 'rule_name': 'Example_rule', '@timestamp': datetime.datetime(2023, 6, 23, 13, 0, 1, 533085, tzinfo=tzutc()), 'until': datetime.datetime(2023, 6, 23, 13, 1, 1, 533076, tzinfo=tzutc())}
elastalert_status - {'rule_name': 'Example_rule', 'endtime': datetime.datetime(2023, 6, 23, 13, 0, 1, 245698, tzinfo=tzutc()), 'starttime': datetime.datetime(2023, 6, 23, 12, 44, 52, 245698, tzinfo=tzutc()), 'matches': 1, 'hits': 43, '@timestamp': datetime.datetime(2023, 6, 23, 13, 0, 1, 538969, tzinfo=tzutc()), 'time_taken': 0.032947540283203125}
Nyní je potřeba vytvořit nový soubor smtp_auth_file.yaml ve složce ~/myvenv/bin/rules:
vi rules/smtp_auth_file.yaml
V tomto souboru smtp_auth_file.yaml přidat parametry níže. Password je tady App password vytvořený na Google účtu a user je emailová adresa na které bylo vygenerováno heslo:
Výstup příkazu python3.10 -m elastalert.elastalert –verbose –rule rules/example_frequency.yaml ukazuje, že jedno pravidlo bylo načteno a jeden alert byl poslán:
INFO:elastalert:1 rules loaded
INFO:elastalert:Starting up
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999693 seconds
INFO:elastalert:Queried rule Example_rule from 2023-06-23 14:49 CEST to 2023-06-23 15:04 CEST: 43 / 43 hits
INFO:elastalert:Queried rule Example_rule from 2023-06-23 15:04 CEST to 2023-06-23 15:16 CEST: 39 / 39 hits
INFO:elastalert:Sent email to ['prijemce@seznam.cz']
INFO:elastalert:Ignoring match for silenced rule Example_rule
INFO:elastalert:Ran Example_rule from 2023-06-23 14:49 CEST to 2023-06-23 15:16 CEST: 39 query hits (0 already seen), 2 matches, 1 alerts sent
INFO:elastalert:Example_rule range 1657
V emailovém účtu prijemce@seznam.cz by měla jít emailová notifikace vidět:
Příklad filtrování jednotlivých řádků v emailové zprávě:
Vytvořit nový soubor siem_general_rule.yaml ve složce rules/:
vi rules/siem_general_rule.yaml
Zde je příklad filtrování jednotlivých polí:
#bude filtrovano pro libovolny typ udalosti
type: any
#hvezdicka znamena, hledej ve vsech indexech
index: "*"
#pocet udalosti, ktere odpovidaji podminkach nize, aby bylo generovano upozorneni
num_events: 1
timeframe:
minutes: 5
#filtruji se jen logy obsahujici pole kibana.alert.rule.consumer a hodnotu siem
filter:
- term:
kibana.alert.rule.consumer: "siem"
#jako alert se vygeneruje email
alert:
- "email"
#odesila se emailovou adresu prijemce@seznam.cz
email:
- "prijemce@seznam.cz"
#v emailu budou videt pouze definovane argumenty v alert_text_args
alert_text_type: alert_text_only
#promenne ktere se budou ukazovat emailove zprave
alert_text: "Alert created: {0} \n\n hostname: {1} \n\n IP_address: {2} \n\n kibana.alert.rule.severity: {3} \n\n kibana.alert.rule.name: {4} \n\n kibana.alert.rule.description: {5} \n\n URL: {6}"
#seznam argumentu, které budou nahrazovat odpovídající značky v alert_text
alert_text_args:
- "@timestamp"
- winlog.computer_name
- host.ip
- kibana.alert.rule.severity
- kibana.alert.rule.name
- kibana.alert.rule.description
- kibana.alert.url
#promenna ktera se budou ukazovat v subjectu emailove zpravy
alert_subject: "ElastAlert rule name: {0}"
#seznam argumentu, které budou nahrazovat odpovídající značky v alert_subject
alert_subject_args:
- kibana.alert.rule.name
Takto vypada finální email s filtrovanými proměnnými:
Spuštění příkazu na pozadí:
Aby po odlášení uživatele běžel příkaz pro spuštění ElastAlert, je možné použít příkaz níže:
screen
Stisknout mezerník a následně je možné vložit příkaz pro spuštění ElastAlert.
Spuštění příkazu po rebootu OS:
Aby se zasílaly emaily po rebootu OS je potřeba jej přidat do rc.local souboru, který slouží ke spouštění příkazů při startu systému:
sudo vi /etc/rc.local
Do souboru rc.local dopsat (bez sleep příkazu jsem to nezkoušel):
Pozn. Pokud se v emailové notifikaci zobrazí hláška:
[WARN ][plugins.alerting] APIs are disabled because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.“,
Je potřeba nastavit API integration key, který popisuje tento článek.
Ahoj čtenáři, rád bych tě poprosil aby ses zamyslel, co je vše potřeba ke vzniku článku. Jakožto amatérský softwarový kutil musím:
1) Nejdříve vše nastudovat v cizích jazycích. 2) Vše následně prakticky vyzkoušet. 3) Svoje poznatky a zkušenosti napsat do článku který si právě přečetl v jazyku kterému rozumíš. 4) Dát článku hlavu a patu a publikovat.
Každý článek zabere několik hodin práce, za kterou mi nikdo neplatí. Prosím zvaž, kolik času jsem ti právě ušetřil. Pokud ti to stojí aspoň za cenu jedné kávy, tak mi ji kup. Předem moc děkuji.
Příspěvek tak můžeš provést zasláním libovolné částky na mé číslo účtu 1558701011/3030 Nebo můžeš dar poslat kliknutím na tento odkaz Podpořit tento WEB, který tě přesměruje na mou platební bránu Revolut.
Dar je také možné poslat ve formě Bitcoinu na BTC peněženku bc1qqdf5fp42a7srwwhh2rut8zr9x4jm5c8fqc9qw6
Veškeré peněžní prostředky budu také používat na zlepšení kvality své webové tvorby a na psaní nových technických návodů. Za každý dar předem děkuji.