Здравствуйте! Мне нужно написать модуль альтератора для учёта трафика в рамках Office Server. Оцените идею, кто в теме. Наиболее простым кажется использовать ulogd и sqlite, поскольку это самодостаточные пакеты, и между ними не требуется прослойки. Так что я добавил правила: # iptables --insert INPUT -j ULOG --ulog-nlgroup 1 --ulog-cprange 48 --ulog-qthreshold 50 --ulog-prefix "icount" # iptables --insert OUTPUT -j ULOG --ulog-nlgroup 1 --ulog-cprange 48 --ulog-qthreshold 50 --ulog-prefix "ocount" # iptables --insert FORWARD -j ULOG --ulog-nlgroup 1 --ulog-cprange 48 --ulog-qthreshold 50 --ulog-prefix "fcount" и настроил ulogd-sqlite3 на /var/lib/ulogd/sqlite3.db Всё бы хорошо, но пакетов приходит много, база растёт, а потенциальные пользователи Office Server вряд ли будут за ней следить и чистить. Поэтому я внёс дополнения в схему базы (cм. ниже). При вставке (INSERT) новой строки длина пакета триггером добавляется к суточному счётчику (в соответствии с протоколом, IP, портами и пр.), а строка тут же удаляется. Счётчик сначала пытается вставиться (INSERT OR IGNORE - если уже есть, молча идём дальше) в суточную таблицу (ulog_daily), а затем увеличивается на длину пакета UPDATE-ом. Поскольку в альтераторе не будет подробных сведений, время округляется до суток. По ulog_daily строится индекс для скорейшего поиска. Входной/выходной интерфейсы, порты tcp/udp при вставке в ulog_daily складываются, поскольку одновременно используется только один из пары. Ввод такой схемы даёт 16-кратную экономию места, при том, что скорость падает примерно в 4 раза: дамп на 360 тысяч строк залился чуть больше, чем за минуту (на Athlon 64 X2 3600) против 15 секунд по старой схеме. Мне кажется, это приемлимо. Покритикуйте, если я что-нибудь упустил. --- >8 --- CREATE TABLE ulog ( raw_mac VARCHAR(80), oob_time_sec INT UNSIGNED, oob_time_usec INT UNSIGNED, oob_prefix VARCHAR(32), oob_in VARCHAR(32), oob_out VARCHAR(32), ip_saddr VARCHAR(16), ip_daddr VARCHAR(16), ip_protocol TINYINT UNSIGNED, ip_totlen SMALLINT UNSIGNED, tcp_sport SMALLINT UNSIGNED, tcp_dport SMALLINT UNSIGNED, udp_sport SMALLINT UNSIGNED, udp_dport SMALLINT UNSIGNED, udp_len SMALLINT UNSIGNED, icmp_type TINYINT UNSIGNED, icmp_code TINYINT UNSIGNED, icmp_echoid SMALLINT UNSIGNED, icmp_echoseq SMALLINT UNSIGNED, icmp_gateway INT UNSIGNED, icmp_fragmtu SMALLINT UNSIGNED ); CREATE TABLE ulog_daily ( time INT UNSIGNED, prefix VARCHAR(32), iface VARCHAR(32), saddr VARCHAR(16), daddr VARCHAR(16), protocol TINYINT UNSIGNED, sport SMALLINT UNSIGNED, dport SMALLINT UNSIGNED, bytes INTEGER ); CREATE UNIQUE INDEX ulog_daily_idx ON ulog_daily (time, prefix, iface, saddr, daddr, protocol, sport, dport); CREATE TRIGGER aggregate AFTER INSERT ON ulog BEGIN INSERT OR IGNORE INTO ulog_daily ( time, prefix, iface, saddr, daddr, protocol, sport, dport, bytes ) values ( NEW.oob_time_sec/86400*86400, NEW.oob_prefix, NEW.oob_in || NEW.oob_out, NEW.ip_saddr, NEW.ip_daddr, NEW.ip_protocol, ifnull (NEW.tcp_sport, 0) + ifnull (NEW.udp_sport, 0), ifnull (NEW.tcp_dport, 0) + ifnull (NEW.udp_dport, 0), 0 ); UPDATE ulog_daily SET bytes = bytes + NEW.ip_totlen WHERE time = NEW.oob_time_sec/86400*86400 AND prefix = NEW.oob_prefix AND iface = NEW.oob_in || NEW.oob_out AND saddr = NEW.ip_saddr AND daddr = NEW.ip_daddr AND protocol = NEW.ip_protocol AND sport = ifnull (NEW.tcp_sport, 0) + ifnull (NEW.udp_sport, 0) AND dport = ifnull (NEW.tcp_dport, 0) + ifnull (NEW.udp_dport, 0); DELETE from ulog WHERE ROWID = NEW.ROWID; END; -- Grigory Batalov, ALT Linux Team