Implementacni poznamky¶
- Table of contents
- Implementacni poznamky
Struktura Warden databaze pro warden-server-2.2¶
Tabulka 'clients' +--------------------+--------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------------+--------------+------+-----+---------------------+----------------+ | client_id | int(11) | NO | PRI | NULL | auto_increment | | hostname | varchar(256) | YES | | NULL | | | registered | timestamp | NO | | 0000-00-00 00:00:00 | | | requestor | varchar(256) | YES | | NULL | | | service | varchar(64) | YES | | NULL | | | client_type | varchar(1) | YES | | NULL | | | type | varchar(64) | YES | | NULL | | | receive_own_events | varchar(1) | YES | | NULL | | | description_tags | varchar(256) | YES | | NULL | | | ip_net_client | varchar(256) | YES | | NULL | | | valid | varchar(1) | YES | | NULL | | +--------------------+--------------+------+-----+---------------------+----------------+ Tabulka 'events' +--------------+-----------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------------+------+-----+---------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | detected | timestamp | NO | | 0000-00-00 00:00:00 | | | received | timestamp | NO | | 0000-00-00 00:00:00 | | | type | varchar(64) | YES | | NULL | | | source_type | varchar(64) | YES | | NULL | | | source | varchar(256) | YES | | NULL | | | target_proto | varchar(16) | YES | | NULL | | | target_port | int(2) unsigned | YES | | NULL | | | attack_scale | int(4) unsigned | YES | | NULL | | | note | text | YES | | NULL | | | priority | int(1) unsigned | YES | | NULL | | | timeout | int(2) unsigned | YES | | NULL | | | valid | varchar(1) | YES | | NULL | | | client_id | int(11) | YES | | NULL | | +--------------+-----------------+------+-----+---------------------+----------------+
Vyvoj funkcionality¶
Typy Subject Alternate Names v SSL certifikatu:¶
#define GEN_OTHERNAME 0 #define GEN_EMAIL 1 #define GEN_DNS 2 #define GEN_X400 3 #define GEN_DIRNAME 4 #define GEN_EDIPARTY 5 #define GEN_URI 6 #define GEN_IPADD 7 #define GEN_RID 8
Odmazavani databaze¶
- /opt/warden-server/bin/warden-server.pl
our $MAX_DB_SIZE = undef; our $LWM = undef; . . . #------------------------------------------------------------------------------- # vacuumDb - start vacuum process in SQLite database #------------------------------------------------------------------------------- sub vacuumDb { local $DBH->{AutoCommit} = 1; $DBH->do('VACUUM'); return; } #------------------------------------------------------------------------------- # cleanDb - delete old received events from table 'events' after exceed of # $MAX_DB_SIZE #------------------------------------------------------------------------------- sub cleanDb { my $db = shift; my $db_size_human = shift; my $db_size_bytes = shift; my $max_db_size_bytes = shift; my $lwm_bytes = ($max_db_size_bytes / 100) * $LWM; my ($sth, $last_date, $last_timestamp, $delete_threshold_db, $db_size_bytes_old, $sum_deleted_bytes); write2log("info", "Starting cleanup of DB => DB_SIZE: $db_size_human ($db_size_bytes bytes), MAX_DB_SIZE: $MAX_DB_SIZE" . "MB ($max_db_size_bytes bytes), LWM: $LWM" . "% ($lwm_bytes bytes)"); LOOP: { do { # obtain timestamp of last received event $sth = $DBH->prepare("SELECT received FROM events WHERE id = (SELECT min(id) FROM events);"); if ( !defined $sth ) {die("Cannot prepare statement in cleanDb: $DBI::errstr\n")} $sth->execute; $last_timestamp = $sth->fetchrow(); # prepare threshold for deletion last LOOP if !defined $last_timestamp; # break if $last_timestamp is not defined => DB is empty $last_date = substr($last_timestamp,0,10); # only 2012-01-16 from 2012-01-16T13:44:45 $delete_threshold_db = $DBH->quote($last_date . "T23:59:59"); # delete events latest than $delete_threshold $DBH->do("DELETE FROM events WHERE received <= $delete_threshold_db;"); if ($DBH->err()) {die("Cannot do delete statement in cleanDb: $DBI::errstr\n")} $DBH->commit(); vacuumDb; # obtain new DB size and sum of deleted bytes $db_size_bytes_old = $db_size_bytes; $db_size_bytes = -s $db; $sum_deleted_bytes = $db_size_bytes_old - $db_size_bytes; write2log("info", "$last_date ($sum_deleted_bytes bytes) was deleted; DB size: $db_size_bytes bytes;"); } while ($db_size_bytes >= $lwm_bytes); } $db_size_human = Format::Human::Bytes::base10(-s $db); write2log("info", "Stopping cleanup of DB => DB_SIZE: $db_size_human ($db_size_bytes bytes), MAX_DB_SIZE: $MAX_DB_SIZE" . "MB ($max_db_size_bytes bytes), LWM: $LWM" . "% ($lwm_bytes bytes)"); } # End of cleanDb . . . # check if size of DB file exceed $MAX_DB_SIZE #my $db_size_bytes = -s $db; #my $max_db_size_bytes = $MAX_DB_SIZE * 1024 * 1024; #if ($db_size_bytes >= $max_db_size_bytes) { cleanDb($db, $db_size_human, $db_size_bytes, $max_db_size_bytes) }
- /opt/warden-server/etc/warden-server.conf
#------------------------------------------------------------------------------- # MAX_DB_SIZE - maximal size of database file (in MB) #------------------------------------------------------------------------------- $MAX_DB_SIZE = 790; #------------------------------------------------------------------------------- # LWM - delete received events from table 'events' until size of database # file = $LWM % of $MAX_DB_SIZE; typically 90 #------------------------------------------------------------------------------- $LWM = 90;
Poznamky¶
- SQLite
- Mini HOWTO - http://defindit.com/readme_files/sqlite.html
- Mini HOWTO - http://www.perlmonks.org/?node_id=619077
- Cooking with Perl - http://www.perl.com/pub/2003/09/03/perlcookbook.html
- DROP DATABASE - http://www.devdaily.com/android/sqlite-drop-database-how
- Priklad prace s SQLite v Perlu, Pythonu a BASH - http://mailliststock.wordpress.com/2007/03/01/sqlite-examples-with-bash-perl-and-python/
- Ukladani IP v SQLite - http://stackoverflow.com/questions/4448284/sqlite3-integer-max-value
- SQLite3 datove typy - http://www.sqlite.org/datatype3.html
- SQLite Time format - http://stackoverflow.com/questions/2930768/how-to-compare-sqlite-timestamp-values
- Problem s rozdili mezi verzemi perl-DBI a shell interpreteru http://threebit.net/mail-archive/trac/msg00613.html
- Autoinkrement - http://www.sqlite.org/faq.html#q1
- SQLite3 Integer Max Value http://stackoverflow.com/questions/4448284/sqlite3-integer-max-value
- http://guide.soaplite.com/
- http://perldoc.net/SOAP/Data/ComplexType.pm - konstanty a prace s objekty
- http://search.cpan.org/~mkutter/SOAP-Lite-0.712/lib/SOAP/SOM.pod
- http://search.cpan.org/~mkutter/SOAP-Lite-0.712/lib/SOAP/Data.pod
- http://www.herongyang.com/WSDL/Perl-SOAP-Lite-0710-Deserializer-XML-to-Data-Object.html
- http://sldn.softlayer.com/article/Implementing-SOAP-Perl
- http://users.skynet.be/pascalbotte/rcx-ws-doc/perldotnet.htm
Prenasene XML schema¶
- XML schema pro zaslani informaci o udalostech ve wardenu za pouziti name->value(\name->)
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getNewEventsResponse xmlns="http://localhost/Warden"> <event> <Id xsi:type="xsd:int">1</Id> <Time xsi:type="xsd:string">2011-01-01-0100</Time> <IP xsi:type="xsd:string">10.0.0.1</IP> <Type xsi:type="xsd:string">scan</Type> </event> <event> <Id xsi:type="xsd:int">2</Id> <Time xsi:type="xsd:string">2012-02-02-0200</Time> <IP xsi:type="xsd:string">10.0.0.2</IP> <Type xsi:type="xsd:string">spam</Type> </event> </getNewEventsResponse> </soap:Body> </soap:Envelope>
- XML schema pro zaslani informaci o udalostech ve wardenu za pouziti atributu
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <getNewEventsResponse xmlns="http://localhost/Warden"> <warden:id xsi:type="xsd:int" xmlns:TYPE="urn:scan" xmlns:TIME="urn:2011-01-01-0100" xmlns:IP="urn:10.0.0.1">1</warden:id> <warden:id xsi:type="xsd:int" xmlns:TYPE="urn:spam" xmlns:TIME="urn:2012-02-02-0200" xmlns:IP="urn:10.0.0.2">2</warden:id> </getNewEventsResponse> </soap:Body> </soap:Envelope>
Poznatky o odmazavani databaze SQLite¶
- pro periodicke odmazavani databaze jsem pouzil algoritmus, ktery:
- zacal odmazavat udalosti z DB po dosazeni nastavene maximalni velikosti db v promenne $max_db_size
- odmazavani skoncilo v okamzik, kdy aktualni velikost databaze $current_db_size <= hodnote promenne $low_water_mark, ktera by nastavena na 90% (90% z $max_db_size)
- z databaze byly odmazany udalosti vzdy po 1 dni
- z DB byla vzdy odmazana posledni udalost v DB spolecne se vsemi, ktere prisly na warden server ve stejny den
- z casu prijeti posledni udalosti, napr. 2012-01-16T13:44:45 se vzala cast 2012-01-16 a udalosti, ktere prisly v tento den byly take smazany
- z DB byla vzdy odmazana posledni udalost v DB spolecne se vsemi, ktere prisly na warden server ve stejny den
- po odmazani dostatecneho mnozstvi udalosti byl spusten prikaz vacuum, ktery skutecne data z databaze smazal
- zde jsem narazil na problem, jelikoz beh vaccum na vetsi DB (na DB ve ktere se odmazalo vice dat) trval nekolik minut
- zkousel jsem i odhadovat cas, ktery vaccum spotrebuje, nicmene tento pristup se neosvedcil, jelikoz kazdy zaznam v DB ma jinou velikost
- pro tento algoritmus by bylo lepsi kdyby warden jel na databazi umoznujici partitioning (PostgreSQL), jelikoz by bylo mozne odmazavat data po partitionach o velikosti napr. 1 den *
- dale, pokud se nepletu, tak vaccum v PostgreSQL nezamyka tabulku a je tedy mozne s ni pracovat i po dobu behu vacuua