пятница, 24 февраля 2012 г.

Совмещение таблиц bcc и alias в Postfix

Продолжаю потихоньку совершенствовать свою почтовую систему, параллельно разрабатывая веб-интерфейс для управления всем этим хозяйством. Этот пост по сути носит лишь отчётный характер и не предназначен для внедрения кем бы то ни было в практику. С другой стороны, знающие люди могут заинтересоваться описанными здесь идеями и реализовать нечто подобное у себя.

Месяца два назад аккуратно поэкспериментировал с таблицей virtual_alias_maps и обнаружил, что в случае, если запрос для одного псевдонима возвращает два адреса, Postfix отправляет письмо на оба адреса.

Таким образом можно делать рассылки штатными средствами самого Postfix. Можно добавить в таблицу псевдонимов несколько записей с одинаковым псевдонимом, но с разными получателями и получить простейший список рассылки.

Потом я подумал о том, что между такой рассылкой и копированием входящей почты нескольким адресатам фактически нет никакой разницы. Разница только лишь в том, куда подставлена эта карта - в recipient_bcc_maps или в virtual_alias_maps. Потом я подумал о том, что обе функции можно объединить в одной таблице, если учитывать существование адреса в таблице пользователей и статус этого пользователя - включен или отключен. Если пользователь включен, то он должен получить своё письмо в свой ящик, а вместе с ним все те, кто подписан на его входящую почту - это поведение для recipient_bcc_maps. Если пользователь отключен или он не существует, то почту должны получить лишь те, кто подписан на входящую почту этого адреса - это поведение virtual_alias_maps. Добавим в таблицу ещё дополнительную колонку, которая позволит отличать подписку на исходящую почту и входящую почту и получим совмещённую таблицу алиасов, подписок, пересылок и скрытых копий входящей и исходящей почты.

