Ключевые слова: Х-терминал, linux, LTSP, Linux Terminal Server Project, терминальный linux-сервер, бездисковая станция, ПК без жесткого диска, использование старых компьютеров, diskless workstation, thin client, asplinux, использование Linux в офисе, X-terminal
Локальная сеть для Х-терминальной среды – это своего рода магистраль, которая соединяет все компьютеры в одно целое, если на каком либо из ее участков случается авария, то это сказывается на работе всей системы. Для управления локальной сетью предназначен даже специальный протокол SNMP (Simple Network Management Protocol – простой протокол управления сетью), который поддерживается практически всеми маршрутизаторами. Для работы с данным протоколом в операционной системе Linux существует специальный демон – smnpd. Кроме этого, существует еще довольно много способов учета сетевой статистики, которые можно использовать в своей работе. Также много и специального программного обеспечения, которое используется в этих целях. Одной из таких программ является MRTG (Multi Router Traffic Grapher), найти которую можно на ее официальном сайте http://www.mrtg.org.
Для тех пользователей, которые любят делать все своими руками, и при этом полностью контролировать процесс, я предлагаю построить простую систему учета трафика между Х-терминалами и Х-терминал сервером. При этом в своей работе мы воспользуемся программой iptables. Ну что ж, приступим.
Для начала нужно создать разрешающие правила для всех IP-адресов Х-терминалов, причем как на входящие (цепочка INPUT), так и исходящие пакеты (цепочка OUTPUT). Для этого можно воспользоваться таким простым сценарием:
#!/bin/sh
iptables='/sbin/iptables'
echo 'Creating chaines for IP-accounting'
term_list='192.168.1.3 192.168.1.6 192.168.1.8
192.168.1.13 192.168.1.14 192.168.1.15
192.168.1.16 192.168.1.18 192.168.1.23 '
# Удаление всех cуществующих цепочек
$iptables -F
# Цикл по всем цепочкам
for term_ip in $term_list
do
echo "Chain for IP: $term_ip"
$iptables -A OUTPUT -d $term_ip -j ACCEPT
$iptables -A INPUT -s $term_ip -j ACCEPT
done
echo "Done."
В приведенном выше примере в переменной term_list содержится список IP-адресов Х-терминалов, за которыми ведется наблюдение. После запуска этого сценария (файл create_rip.sh) на экране должен быть такой вывод:
# ./create_rip.sh
Creating chaines for IP-accounting
Chain for IP: 192.168.1.3
Chain for IP: 192.168.1.6
Chain for IP: 192.168.1.8
Chain for IP: 192.168.1.13
Chain for IP: 192.168.1.14
Chain for IP: 192.168.1.15
Chain for IP: 192.168.1.16
Chain for IP: 192.168.1.18
Chain for IP: 192.168.1.23
Done.
Чтобы убедится в том, что цепочки установлены и работают правильно, следует от имени суперпользователя выполнить такую команду:
# /sbin/iptables -L -v -n
Chain INPUT (policy ACCEPT 121 packets, 10353 bytes)
pkts bytes target prot opt in out source destination
670 43744 ACCEPT all -- * * 192.168.1.3 0.0.0.0/0
0 0 ACCEPT all -- * * 192.168.1.6 0.0.0.0/0
741 47400 ACCEPT all -- * * 192.168.1.8 0.0.0.0/0
768 48836 ACCEPT all -- * * 192.168.1.13 0.0.0.0/0
1432 134K ACCEPT all -- * * 192.168.1.14 0.0.0.0/0
348 26960 ACCEPT all -- * * 192.168.1.15 0.0.0.0/0
765 48548 ACCEPT all -- * * 192.168.1.16 0.0.0.0/0
1064 70768 ACCEPT all -- * * 192.168.1.18 0.0.0.0/0
1071 97572 ACCEPT all -- * * 192.168.1.23 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 16084 packets, 5230K bytes)
pkts bytes target prot opt in out source destination
45898 27M ACCEPT all -- * * 0.0.0.0/0 192.168.1.3
0 0 ACCEPT all -- * * 0.0.0.0/0 192.168.1.6
32880 16M ACCEPT all -- * * 0.0.0.0/0 192.168.1.8
57530 33M ACCEPT all -- * * 0.0.0.0/0 192.168.1.13
41469 19M ACCEPT all -- * * 0.0.0.0/0 192.168.1.14
32495 21M ACCEPT all -- * * 0.0.0.0/0 192.168.1.15
32172 17M ACCEPT all -- * * 0.0.0.0/0 192.168.1.16
90640 47M ACCEPT all -- * * 0.0.0.0/0 192.168.1.18
65262 30M ACCEPT all -- * * 0.0.0.0/0 192.168.1.23
У себя вы должны получить похожие результаты. Особое внимание обратите на столбцы с именами "pkts" и "bytes" - они показывают количество и суммарный размер переданных пакетов в цепочке. Интересно, но с помощью iptables можно сразу узнать какие Х-терминалы не работают (выключены), так как их счетчики содержат нулевые значения (в примере это Х-терминал с IP-адресом 192.168.1.6). Особое внимание следует обратить на отсутствие правил для пересылаемого трафика FORWARD. Это связано с тем, что общение Х-терминалов с сервером идет по довольно простой схеме и надобность в пересылке пакетов на другие другие узлы локальной сети отсутствует. Очень часто программным брандмауэром вообще запрещена пересылка пакетов для сервера Х-терминалов:
$ cat /proc/sys/net/ipv4/ip_forward
0
Важно также помнить, что отсутствие возможности пересылки пакетов отнюдь не мешает использовать ресурсы глобальной компьютерной сети пользователям Х-терминалов. Это становится возможным благодаря тому, что программы пользователей непосредственно выполняются на сервере Х-терминалов, который имеет подключение к Интернет.
Но вернемся к анализу использования сетевого трафика Х-терминалами. Метод учета статистики использования локальной сети заключается в том, чтобы через равные промежутки времени получать значения счетчиков iptables и сохранять их в файле. Примером сценария, предназначенного для этих целей, может быть сценарий, написанный на языке Perl (имя файла acc_ips.pl), текст которого приведен ниже:
#!/usr/bin/perl -w
# - - - - - - - - - - - - - - - - - - - - - -
# Сценарий для учета статистики использования
# локальной сети Х-терминалами
# - - - - - - - - - - - - - - - - - - - - - -
use strict;
use POSIX;
my $log_dir = '/var/log/ip_acc/';
my $fip_stat = $log_dir.'ip_comm_stat.txt';
my $fip_log = $log_dir.'ip_stat.log';
my $iptables = '/sbin/iptables';
my %stat = ();
# Считать информацию из файла со счетчиками
if ( open (FSLOAD, "<$fip_stat") ) {
while () {
chomp;
my ($ip, $t_input, $ti_count, $t_output, $to_count) = split /\s/;
${$stat{$ip}}{total_input}=$t_input;
${$stat{$ip}}{total_icount}=$ti_count;
${$stat{$ip}}{total_output}=$t_output;
${$stat{$ip}}{total_ocount}=$to_count;
}
close (FSLOAD);
} else { `touch $fip_stat` }
# Обнулить счетчики INPUT и одновременно показать их значения
my @input_counters = `$iptables -L -v -n -x -Z INPUT`;
for (@input_counters) {
next if (/INPUT|target/); # пропустить неинформативные строки
my ($bytes, $ip) = ( split ) [1,7];
${ $stat{$ip} }{input} = $bytes;
${ $stat{$ip} }{input_count} = ($bytes) ? 1 : 0;
}
# Обнулить счетчики OUTPUT
my @output_counters = `$iptables -L -v -n -x -Z OUTPUT`;
for (@output_counters) {
next if (/OUTPUT|target/); # пропустить неинформативные строки
my ($bytes, $ip) = ( split ) [1,8];
${$stat{$ip}}{output} = $bytes;
${$stat{$ip}}{output_count} = ($bytes) ? 1 : 0;
}
# Подсчет статистики
for (keys %stat) {
my $href = $stat{$_};
${$href}{total_input} += ${$href}{input};
${$href}{total_output} += ${$href}{output};
${$href}{total_icount} += ${$href}{input_count};
${$href}{total_ocount} += ${$href}{output_count};
}
# Сохранить данные в файлах
my @log_data = ();
push @log_data, strftime ("%Y-%m-%d %H:%M:%S", localtime());
open (FSSAVE, ">$fip_stat") or die "Cant save stat file $!\n";
for (sort keys %stat) {
my $href = $stat{$_};
print FSSAVE join("\t", ($_, ${$href}{total_input}), ${$href}{total_icount},
${$href}{total_output}, ${$href}{total_ocount}), "\n";
push @log_data, ${$href}{input}, ${$href}{output};
}
close (FSSAVE);
unless (-f $fip_log) {
my $header = '"Date Time ' . join (' ', sort keys %stat) .'"';
`echo $header > $fip_log`
}
open (FLSAVE, ">>$fip_log") or die "Cant save log file $!\n";
print FLSAVE join(" ", @log_data), "\n";
close (FLSAVE);