Project

General

Profile

Actions

Bug #4253

closed

Handling of too big events

Added by Pavel Kácha over 5 years ago. Updated about 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Development - Core
Target version:
Start date:
08/09/2018
Due date:
% Done:

0%

Estimated time:
To be discussed:
No

Description

Date: Wed, 1 Aug 2018 11:11:56 +0200
From: Radko Krkoš <>

Zdravím páni,
v rámci dlhodobého ladenia a monitorovania výkonu PostgreSQL pod
Mentatom na (dnes už) mentat-hub som si všimol kuriózny typ udalosti.
Jedná sa o detekciu na našom tarpite, zdroj 185.141.60.128 (Telenor
India), ktorý zdá sa skenuje stále dookola celý tento dark rozsah.
Udalosť je nahlasovaná každých cca 15 minút, má desiatky cieľových
adries a portov. Príklad udalosti (bezpečné):

https://mentat-hub.cesnet.cz/mentat/events/show/26aa5f45-1a36-4bf4-b1ee-f2d5e9e1c140

Jednoduché hľadanie na túto adresu ako zdroj trvalo vyše 16 minút,
PostgreSQL vrátil výsledok prakticky okamžite (určite pod 2s, do logu sa
dotaz nedostal), úzke hrdlo bolo spracovanie v apache ktorý to zvyšok
času formátoval na jednom jadre.
Ďalšia vec je zobrazenie na klientovi, to tiež pár minút trvalo a po
dokončení (javascript?) vyťažuje jedno jadro na plno a prakticky sa to
celé nedá používať.

Myslím že takto oznamovaná udalosť nie je príliš užitočná k ničomu,
nejaké mapovania na ktorých IP boli skenované ktoré porty či to ktoré
práve cieľové adresy pripadli na toto okno sú naozaj len výsledky zákona
veľkých čísel a malého okna.

Kto má cz.cesnet.tarpit na starosti? Zdá sa mi že pharook spomínal že
Pavel Vachek ale už minule robil zásahy do agregátoru nakoniec pharook sám.

Ako radíte postupovať? RT? Je to konektor vo warden-contrib hp-labrea?
Ak áno, mám porozmýšľať nad implementáciou nejakej silnejšej agregačnej
logiky pre takéto extrémne prípady?

Alebo to chceme s takouto úrovňou detailov s tým že práca s týmito
udalosťami sa bude musieť diať mimo Mentat?
Zlepšenie v Mentate asi nebude jednoduché, formátovanie v apache v
multithreade by na implementácii zrejme zabralo viac času ako by bolo
slušné. A čo spraviť na strane klienta si ani neviem predstaviť.


Related issues

Related to Mentat - Bug #4261: Shorten events/search output in case of too long eventsClosedJan Mach08/10/2018

Actions
Related to Mentat - Feature #4273: Consider/choose/implement different communication protocolNew08/21/2018

Actions
Related to Mentat - Feature #4274: Minimize whole JSON IDEA events usage (jsonb column)ClosedRadko Krkoš08/22/201808/22/2018

Actions
Related to Mentat - Feature #4275: Split jsonb column into its own tableClosedPavel Kácha

Actions
Actions #1

Updated by Pavel Kácha over 5 years ago

Date: Tue, 7 Aug 2018 11:50:12 +0200
From: Pavel Kácha <>
Subject: Re: [Mentat] Máme víťaza v súťaži o vraha výkonu

- U nás si to můžeme pořešit, pokusil jsem se to udělat (dopsal jsem přímo
na produkci na au1 natvrdo kladivo, které nepřidává zdrojové porty, pokud
jich je víc než 1024, a ukončí kontext a pošle zprávu, pokud už obsahuje
víc než 2000 spojení. Je to nad většinou toho, co vidím v logu, takže by
to mohlo rozlámat jen obří outliery. Vzhledem k tomu, že je to docela
specificky napsaný a časově založený kontextový manager, bylo docela
vyšívání nerozbít něco jiného. Poučení pro Deadbeat.)

- To ale neznamená, že se s podobnými zprávami nezačneme setkávat z jiných
zdrojů (Protective/CTI/Turris anyone?), zpráva je obrovská, ale legitimní,
popisuje poměrně přesně, co se v okně stalo.

Takže bychom
1, neměli utavit databázi
2, neměli utavit apache
3, neměli utavit uživateli browser (a navíc mu podat neprohlédnutelnou stránku)