Вот и запрос для создания соответствующей таблицы:
CREATE TABLE `subscription` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `direction` varchar(1) NOT NULL default 'I',
  `email` varchar(255) character set latin1 NOT NULL,
  `recipient` varchar(255) character set latin1 NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `subscription` (`direction`,`email`,`recipient`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Запрос для создания таблицы пользователей/ящиков у меня выглядит так:
CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `active` varchar(1) default 'Y',
  `email` varchar(255) character set latin1 NOT NULL,
  `password` varchar(255) character set latin1 NOT NULL default '',
  `surname` varchar(255) NOT NULL default '',
  `name` varchar(255) NOT NULL default '',
  `patronym` varchar(255) NOT NULL default '',
  `lastip` varchar(32) default NULL,
  `lasttime` datetime default NULL,
  `bytes` bigint(20) default NULL,
  `messages` int(11) default NULL,
  `max_bytes` bigint(20) unsigned NOT NULL default '1073741824',
  `max_messages` int(10) unsigned NOT NULL default '1000',
  `ad_login` varchar(255) character set latin1 NOT NULL default '',
  `phones` varchar(255) NOT NULL default '',
  `position` varchar(255) NOT NULL default '',
  `department` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `email` (`email`),
  UNIQUE KEY `fullname` (`surname`,`name`,`patronym`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
И, наконец, запрос для создания таблицы доменов/транспортов выглядит так:
CREATE TABLE `domain` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `domain` varchar(255) character set latin1 NOT NULL,
  `transport` varchar(255) character set latin1 NOT NULL default 'dovecot:',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `domain` (`domain`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
В файле /etc/postfix/main.cf имеется 5 карт для работы с этими таблицами:
transport_maps = mysql:/etc/postfix/mysql/transport.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/user.cf
virtual_alias_maps = mysql:/etc/postfix/mysql/subscription.cf
sender_bcc_maps = mysql:/etc/postfix/mysql/sender_bcc.cf
recipient_bcc_maps = mysql:/etc/postfix/mysql/recipient_bcc.cf
Ещё одна карта используется для отказа в приёме писем для тех адресатов, у которых переполнился ящик:
check_recipient_access mysql:/etc/postfix/mysql/quota.cf
Ещё одна карта используется для аутентификации POP-before-SMTP (и для IMAP-before-SMTP):
mysql:/etc/postfix/mysql/pop-before-smtp.cf
Вот сами эти карты. Первая - /etc/postfix/mysql/transport.cf:
user = postfix
password =  postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT transport FROM domain WHERE domain='%s'
Вторая - /etc/postfix/mysql/user.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT CONCAT(SUBSTRING_INDEX(email, '@', -1), '/', SUBSTRING_INDEX(email, '@', 1), '/')
        FROM user
        WHERE email='%s'
Третья - /etc/postfix/mysql/subscription.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT recipient
        FROM subscription
        WHERE direction='I'
          AND email='%s'
          AND email NOT IN (SELECT email
                            FROM user
                            WHERE email='%s'
                              AND active='Y')
Четвёртая - /etc/postfix/mysql/sender_bcc.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT recipient
        FROM subscription
        WHERE direction='O'
          AND email='%s'
          AND email IN (SELECT email
                        FROM user
                        WHERE email='%s'
                          AND active='Y')
Пятая - /etc/postfix/mysql/recipient_bcc.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT recipient
        FROM subscription
        WHERE direction='I'
          AND email='%s'
          AND email IN (SELECT email
                        FROM user
                        WHERE email='%s'
                          AND active='Y')
Шестая - /etc/postfix/mysql/quota.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT '452 Mailbox is over quota'
        FROM user
        WHERE email = '%s'
          AND ((bytes >= max_bytes AND max_bytes > 0)
            OR (messages >= max_messages AND max_messages > 0))
Седьмая - /etc/postfix/mysql/pop-before-smtp.cf:
user = postfix
password = postfix_password
dbname = mail
hosts = 127.0.0.1
query = SELECT DISTINCT lastip
        FROM user
        WHERE lastip='%s'
          AND ADDTIME(lasttime, '0:1:0') > NOW()
Для реализации POP-before-SMTP и IMAP-before-SMTP сделаны два скрипта, которые вызываются сразу после аутентификации в Dovecot.

Первый - /etc/dovecot/pop-before-smtp.sh:
#!/bin/sh

echo "UPDATE user SET lasttime=NOW(), lastip='$IP' WHERE email='$USER';" | mysql -udovecot -pdovecot_password -h127.0.0.1 mail
exec /usr/lib/dovecot/pop3 "$@"
И второй - /etc/dovecot/imap-before-smtp.sh:
#!/bin/sh

echo "UPDATE user SET lasttime=NOW(), lastip='$IP' WHERE email='$USER';" | mysql -udovecot -pdovecot_password -h127.0.0.1 mail
exec /usr/lib/dovecot/imap "$@"
В Dovecot используются два файла, позволяющие брать информацию из БД MySQL.

Первый - /etc/dovecot/dovecot-mysql.conf:
driver = mysql
connect = host=127.0.0.1 dbname=mail user=dovecot password=dovecot_password
default_pass_scheme = CRYPT
password_query = SELECT password FROM user WHERE email='%u'
user_query = SELECT CONCAT(SUBSTRING_INDEX(email, '@', -1), '/', SUBSTRING_INDEX(email, '@', 1), '/'), \
                    999 AS uid, \
                    999 AS gid, \
                    CONCAT('*:bytes=', max_bytes, ':messages=', max_messages) AS quota_rule \
             FROM user \
             WHERE email = '%u'
Второй - /etc/dovecto/dovecot-dict-mysql.conf:
connect = host=127.0.0.1 dbname=mail user=dovecot password=dovecot_password
map {
  pattern = priv/quota/storage
  table = user
  username_field = email
  value_field = bytes
}
map {
  pattern = priv/quota/messages
  table = user
  username_field = email
  value_field = messages
}
Файл конфигурации самого Dovecot /etc/dovecot/dovecot.conf у меня выглядит вот так:
protocols = pop3 imap
disable_plaintext_auth = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_location = maildir:/var/mail/virtual/%Ld/%Ln
first_valid_uid = 999
first_valid_gid = 999

dict {
  quotadict = mysql:/etc/dovecot/dovecot-dict-mysql.conf
}
plugin {
  quota = dict:user::proxy::quotadict
  quota_rule = *:storage=1G:messages=1000
}
protocol pop3 {
  mail_plugins = quota
  mail_executable = /etc/dovecot/pop-update-lastlog.sh
}
protocol imap {
  mail_plugins = quota imap_quota
  mail_executable = /etc/dovecot/imap-update-lastlog.sh
}
protocol lda {
  postmaster_address = postmaster@mydomain.ru
  mail_plugins = quota
  quota_full_tempfail = yes
  rejection_reason = Your message to <%t> was automatically rejected:%n%r
  quota_exceeded_message = 422: No space to store your message
}

auth_default_realm = mydomain.ru

auth default {
  mechanisms = plain login
  passdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }
  userdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }
  socket listen {
    client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
    master {
      path = /var/run/dovecot/auth-master
      mode = 0660
      user = vmail
      group = vmail
    }
  }
}
Для ограничения доступа к таблицам из postfix и dovecot были созданы два пользователя, которые имеют минимально необходимые им для работы права доступа к соответствующей БД MySQL:
insert into user(host, user, password)
values('localhost', 'postfix', PASSWORD('postfix_password'));
insert into tables_priv(host, db, user, table_name, table_priv, column_priv)
values('localhost', 'mail', 'postfix', 'subscription', '', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'subscription', 'direction', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'subscription', 'email', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'subscription', 'recipient', 'select');

insert into tables_priv(host, db, user, table_name, table_priv, column_priv)
values('localhost', 'mail', 'postfix', 'domain', '', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'domain', 'domain', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'domain', 'transport', 'select');

insert into tables_priv(host, db, user, table_name, table_priv, column_priv)
values('localhost', 'mail', 'postfix', 'user', '', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'active', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'email', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'password', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'bytes', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'max_bytes', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'messages', 'select'); 
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'max_messages', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'lasttime', 'select'); 
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'postfix', 'user', 'lastip', 'select');

