[devel] Учёт трафика (ulogd + sqlite)

Grigory Batalov =?iso-8859-1?q?bga_=CE=C1_altlinux=2Eorg?=
Сб Ноя 24 17:26:39 MSK 2007


  Здравствуйте!

  Мне нужно написать модуль альтератора для учёта трафика в рамках
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
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип     : application/pgp-signature
Размер  : 189 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url     : <http://lists.altlinux.org/pipermail/devel/attachments/20071124/a5b73bc6/attachment-0002.bin>


Подробная информация о списке рассылки Devel