Ad 3: Asi by bylo rozumné nesnažit se v events/search zobrazit úplně
všechno, ale omezit počet adres na nějaký smysluplný počet (třeba s indikací
počtu, něco jako "195.113.134.228, 195.113.134.229, ... (10 000 IPs)", nebo třeba
"~195.113.134.0/24, ... (10 000 IPs)".

Ad 2: Tohle generování zobrazení by nemělo být náročné. Takže buď velmi
jednoduchý scan a příprava předtím, než se to všechno předá šabloně
(předpokládám, že tam bude bottleneck), nebo předpočítání fallbackovaného
rozsahu, které se dá spojit s (3).

Ad 3: O tom jsme se kdysi bavili s Radkem, že by v tabuli events mohl být
kromě pole zdrojových a pole cílových IP adres vytažen i zdrojový rozsah
(který pokrývá všechny zdrojové IP ve zprávě) a cílový rozsah (ditto).
Dotazy by se mohly rozšířit na AND na tento rozsah, a pokud není postgres
pitomý, mohlo by to pomoci při předfiltrování zpráv podle indexu, na které
následně použije tvrdou podmínku.

A tyto rozsahy by se daly použít i jako předpočítaný fallback pro
zobrazení na webu, když je adres moc.

Ad 3 podruhé: Nevejde se nám do paměti současně index a DB. Ve
skutečnosti máme ale úrovně indexů dvě: skutečné databázové indexya tabuli s
vytaženými daty, která je pro nás forma indexu, a pak skutečná JSONová data.
Nepomohlo by vytáhnout JSONová data do vlastní tabule a nechat prohledávací
tabuli bez nich? Pokud v ní jsou veškerá data, potřebná pro prohledávací
dotazy, dotazů na JSON data by mohlo být minimum - raw (JSON) data
potřebujeme jen pro zobrazení 100 položek výsledků hledání nebo pro
reporter.
Pak by paměť mohla stačit na indexy + prohledávací tabuli, a zřídka
zobrazovaný JSON by mohl kromě právě potřebných stovek smrdět na disku.

Actions #2

Updated by Pavel Kácha over 5 years ago

Note: Moved from email. Continuation in english, please.

Actions #3

Updated by Pavel Kácha over 5 years ago

  • Related to Bug #4261: Shorten events/search output in case of too long events added
Actions #4

Updated by Radko Krkoš over 5 years ago

Ad 3 podruhé: Nevejde se nám do paměti současně index a DB. Ve
skutečnosti máme ale úrovně indexů dvě: skutečné databázové indexya tabuli s
vytaženými daty, která je pro nás forma indexu, a pak skutečná JSONová data.
Nepomohlo by vytáhnout JSONová data do vlastní tabule a nechat prohledávací
tabuli bez nich? Pokud v ní jsou veškerá data, potřebná pro prohledávací
dotazy, dotazů na JSON data by mohlo být minimum - raw (JSON) data
potřebujeme jen pro zobrazení 100 položek výsledků hledání nebo pro
reporter.
Pak by paměť mohla stačit na indexy + prohledávací tabuli, a zřídka
zobrazovaný JSON by mohl kromě právě potřebných stovek smrdět na disku.

Original design using a single table for both event metadata and details was based on an assumption of average event record size of ~10kB. This is no longer true as there are isolated event records of ~250kB. Furthermore, average record size is expected to rise considerably as there are multiple sources providing more aggressively aggregated data and this trend will continue with no foreseeable upper limit.
Next, event data was designed to be stored as searchable JSON what proved impractical because of DB limitations (inability to represent NULL byte inside JSON). This was to allow searching on both metadata and event data, but was never used in the end.
Based on these a storage format optimization, as proposed by Pavel Kácha above, is in order. The event metadata table should be stripped of the event bytea column containing encoded JSON event data. The event data should be stored in a different table also containing event id as the PRIMARY KEY (with index, also FOREIGN KEY with ON DELETE CASCADE to make existing event purging code work with no change). This would require slight changes on import and a transition operation but no changes for event search (and only table name change for event detail display). The downsides are that event data would no longer be cached in memory leading to longer event detail display times (with low impact as this is a much rarer operation than originally expected) and a duplication of the event id index (6GB in size, largest of all). A huge advantage are better scaling with event record size (constant for typical event) and better scaling with total number of events stored (as for good performance the events table and its indices should fit into memory).

Actions #5

Updated by Pavel Kácha over 5 years ago

Radko Krkoš wrote:

Based on these a storage format optimization, as proposed by Pavel Kácha above, is in order. The event metadata table should be stripped of the event bytea column containing encoded JSON event data. The event data should be stored in a different table also containing event id as the PRIMARY KEY (with index, also FOREIGN KEY with ON DELETE CASCADE to make existing event purging code work with no change). This would require slight changes on import and a transition operation but no changes for event search (and only table name change for event detail display). The downsides are that event data would no longer be cached in memory leading to longer event detail display times (with low impact as this is a much rarer operation than originally expected) and a duplication of the event id index (6GB in size, largest of all). A huge advantage are better scaling with event record size (constant for typical event) and better scaling with total number of events stored (as for good performance the events table and its indices should fit into memory).

This has been partially discussed with Mek already, with regard to needed code changes. We'll need:

  1. API change, to return incomplete/lightweight/stripped Idea events, constructed only from main table data (so lacking lot of info in original JSON). No JSON conversion would thus be needed, only setting up simple nested dict from result of SELECT *. Filtering done in application (not in db) would thus remain working.
  2. API change to allow to enhance/convert stripped events to full format from related db (meant for small event/show and for reporter)

Small question remains - what does ip range type, which is now used for arrays of source/target IPs return in python? What conversions will be needed here?

Actions #6

Updated by Radko Krkoš over 5 years ago

Pavel Kácha wrote:

Small question remains - what does ip range type, which is now used for arrays of source/target IPs return in python? What conversions will be needed here?

As discussed in teleconference, iprange types are returned as string representations in single address, prefix or arbitrary range (min-max) forms (best match). This is because iprange is a nonstandard extension and the standard connector does not understand its data type. Anyways, there is no native/standard library data type that would fit iprange (not the arbitrary range part at least).

Actions #7

Updated by Pavel Kácha over 5 years ago

  • Related to Feature #4273: Consider/choose/implement different communication protocol added
Actions #8

Updated by Pavel Kácha over 5 years ago

  • Related to Feature #4274: Minimize whole JSON IDEA events usage (jsonb column) added
Actions #9

Updated by Pavel Kácha over 5 years ago

  • Related to Feature #4275: Split jsonb column into its own table added
Actions #10

Updated by Pavel Kácha about 4 years ago

  • Status changed from New to Closed

Seems to me we are done here in all important related tickets (save for communication overhead, which is for Future and not a showstopper for this bug.) All the low(er) hanging fruit was addressed. Thanks everybody for help.
Closing.

Actions #11

Updated by Jan Mach about 4 years ago

  • Target version changed from Backlog to 2.6
Actions

Also available in: Atom PDF