insert into user(host, user, password)
values('localhost', 'dovecot', PASSWORD('dovecot_password'));
insert into tables_priv(host, db, user, table_name, table_priv, column_priv)
values('localhost', 'mail', 'dovecot', 'user', '', 'select,update');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'email', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'password', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'bytes', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'max_bytes', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'messages', 'select'); 
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'max_messages', 'select');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'bytes', 'update');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'messages', 'update'); 
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'lasttime', 'update');
insert into columns_priv(host, db, user, table_name, column_name, column_priv)
values('localhost', 'mail', 'dovecot', 'user', 'lastip', 'update');
flush privileges;
Естественно, во всём тексте статьи, для облегчения восприятия, реальные пароли заменены на их заменители - postfix_password и dovecot_password.

На интерфейс для управления почтовым сервером (по понятным причинам, реальные данные пришлось забрызгать спреем) можно посмотреть на нижеследующих снимках.

Управление доменами и транспортами:

Редактирование одного домена и его транспорта:

Управление пользователями/ящиками (совмещены две разные картинки):

Редактирование одного пользователя/ящика:

Заведение нового пользователя/ящика:

Управление всеми подписками на входящие (скоро переделаю для управления подписками на исходящие тоже):

Страница синхронизации информации почтовой системы с порталом MS SharePoint Services 3.0:

