Стимулирайте трафик в Linux
Няма да настроим sendmail, нито ще се караме на идеята на Били, но ще се опитаме да създадем нещо като таксуване, т.к. този въпрос рано или късно възниква пред почти всички системни администратори.
Статията е насочена към начинаещи в администрацията и опитни специалисти едва ли ще представляват интерес. И така, какво имаме? Мрежа от 50-200 компютъра, специален интернет канал (ADSL, Ethernet и др.), linux рутер. Необходимо е да се преброи интернет трафикът на потребителите (в различни посоки), да се ограничи скоростта и да се определят ограниченията на трафика на месец. Освен това искам да управлявам всичко това чрез някаква уеб муцуна.
Нека вземем за основа дистрибуцията на ubuntu-server 8.04.
Ще изпълняваме почти всички действия в конзолата като root, така че за да не пишем sudo всеки път, пишем:
Настройка на PPTP сървър
# apt-get инсталирате pptpd
Отворете конфигурацията /etc/pptpd.conf и добавете редовете:
# Тайни за удостоверяване с помощта на CHAP # тайни IP адреси на клиент сървър user1 pptpd 123 10.1.0.2 user2 pptpd 567 10.1.0.3
Рестартиране на услугата pptpd:
Разрешаване на връзки към нашата услуга:
# iptables -A INPUT -s 192.168.0.0/24 -p tcp -m състояние --state НОВО -m tcp --dport 1723 -j ПРИЕМАНЕ
Настройка на ulog-acctd
# apt-get install ulog-acctd
Отворете конфигурацията /etc/ulog-acctd.conf. Интересуваме се от счетоводния формат и параметрите на fdelay.
# време изпращач получател трафик accounting format="%t\t%s\t%d\t%b\n"
Параметърът fdelay определя след какъв период от време ulog-acctd ще изхвърли натрупаната статистика в дневника, задайте го на 10 секунди.
Настройка на iptables
# iptables -t nat -AПОСТРУТИРАНЕ -s 10.1.0.0/24 -j МАСКАРАД
С това правило казваме на ulog какъв трафик да регистрира:
# iptables -A НАПРЕД -d 10.1.0.0/24 -j ULOG --ulog-cprange 48 --ulog-qthreshold 50
Интересуваме се от транзитен трафик към VPN мрежата.
Сега нека тестваме получения пакет, свържете се с мрежата и опитайте да изтеглите нещо, следните записи трябва да се появят в регистрационния файл /var/log/ulog-acctd/account.log:
1224187495 208.67.222.222 10.1.0.2126 1224187594 205.188.9.192 10.1.0.2 40 1224187599 62.213.122.2 10.1.0.2 22130 1224187615 62.213.122.2 10.1.0.2 1037 .
MySQL и схема на база данни
# apt-get инсталирайте mysql-сървър
Създайте потребителски ulog на MySQL и импортирайте схема на база данни:
CREATE DATABASE `ulogdb` DEFAULT CHARSET utf8;
CREATE TABLE `data` ( `id` int(11) NOT NULL auto_increment, `id_user` int(11) NOT NULL, `ts` int(11) NOT NULL, `bytes` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CH ARSET utf8;
CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `login` varchar(32) NOT NULL, `password` varchar(64) NOT NULL, `ip` varchar(15) NOT NULL, PRIMARY KEY (`id`), KEY `ip` (`ip`) ) ENGINE=MyISAM DEFAULT CHARSET utf8;
Това е опростена диаграма, ще я модернизираме по-късно. В таблицата с данни ние съхраняваме обобщена статистика за трафика, в потребителите информация за потребителите. Добавете потребителите, посочени в /etc/ppp/chap-secrets, към таблицата с потребители.
INSERT INTO `users` (`login`, `password`, `ip`) VALUES ('user1', '123', '10.1.0.2'); INSERT INTO `users` (`login`, `password`, `ip`) VALUES ('user2', '567', '10.1.0.3');
парсим дневник
# apt-get инсталирайте libdbd-mysql-perl
Ето пълния текст на скрипта:
# дефинирайте името на базата данни, потребителя и паролата my $db_name = "ulogdb"; my $db_user = "ulog"; моят $db_pass = "1234";
# път към лог файла $account_log = "/var/log/ulog-acctd/account.log";
# свържете се с нашата база данни my $DBH = DBI->connect("DBI:mysql:$db_name:localhost",$db_user,$db_pass) или умрете "Грешка при свързване с база данни";
# вземете списък с потребители в ip+id_user my $STH = $DBH->prepare("изберете ip,id от потребители"); $STH->изпълни; while (@tmp = $STH->fetchrow_array()) $users = $tmp[1]; > $STH->финиш;
# направете временно копие на дневника и изчистете оригиналния файл system "cp $account_log /tmp/ulog-parser.tmp && cat /dev/null > $account_log"; отворете LOGFILE," ) chomp;
# все още не използвайте променливата $saddr, # тя ще ви бъде полезна по-късно
($ts,$saddr,$daddr,$bytes) = разделяне /\t/;
# създайте ново времево клеймо, необходимо за агрегиране на # потребителски статистики за определен интервал от време # в един запис. интервалът ще бъде 1 минута.
# сравнете ip от дневника със списъка на потребителите # ако ip е в базата данни - нашият клиент # масив със статистика има дървовидна структура: # timestamp -> потребителско име -> получен трафик
# подготовка на заявки за база данни my $STH_CHK = $DBH->prepare("select > my $STH_ADD = $DBH->prepare("вмъкване в данни (id_user,ts,bytes) values(. )"); my $STH_UPD = $DBH->prepare("актуализиране на набор от данни bytes=bytes+? where > # преминаване през целия масив от статистики във вложен цикъл # за $ts (ключове %data) # проверка дали базата данни съдържа записи с такова времево клеймо $STH_CHK->изпълни($ts); %ex_data = (); while (@tmp = $STH_CHK->fetchrow_array()) $ex_data = $tmp[1]; > $STH_CHK->финиш;
# изберете данни за потребителите в текущия период за $id_user (ключове %>) if (exists($ex_data)) # ако записът вече съществува, тогава просто актуализирайте стойността на байтовото поле $STH_UPD->execute($data,$ex_data); $STH_UPD->финиш; > else # в противен случай добавете нов запис $STH_ADD->execute($id_user,$ts,$data); $STH_ADD->финиш; > > > # прекъсване на връзката с базата данни $DBH->disconnect;
Запишете скрипта като /usr/bin/ulog-parser.pl и задайте атрибутите:
# chmod 700 /usr/bin/ulog-parser.pl
Опитваме се да стартираме и да видим дали данните са се появили в таблицата data:
С минимални познания по PHP и SQL, няма да е трудно да изготвите статистика;)
P.S.: Благодаря на ISVir и thestorm за кармата. Първи пост.
И тук можете да получите грант за тестов период на Yandex.Cloud. Необходимо е само да въведете "Habr" в полето "секретна парола".