Last Updated on 20/12/2023 by administrator
Instalace ElastAlert2 pro Elastic
Instalace ElastAlert2 pro Elastic
Prerekvizita:
Prerekvizita pro tuto instalaci ElastAlert2 je Instalace Ubuntu Elasticsearch Kibana Logstash Filebeat (Elastic Stack)
Instalace Ubuntu Elasticsearch Kibana Logstash Filebeat (Elastic Stack)
Motivace:
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ý soubor example_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
name: Example_rule type: frequency index: filebeat-* num_events: 30 timeframe: minutes: 15 filter: - term: host.os.platform: "ubuntu" alert: - "email" email: - "prijemce@seznam.cz"
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}
Google – nastavení dvoufaktorové autentizace:
Postup k nastavení dvoufaktorové autentizace lze vidět v tomto článku:
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:
user: vaslogin@gmail.com password: qcsn sxsk xmte mcas
Spustění ElastAlert 2
Vše je připraveno, nyní je možné spustit ElastAlert příkazem níže ve složce ~/myvenv/bin:
python3.10 -m elastalert.elastalert --verbose --rule rules/example_frequency.yaml
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):
#!/bin/bash sleep 5 source ~/myvenv/bin/activate sleep 1 cd ~/myvenv/bin sleep 1 python3.10 -m elastalert.elastalert --verbose --rule rules/siem_v2.yaml
Je nutné povolit práva pro spouštění po restartu:
chmod 744 /etc/rc.local
Řešení problémů:
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.
Zdroj:
[1] https://www.youtube.com/watch?v=wKeUmRuRxi8
[2] https://elastalert2.readthedocs.io/en/latest/running_elastalert.html