В процессе написания веб-приложения сам собой зародился простенький фреймворк в процедурном стиле, в который входит несколько функций для более удобного доступа к БД, функции для работы с шаблонами, виджеты таблиц и форм редактирования объектов БД, функции для ведения веб-сессий в БД (стандартный механизм сессий для PHP мне не подошёл, сессии сейчас в приложении никак не используются), и каркас приложения, который вызывает функции обработки форм и формирования HTML-блоков. Аутентификацию на базе модуля сессий делал, но пока что она не имеет смысла, т.к. нет механизмов авторизации, то есть программа может отличать пользователей друг от друга, но у всех пользователей, включая неаутентифицированных, пока что равные права. Сейчас ограничение доступа осуществляется средствами веб-сервера, в котором каталог с приложением просто запаролен.

Планов по дальнейшему развитию системы ещё очень много. Однако, дело это не быстрое и не известно, хватит ли терпения всё это реализовать.

среда, 15 февраля 2012 г.

Мониторинг SNMP-устройств с помощью RRDTool

В моей сети я обнаружил 16 устройств, содержащих в своём составе SNMP-агент:
  1. маршрутизатор Cisco 2821,
  2. коммутатор HP ProCurve Switch 2626,
  3. 2 коммутатора HP ProCurve Switch 2650,
  4. 2 блока бесперебойного питания Smart-UPS 3000 RM с модулем сетевого управления,
  5. 7 многофункциональных устройств Kyocera Mita FS-1028MFP,
  6. 1 многофункциональное устройство Kyocera Mita FS-1118MFP,
  7. 1 многофункциональное устройство Kyocera Mita FS-1300D,
  8. 1 многофункциональное устройство Kyocera Mita KM-1650.
Недели две назад я попробовал воспользоваться для наблюдения за коммутаторами munin'ом, а затем cacti.

munin поддерживает мониторинг SNMP-устройств, но нельзя сказать, что это его основное назначение. Предназначен он скорее для наблюдения за Linux. В принципе, наблюдать за Linux можно теми же средствами SNMP, для чего нужно поставить SNMP-агент. Munin тут скорее имеет преимущество другого рода - для него легче писать плагины. Плагины для наблюдения за SNMP-устройствами, идущие в комплекте с Munin, запрашивают у оборудования по одному параметру за раз, что увеличивает нагрузку на сеть, на наблюдаемое устройство, на саму систему мониторинга и существенно замедляет сам мониторинг. Munin полностью перестраивает графики каждые 5 минут, что может показаться полезным только в том случае, если мониторингом занимается много людей. В случае, если мониторингом занимается мало людей, выгоднее перестраивать каждый график тогда, когда к нему обратятся.

Именно так делает Cacti, который предназначен именно для наблюдения за сетевыми устройствами по SNMP, обновляет графики только по требованию. Cacti - хорошая штука для наблюдения за сетевыми устройствами и компьютерами, но мне хотелось бы наблюдать ещё и за бесперебойниками и принтерами. Возможно для этого есть какие-то плагины и шаблоны, но их поисками я заниматься не стал. Ещё один момент, который мне не понравился - нельзя инвертировать входящий трафик так, чтобы на графике он оказался ниже оси времени (то есть можно, но нельзя выбрать операцию типа "инвертировать и умножить на 8"). В Cacti есть поля для настройки rrdtool graph, но там нет главного - возможности задавать произвольные функции в обратной польской записи, что позволяет сам rrdtool graph.

В общем, после знакомства с этими системами я узнал об их ограничениях и недостатках и решил изобрести собственный велосипед, ещё более ограниченный и кривой, но тем не менее заточенный конкретно на мои потребности. К тому же, было бы полезно изучить сами базовые инструменты - пакет net-snmp и rrdtool. Большим подспорьем в освоении этих инструментов для меня оказались материалы Сергея Евгеньевича Богомолова:

Bog BOS: SNMP, MIB, RMON
Bog BOS: RRDtool - хранение и отображение данных мониторинга
Bog BOS: hardware: UPS, мониторинг и управление с помощью SNMP

В сети довольно часто встречаются другие материалы по SNMP и RRDTool, однако в них заметны просто огромные куски, не бездумно, но лениво скопированные из первых двух статей. В частности, оттуда кусками вырываются описания функций построения графиков в rrdtool graph и описания выбора количества ячеек и отсчётов в ячейках RRA при использовании rrdtool create, которые автор подбирает похожими на поведение MRTG.

