понедельник, 24 февраля 2014 г.

Растущее количество dropped пакетов в ifconfig

Настраивая новую систему мониторинга я заметил, что график ошибок сетевого адаптера одного из серверов показывает рост значения RX packets: dropped.

# ifconfig em2
em2       Link encap:Ethernet  HWaddr 00:25:90:d0:df:18  
          inet addr:xx.xx.xx.xx  Bcast:xx.xx.xx.255  Mask:255.255.255.0
          inet6 addr: fe80::225:90ff:fed0:df18/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:180047091 errors:0 dropped:31438 overruns:0 frame:0
          TX packets:165010458 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:58487975592 (58.4 GB)  TX bytes:192626658770 (192.6 GB)
          Memory:f7100000-f7180000

Это может говорить о том, что система не успевает забирать пакеты из буфера приема сетевого адаптера. Хотя в этом случае должно расти и значение RX packets: overruns.

Поиск в гугле вывел на возможное объяснение такому поведению. Такое поведение счетчика ошибок поясняется цитатой ниже

Beginning with kernel 2.6.37, it has been changed the meaning of dropped packet count. Before, dropped packets was most likely due to an error. Now, the rx_dropped counter shows statistics for dropped frames because of:

  • Softnet backlog full
  • Bad / Unintended VLAN tags
  • Unknown / Unregistered protocols
  • IPv6 frames when the server is not configured for IPv6

If any frames meet those conditions, they are dropped before the protocol stack and the rx_dropped counter is incremented.

Вариант с Softnet backlog full я исключил сразу, поскольку ошибки распределены более-менее равномерно и присутствуют даже при траффике менее 100 пакетов в секунду.

Для проверки остальных пунктов на сутки был запущен tcpdump на проблемном интерфейсе em2.



По истечении суток показания мониторинга подтвердили теорию - ошибки при запущенном tcpdump не появляются, а следовательно можно не дергать сервер.

понедельник, 17 февраля 2014 г.

Локальный репозитарий с reprepro

Устанавливаем reprepro

# aptitude install reprepro

Создаем корневую директорию для репозитория и конфигурацию reprepro

# mkdir -p /var/www/debian/conf
# cat > /var/www/debian/conf/distributions <<_EOF_
Origin: Amasty
Suite: stable
Codename: wheezy-amasty
Version: 7.0
Architectures: i386 amd64 source
Components: main backports
UDebComponents: main backports
Description: Local Amasty repository
_EOF_

Теперь нужно инициализировать созданную конфигурацию

# reprepro -b /var/www/debian export
# reprepro -b /var/www/debian createsymlinks

Пакеты уже залиты на сервер в директорию /tmp/incoming, добавляем их в секцию main

# reprepro -b /var/www/debian -C main includedsc /tmp/incoming/*.dsc
# reprepro -b /var/www/debian -C main includedeb /tmp/incoming/*.deb

Осталось подчистить "хвосты"

# rm -fr /tmp/incoming

четверг, 13 февраля 2014 г.

Резервное копирование домашнего медиацентра

Сегодня наводил окончательный лоск в настройках домашнего медиацентра (Raspberry PI + OpenELEC) после переноса его директории /storage с SD карты на сервер NFS (SD карта используется только для загрузки, а все файлы конфигурации и пользовательских данных хранятся на сервере и доступны через NFS).

Когда с настройками было покончено я сделал резервную копию средствами OpenELEC, но вот что интересно - резервная копия выполняется без завершения работы XBMC, а значит часть файлов копируется в процессе использования.

Узнать список файлов, которые в данный момент используются, можно на самом медиацентре

OpenELEC:~ # lsof | grep /storage
866 /usr/sbin/connmand /storage/.cache/connman/ethernet_b827eb9ace35_cable/data
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/temp/xbmc.log
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/userdata/Database/Addons15.db
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/userdata/Database/Textures13.db
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/userdata/Database/TV22.db
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/userdata/Database/Epg7.db
946 /usr/lib/xbmc/xbmc.bin /storage/.xbmc/userdata/Database/Addons15.db

Открытые файлы *.db это базы SQLite, которые могут быть в промежуточном состоянии на момент создания резервной копии.

Чтобы избежать копирования открытых файлов можно выключить оболочку XBMC, создать резервную копию и затем включить XBMC обратно.

После изучения системы инициализации в OpenELEC оказалось, что самым простым способом достичь желаемого - выполнить перезагрузку всего медиацентра. В процессе завершения работы системы выполняется скрипт /storage/.config/shutdown.sh, который запускается после выключения XBMC, но до перезагрузки всей системы.

Собственно скрипт

if [ "`date +'%H'`" != "05" ]; then
 echo "Seems triggered not by cron job, simply exiting"
 exit 0
fi

STAMP=`date +'%Y%m%d%H%M%S'`

if [ ! -d /storage/backup ]; then
 mkdir /storage/backup
fi

echo "Settings backup..."
tar -cf /storage/backup/${STAMP}.tar /storage/.cache /storage/.config /storage/.xbmc

if [ "`date +'%u'`" == "7" ]; then
 echo "Flash backup..."
 tar -cf /storage/backup/${STAMP}_flash.tar /flash
fi

echo "Backup finished, syncing..."
sync
sleep 30s