Чтобы не быть лентяем и не заниматься бездумным копированием, а действительно хоть в чём-то разобраться самостоятельно, я решил выбрать собственные настройки RRA. Количество ячеек выбирал таким образом, чтобы они охватывали какой-то принятый в календаре и часах период времени, чтобы каждая ячейка, в свою очередь, тоже подчинялась этому правилу, и чтобы количество ячеек было в пределах 250-350 штук, чтобы графики не были ступенчатыми, а действительно напоминали графики.

В результате остановился на следующих настройках:
RRA:AVERAGE:0.5:1:288  день с точностью до 5 минут
RRA:AVERAGE:0.5:12:336  14 дней с точностью до часа
RRA:AVERAGE:0.5:228:366  год с точностью до дня
RRA:AVERAGE:0.5:2016:261 5 лет с точностью до недели
Смысл настроек RRA такой: создаётся кольцевой буфер из n ячеек, где каждая из ячеек содержит m отсчётов. Эти отсчёты при каждом использовании rrdtool update заполняются по кругу. Мы создали четыре таких кольцевых архива, каждый из которых будет заполняться по кругу, на каждом из очередных витков предыдущие данные будут затираться новыми. Значение 0.5 определяет, что значение из ячейки будет считаться определённым, когда в ней накопится хотя бы половина отсчётов. Для вычисления значения ячейки из значений в отсчётах применяется указанная функция. В данном случае это функция AVERAGE, что означает вычисление среднего значения отсчётов в ячейке. В ячейках могут храниться и неопределённые значения, например на тот случай, если в соответствующее время наблюдаемый объект был отключен или недоступен.

Настройки, конечно, спорные, но зато я не похож на других :-P

Для наблюдения за блоками бесперебойного питания я нашёл в интернете файл POWER-MIB. Имена наблюдаемых мной параметров и их значение перечислены ниже:
upsAdvBatteryCapacity.0  уровень заряда батареи в процентах
upsAdvBatteryTemperature.0 температура батареи в градусах Цельсия
upsAdvInputLineVoltage.0 напряжение в сети в Вольтах
upsAdvInputMinLineVoltage.0 минимальное напряжение в сети за последнюю минуту в Вольтах
upsAdvInputMaxLineVoltage.0 максимальное напряжение в сети за последнюю минуту в Вольтах
upsAdvInputFrequency.0  частота напряжения в сети в Герцах
upsAdvOutputVoltage.0  выходное напряжение в Вольтах
upsAdvOutputFrequency.0  частота выходного напряжения
upsAdvOutputLoad.0  уровень нагрузки в процентах от номинальной
upsAdvOutputCurrent.0  сила выходного тока в Амперах
upsBasicConfigNumDevices.0 количество подключенных устройств в штуках
Для наблюдения за МФУ я использую следующие SNMP-переменные:

Kyocera Mita FS-1028MFP
enterprises.1347.42.3.1.3.1.1.2  отсканировано страниц в копировальном аппарате
enterprises.1347.42.3.1.4.1.1.1  отсканировано страниц на сканере
enterprises.1347.46.10.1.1.5.3  отсканировано страниц всего (на копире и сканере)
enterprises.1347.42.3.1.1.1.1.2  распечатано страниц в копировальном аппарате
enterprises.1347.42.3.1.1.1.1.1  распечатано страниц на принтере
enterprises.1347.43.10.1.1.12.1.1 распечатано страниц всего (на копире и на принтере)
Kyocera Mita FS-1118MFP
enterprises.1347.46.10.1.1.5.3  отсканировано страниц всего
enterprises.1347.43.10.1.1.12.1.1 распечатано страниц всего
Kyocera Mita FS-1300D и KM-1650
1.3.6.1.2.1.43.10.2.1.4.1.1  распечатано страниц всего
Все эти параметры я искал с помощью snmpwalk и веб-интерфейса соответствующего МФУ. Когда на странице статуса МФУ было видно, что принтер находится в состоянии ожидания, я смотрел счётчик, выполнял команду snmpwalk и искал этот счётчик по тексту, выданному snmpwalk. МФУ KM-1650 оказалось ветераном среди всех МФУ, он отпечатал около 280 тысяч страниц.

В итоге, для каждого вида устройства был создан собственный скрипт для создания базы, опроса устройства и внесения информации в базу данных RRD, создания HTML-страниц и для обновления графиков. У каждого из скриптов 4 соответствующих режима работы (для примера взят скрипт rrd-cisco2821.sh):

rrd-cisco2821.sh create id
- создание базы данных для слежения за устройством.

rrd-cisco2821.sh update id ip community
- получение отслеживаемых параметров с устройства с указанным IP и строкой сообщества community,

rrd-cisco2821.sh build id period
- построение графиков за указанный период period. С используемыми настройками RRD и генерируемыми HTML-файлами имеет смысл использовать значения 1day, 2weeks, 1year и 5years. Хотя, если вы хотите сгенерировать графики за произвольный период, вы можете указать любое значение period, которое поймёт rrdtool.

rrd-cisco2821.sh html id
- создание HTML-страниц, на которых будут использоваться сгенерированные графики.

Во всех режимах используется значение id - это произвольный текстовый или числовой идентификатор без пробельных символов, который позволит скрипту отличать одно устройство этого типа от другого. Он используется в именах RRD-файла, файлов графиков, HTML-файлов.

Скрипты можно взять здесь: rrd.tbz

А вот пример одной из HTML-страниц с графиками наблюдения за блоком бесперебойного питания:


Особого смысла в наблюдении за МФУ по графикам я не вижу. Гораздо полезнее было бы вести учёт этой информации в базе данных и строить, например, ежемесячные отчёты для планирования расходов на... расходные материалы. Да и остальные графики могут быть полезны скорее в аналитических целях, т.к. до превышения нагрузок на оборудование в моей сети ещё очень далеко. То есть, перестраивать и просматривать графики в моём случае стоит не чаще раза в месяц. Обновлять и просматривать графики чаще имеет смысл только если оборудование работает на пределе возможностей, но и в этом случае лучше всё-таки заменить оборудование на более мощное или каким-то образом перераспределить нагрузку заранее.

пятница, 3 февраля 2012 г.

Краткая справка по командам коммутаторов HP ProCurve Switch 26xx

Довелось немного покопаться в коммутаторах Hewlett Packard ProCurve Switch 2650 (50-портовая модель) и 2626 (26-портовая модель). Решил записать на память команды.

В целом схема режимов командной строки коммутатора очень похожа на Cisco: есть привилегированный (enable) и непривилегированный режим (disable), из которого можно попасть в режим настройки (configure terminal), из которого, в свою очередь, можно попасть в режим настройки интерфейса (interface) или VLAN (vlan).

show running-config - показать текущую конфигурацию

write memory - записать текущую конфигурацию в энергонезависимую память

configure terminal - вход в режим настройки

Настройка IP-адреса, маршрута по умолчанию:

ip default-gateway 10.0.0.1 - задать маршрут по умолчанию (существующий заменится на указанный)

interface vlan 1 - перейти в режим настройки интерфейса vlan 1

ip address 10.0.0.2 255.255.255.0 - задать новый адрес и маску (на интерфейсе можно настроить несколько адресов, поэтому старые адреса не заменяются на новые)

no ip address 192.168.0.2 255.255.255.0 - убрать адрес и маску

Настройка способов администрирования коммутатора:

telnet-server - включить управление коммутатором через telnet

no telnet-server - отключить управление коммутатором через telnet

crypto key generate ssh - сгенерировать ключ для ssh-сервера

ip ssh - включить управление коммутатором по SSH