Скрипт проверяет в котором часу он запущен и если сейчас не 5 часов утра, то создание резервной копии отменяется - скорее всего это перезагрузка по требованию пользователя, а не задания крона. Далее создается TAR-архив, содержащий конфигурацию OpenELEC и XBMC. Также если скрипт запущен в воскресенье, то дополнительно создается резервная копия всей системы (защита от неудачного обновления самого OpenELEC или выхода из строя SD карточки). Перед завершением скрипта выполняется сброс буферов и выжидается 30 секунд (на всякий случай).

Задание крона выглядит так

# crontab -u root -l

# Reboot to create semi-offline backup
10 5 * * * /usr/bin/xbmc-send --action="XBMC.Reboot"

Согласно этому заданию в каждый день в 5:10 утра выполняется команда перезагрузки средствами XBMC, что гарантирует корректное завершение работы.

Настройка PHP 5.3 для работы в FastCGI режиме в Debian Squeeze

Процесс установки описан для Debian Squeeze и в других дистрибутивах или релизах Debian процесс может незначительно отличаться. Устанавливаем необходимые пакеты

# aptitude install spawn-fcgi php5-cli php5-cgi php5-curl php5-gd php5-imap php5-mcrypt php5-mysql

Далее нужно создать скрипт инициализации FastCGI менеджера (spawn-fcgi)

# vim /etc/init.d/php5-fcgi

#! /bin/sh
### BEGIN INIT INFO
# Provides:          php5-fcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: PHP FastCGI
# Description:       PHP FastCGI
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="PHP FastCGI"
NAME=php5-fcgi
DAEMON=/usr/bin/spawn-fcgi
FCGI_SOCKET=/var/run/php5-fcgi.sock
FCGI_USER=www-data
FCGI_MODE=0600
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
DAEMON_ARGS="-s $FCGI_SOCKET -M $FCGI_MODE -u $FCGI_USER -U $FCGI_USER -P $PIDFILE -- /usr/bin/php5-cgi"

[ -x "$DAEMON" ] || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME

. /lib/init/vars.sh

. /lib/lsb/init-functions

do_start()
{
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec /usr/bin/php5-cgi --test >/dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
                $DAEMON_ARGS >/dev/null \
                || return 2
}

do_stop()
{
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
        RETVAL="$?"
        rm -f $PIDFILE $FCGI_SOCKET
        return "$RETVAL"
}


case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
      0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
      *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

Для определения параметров работы FastCGI нужно создать конфигурацию по-умолчанию

# vim /etc/default/php5-fcgi

export PHP_FCGI_CHILDREN=10
export PHP_FCGI_MAX_REQUESTS=1000

Запускаем сервис php5-fcgi и добавляем его в автозапуск

# invoke-rc.d php5-fcgi start
# update-rc.d php5-fcgi defaults

вторник, 11 февраля 2014 г.

Использование Gmail в качестве почтового шлюза для Postfix

Если ваш IP адрес "проклят", то при попытке доставить почту на сервера Gmail вы увидите что-то наподобие этого

status=bounced (host gmail-smtp-in.l.google.com[173.194.70.26] said: 550-5.7.1 [87.xx.xx.xx] The IP you're using to send mail is not authorized to 550-5.7.1 send email directly to our servers. Please use the SMTP relay at your 550-5.7.1 service provider instead. Learn more at 550 5.7.1 http://support.google.com/mail/bin/answer.py?answer=10336 g47si26393674eev.48 - gsmtp (in reply to end of DATA command))

Выход прост -  если вам не нужна возможность доставлять почту от разных людей (в моем случае письма только от систем мониторинга), то можно создать почтовый ящик Gmail и слать почту через него. В этом случае локальный почтовый сервер выступает в роли авторизованного клиента Gmail. Из минусов пожалуй только перезапись From: (вроде это можно как-то настраивать).

Если postfix еще не установлен, то самое время его установить

# aptitude install postfix ca-certificates

Сказать postfix, что нужно доставлять почту через релей

# vim /etc/postfix/main.cf

relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes

Указать данные авторизации в Gmail в файле /etc/postfix/sasl_passwd

# vim /etc/postfix/sasl_passwd

[smtp.gmail.com]:587    USERNAME@gmail.com:YOURPASSWORD

После нужно выставить правильные разрешения на файл паролей и создать его хешированную версию

# chmod 0400 /etc/postfix/sasl_passwd
# postmap /etc/postfix/sasl_passwd

Остается только дать postfix доступ к сертификату удостоверяющего центра Gmail (это thawte)

# cp /etc/ssl/certs/Thawte_Premium_Server_CA.pem /etc/postfix/cacert.pem

Перезагружаем конфигурацию postfix и пробуем отправить тестовое письмо

# service postfix reload
# echo 'test message' | mail -s 'relayhost test' someuser@gmail.com

пятница, 7 февраля 2014 г.

Получение информации о принтере через SNMP

Установите SNMP клиент и поддержку загрузки MIB баз

$ sudo aptitude install snmp snmp-mibs-downloader

Закоментируйте строку mibs : в файле /etc/snmp/snmp.conf. Это позволит использовать MIB, которые скачаются при установке пакета snmp-mib-downloader.

Скачайте IETF Printer MIB (я нашел тут) и распакуйте его в директорию ~/.snmp/mibs (создайте эту директорию, если она еще не существует). Затем добавьте в ~/.snmp/snmp.conf строку mibs +Printer-MIB.

Теперь вы можете просмотреть значение переменных

$ snmpwalk -c public -v1 192.168.100.201 SNMPv2-MIB::sysDescr
SNMPv2-MIB::sysDescr.0 = STRING: Panasonic KX-MB2020

P.S. Большая подборка MIB для различных вендоров нашлась тут.