crypto key zeroize ssh - обнулить ключ для ssh-сервера (SSH-сервер отключится автоматически)

web-management plaintext - включить управление коммутатором по HTTP

no web-management plaintext - выключить управление коммутатором по HTTP

web-management ssl - включить управление коммутатором по HTTPS

no web-management ssl - выключить управление коммутатором по HTTPS

Настройка CDP:

cdp enable - включение CDP на коммутаторе

no cdp enable - отключить CDP на коммутаторе

cdp enable ethernet 26 - включить CDP на порту 26 (действует только если включен CDP на уровне всего коммутатора)

no cdp enable ethernet 1-25 - отключить CDP на портах с 1 по 25 (имеет значение только если CDP включен на уровне всего коммутатора)

show cdp - просмотреть настройки CDP на устройстве

show cdp neighbors - посмотреть список соседей на всех портах в виде таблицы

show cdp neighbors ethernet 50 - посмотреть список соседей на порту 50 в виде таблицы

show cdp neighbors detail ethernet 50 - посмотреть список соседей на порту 50 в подробностях

Примечание: В Linux есть пакет cdpr, с помощью которого можно принимать CDP-анонсы. Делается это, например, такой командой:
# cdpr -d eth2

Просмотр MAC-адресов на портах коммутатора:

show mac-address - просмотреть таблицу соответствия MAC-адресов портам коммутатора

show mac-address ehternet 1 - посмотреть таблицу MAC-адресов на первом порту коммутатора

show mac-address ehternet 1-10 - посмотреть таблицы MAC-адресов портах коммутатора с 1 по 10

show mac-address 00:13:d4:4e:c3:74 - посмотреть, через какой порт коммутатора доступен этот MAC-адрес

Настройка даты и времени:

no clock summer-time - отключение автоматического перехода на зимнее/летнее время (режим Медведева)

clock timezone gmt +6:00 - установка часового пояса

clock set 09:59:00 - установка времени

clock set 02/03/2012 - установка даты в формате месяц/число/год

show time - посмотреть время на коммутаторе

Настройка SNTP-клиента:

Не знал, что такое SNTP и обратился за информацией в интернет. Оказалось (Differences Between NTP and SNTP), что SNTP - это упрощённая версия NTP.

Клиенты SNTP и серверы SNTP берут время только из одного источника. SNTP-сервер берёт время из источника точного времени (GPS или "атомные часы"), а SNTP-клиент - только с какого-то определённого сервера NTP. Для сравнения: NTP-серверы/клиенты могут учитывать время на вышестоящих и соседних серверах NTP и поддерживать синхронизацию со всеми ими, ускоряя или замедляя локальные часы.

sntp unicast - выбор метода синхронизации от указанного источника (broadcast - синхронизация по широковещательным пакетам, рассылаемым в сеть)

sntp server 10.0.0.3 - сервер времени

sntp 30 - периодичность синхронизации времени в секундах

timesync sntp - синхронизировать время прямо сейчас по источнику из SNTP

Настройка syslog-клиента:

logging facility user - указываем средство syslog

logging 10.0.0.4 - указываем IP-адрес сервера syslog

К слову, включить приём сообщений по сети в rsyslog можно добавив к его файл конфигурации /etc/rsyslog.conf следующие строки:
$ModLoad imudp
$UDPServerRun 514

$ModLoad imtcp
$InputTCPServerRun 514

Эти строки подключают к rsyslog модули приёма сообщений из сети по UDP и по TCP. К сожалению, на деле сообщения, принятые по TCP, почему-то не попали в syslog (tcpdump показал, что они принимаются).

Для применения новых настроек rsyslog его нужно перезапустить:
# /etc/init.d/rsyslog restart
Пока всё. Относительно много хорошей документации по настройке коммутаторов Hewlett Packard написала Наталья Самойленко на xgu.ru.

P.S. На следующий день нашёл компакт-диск с документацией на коммутаторы, так что эта заметка теперь имеет мало смысла.