Posterous theme by Cory Watilo

Filed under: Networking

FreeBSD IP address change

In FreeBSD ip address is written in /etc/rc.conf.

If you changed it and want to restart network interfaces with latest changes, just run

/etc/rc.d/netif restart

But this wouldn’t affect routing. So if you changed default gateway too, you need to run

/etc/rc.d/routing stop
/etc/rc.d/routing start

To view routing table run

netstat -rn

And, finally, to add gateway by hand exec

route add default 192.168.1.254

Many thanks to VIVEK GITE for his post on nixCraft.

Exim mail forwarding

Стоял у меня MTA Exim4 для отправки почты. И вдруг на этот сервер перенесли MX-запись одного домена (например, example.org), и он вынужден был что-то делать с почтой. Решено было перенаправить всю почту для этого домена на другой ящик на время разбирательств кто прав, а кто виноват.

Для этого в Ubuntu пришлось сделать следующие правки.

В /etc/exim4/update-exim4.conf.conf в dc_other_hostnames и dc_relay_domains был добавлен example.org.

А сам форвард выглядел так (/etc/exim4/conf.d/router/099_exim4-config_redirects):

forward:
    driver = redirect
    domains = example.org
    data = tmp_example.org@somemail.com

В теории должна была сработать запись вида

sender_redirect:
  driver = redirect
  data = ${lookup{$sender_address}lsearch{/etc/exim4/sender_redirects}}
  domains = example.org

И в файле /etc/exim4/sender_redirects были бы

someone@example.org: where.to@forward.com

Но почему-то этот вариант не сработал как ожидалось.

Возможно я допустил какие-то ошибки в конфигурировании, но задача выполнена и почта не потеряна.

PowerDNS - master and slave

В связи с переездом на новый сервер пришлось переносить и кучу сервисов, которые крутились на старом. Одним из них был DNS.

Настоятельно рекомендуется делать master и slave (primary и secondary) на разных машинах, дабы в случае отказа одного из них второй мог полноценно работать. Ну это в теории, на практике все несколько упрощается до одного сервера, который если ляжет – то DNS будет уже не столь важен.

Начал подымать master на OpenSuSE 11.1. Конфиг простой и незамысловатый:

#each slave should be put here (space separated) to allow zone details transfer
allow-axfr-ips=1.1.1.2
disable-axfr=no
daemon=yes
guardian=yes
default-ttl=3600
soa-refresh-default=3600
lazy-recursion=yes
local-address=0.0.0.0
master=yes
recursor=127.0.0.1:5300
launch=gmysql
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns
gmysql-password=powerdns
gmysql-socket=/var/run/mysql/mysql.sock

и рекурсор:

chroot=/var/lib/pdns
local-address=127.0.0.1
local-port=5300
setgid=pdns
setuid=pdns

Базу для него создавал из PowerDNS on Rails, хотя можно ограничиться и той, что в документации.

И напоролся на первый занятный баг – со включенным режимом master он взлетает и долбит базу одинаковыми запросами (пытается получить все записи). На стоящей рядом ubuntu с той же версией такого не наблюдается. Долго пытался отловить что, где и почему – и решил пересобрать из сорсов. Когда обнаружилась нехватка boost я решил проверить, а нет ли готового свеженького пакета с собраным powerdns? Таки есть – надо было всего лишь добавить в списки репо вот этот:

http://download.opensuse.org/repositories/server:/dns/openSUSE_11.1/

и была установлена версия pdns-2.9.22-1.1. Проблема с нагрузкой на БД полечилась, но появилась новая – с репликацией на slave.

В PowerDNS есть такое понятие как supermaster. В общем случае нужно прописывать зону на мастере и слейве. Когда слейв получит от мастера notify, он запросит у мастера записи из этой зоны. Но если сервер, от которого пришел notify, будет обнаружен в списке supermasters, и такой зоны на слейве не будет описано, она создастся автоматически. И потом в нее будут добавлены записи с мастера. Это приятно упрощает жизнь.

В табличке запись довольно простая – ip мастера, имя слейва (ns2.example.org), имя аккаунта (на работу никак не влияет – просто будет фигурировать в описании зоны; удобно для указания клиента, например).

В порядке эксперимента попинал слейв нотификейшенами для разных доменов. Не с первого раза, но заработало:

pdns_control notify example.org

С первого раза не заработало потому, что в PowerDNS on Rails в имя поддомена по привычке вписал “@”, и потом получил записи вида “@.example.org” вместо “example.org” либо “@”. Прошелся простым апдейтом по базе и убрал этот баг.

PS: Хочу выразить благодарность Патрику Фею за его недавний пост, который помог постичь смысл supermaster'ов.

PPS: конфиг pdns для слейва мало чем отличается от мастера:

config-dir=/etc/powerdns
daemon=yes
disable-axfr=yes
guardian=yes
launch=gmysql
lazy-recursion=yes
local-address=0.0.0.0
local-port=53
module-dir=/usr/lib/powerdns
setgid=pdns
setuid=pdns
slave=yes
socket-dir=/var/run
version-string=powerdns
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns
gmysql-password=powerdns

Having fun with RRD and architecture

Переезжал на новый сервер, и наигрался вволю со всеми мониторингами и прочим. Была обнаружена неприятная особенность RRD: бд платформозависима. Пришлось на старом сервере делать дамп

for i in *.rrd; do rrdtool dump $i > $i.xml; done

тащить на новый (tar, scp либо nc) и там разворачивать:

for i in *.xml; do A=`echo $i|sed 's/\.xml//'`; rrdtool restore -f $i $A; done

Копирование ninja way

На стороне получателя

netcat -l -p 7000 | tar x

На стороне отправителя

tar cf - * | netcat otherhost 7000

Ссылки по теме:

OpenVZ on Ubuntu 8.10

Только-что закончил эксперименты с OpenVZ на Ubuntu 8.10 (intrepid). Успешно. Итак, задача: создать виртуальную (для начала одну) машину с Ubuntu 8.10, которая будет доступна в локальной сети. Хост-система - Ubuntu 8.10, выступает в роли роутера для локальной сети, имеет на себе DHCP-сервер. Настройки сети виртуальная машинка должна получать по DHCP, роутиться другим роутером (два провайдера). Задача осложняется тем, что из intrepid убрали поддержку виртуализации посредством OpenVZ и сделали упор на KVM. Так как имеем машинку на базе AMD Duron (900MHz) то приходится выкручиваться. Опыт, как говорится, бесценен. Пару слов о состоянии виртуализации в Ubuntu:
  • KVM. В 8.10 сделали упор на KVM, который требует аппаратной поддержки виртуализации процессором. В данном случае процессор устаревший, так что KVM отпадает.
  • VServer. Выглядит неплохо, но у меня не удалось при помощи make-kpkg собрать ядро (2.6.27-15, наиболее близкое к имеющемуся в 8.10 - 2.6.27-11).
  • OpenVZ. Неплохое решение, но ядро с поддержкой виртуализации было в 8.04, в 8.10 от него отказались в пользу KVM.
  • Xen. Не горел желанием использовать решения полной виртуализации, так как вируализировать оборудование мне не требовалось - это дополнительные накладные расходы. Вроде бы поддержка есть... но, как оказалось, лишь в качестве гостевой ОС (DomU - гостевая, Dom0 - хост-система). А сервером (Dom0) - увы. В 8.04 было ядро умеющее быть сервером.
  • VMWare Server. Также полная виртуализация, тяжеловесное решение. Но хорошо тем, что не требует хаков с ядром.
Итогом чтения доки стала установка VMWare Server, и обошлось без косяков. Но снес его через несколько часов. Во-первых, одновременно с VMWare Server нельзя пользоваться комплектом netatalk. Во-вторых, теперь у VMWare Server появилась вебморда. И все бы ничего, если б не ее тормознутость. Посмотрев список процессов - sun-jre, apache-tomcat. Не знаю у кого как, но на столь небыстрой машинке вебморда тормозила и лагала безбожно. Некогда был Remote Console, но я так и не смог его найти. Таким образом я пришел к OpenVZ. Для начала я прописал в /etc/apt/sources.list репозиторий от 8.04: [cc lang="text"] deb http://de.archive.ubuntu.com/ubuntu/ hardy main restricted universe multiverse deb http://de.archive.ubuntu.com/ubuntu/ hardy-updates main restricted universe multiverse deb http://de.archive.ubuntu.com/ubuntu/ hardy-backports main restricted universe multiverse [/cc] Далее - по учебнику: [cc lang="text"] apt-get install linux-openvz vzctl [/cc] Получил ядро linux-image-2.6.24-23-openvz и проверил, что пакет linux-restricted-modules-openvz потянул за собой linux-restricted-modules-common. Пользуясь aptitude установил версию 2.6.24.16-23.56. Так как сервер уже работал роутером, то изменений в /etc/sysctl.conf я не вносил - более-менее с рекомендациями мои значения совпали. Со странички шаблонов стянул ubuntu-8.10-x86.tar.gz: [cc lang="text"] cd /var/lib/vz/template/cache && wget http://download.openvz.org/template/precreated/ubuntu-8.10-x86.tar.gz [/cc] Затем создал виртуальный контейнер [cc lang="text"] vzctl create 101 --ostemplate ubuntu-8.10-x86 --config vps.basic [/cc] задал виртуальной машине hostname [cc lang="text"] vzctl set 101 --hostname gretchin --save [/cc] и добавил запуск этой VPS вместе с запуском OpenVZ (/etc/init.d/vz) [cc lang="text"] vzctl set 101 --onboot yes --save [/cc] Чудесно. На данный момент имеем виртуальную машину без сети. Для того чтоб она была видна в локальной сети нужно соорудить bridge. Для этого понадобится пакет bridge-utils: [cc lang="text"] apt-get install bridge-utils [/cc] Теперь подправил /etc/network/interfaces: [cc lang="text"] auto lo iface lo inet loopback #Inet iface auto eth0 iface eth0 inet dhcp #eth1 - LAN auto br0 iface br0 inet static address 192.168.1.1 netmask 255.255.255.0 bridge_ports eth1 [/cc] Заодно подправил интерфейс в /etc/default/dhcp3-server: [cc lang="bash"] INTERFACES="br0" [/cc] Затем применил настройки: [cc lang="text"] /etc/init.d/network restart [/cc] ...и лишился сети. Сам не понял что и как, но после ребута роутера и сидения перед его консолью все заработало самостоятельно. Хм. Добавил сетевой интерфейс в виртуальную машину: [cc lang="text"] vzctl set 101 --netif_add eth0 --save [/cc] В vzctl версии >3.0.22 можно указать еще и bridge, к которому присоединяться. Но в ubuntu 8.10 версия 3.0.22, и поэтому пришлось дописывать небольшой скрипт. А заодно исправить мелкий баг. Итак, в /etc/vz/conf/101.conf нужно дописать [cc lang="bash"] CONFIG_CUSTOMIZED="yes" VZHOSTBR="br0" [/cc] Теперь создадим скрипт /etc/vz/bin/vznetaddbr [cc lang="bash"] mkdir /etc/vz/bin touch /etc/vz/bin/vznetaddbr chmod 700 /etc/vz/bin/vznetaddbr [/cc] с таким содержимым [cc lang="bash"] #!/bin/bash # /etc/vz/bin/vznetaddbr # a script to add virtual network interfaces (veth-s) in a CT to a bridge on CT0 CONFIGFILE=/etc/vz/conf/$VEID.conf . $CONFIGFILE VZHOSTIF=`echo $NETIF |sed 's/^.*host_ifname=\(.*\),.*$/\1/g'` if [ ! -n "$VZHOSTIF" ]; then echo "According to $CONFIGFILE CT$VEID has no veth interface configured." exit 1 fi if [ ! -n "$VZHOSTBR" ]; then echo "According to $CONFIGFILE CT$VEID has no bridge interface configured." exit 1 fi echo "Adding interface $VZHOSTIF to bridge $VZHOSTBR on CT0 for CT$VEID" /sbin/ifconfig $VZHOSTIF 0 echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/proxy_arp echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/forwarding /usr/sbin/brctl addif $VZHOSTBR $VZHOSTIF exit 0 [/cc] и затем создадим /etc/vz/vznet.conf со следующим содержимым: [cc lang="bash"] #!/bin/bash EXTERNAL_SCRIPT="/etc/vz/bin/vznetaddbr" [/cc] Теперь про баг (устраненный в 3.0.23): в процессе старта при наличии vznet.conf вызывается скрипт /usr/sbin/vznetcfg. Так как в debian/ubuntu используется dash (/bin/sh), то там по чистой случайности нету команды source, а оттого ошибка появляется на строке 20: [cc lang="bash"] [ -f "$VZNETCFG" ] && source "$VZNETCFG" [/cc] Решение - заменить на [cc lang="bash"] [ -f "$VZNETCFG" ] && ."$VZNETCFG" [/cc] Заменить можно через sed (I'm loving it!): [cc lang="bash"] cp -p /usr/sbin/vznetcfg /usr/sbin/vznetcfg.orig sed -i 's/source "$VZNETCFG"/\. "$VZNETCFG"/' /usr/sbin/vznetcfg [/cc] Соответственно теперь выполним [cc lang="bash"] vzctl stop 101 vzctl start 101 brctl show [/cc] В конце мы должны увидеть нечто похожее на veth101.0: [cc lang="text"] bridge name bridge id STP enabled interfaces br0 8000.00024494a7ac no eth1 veth101.0 [/cc] Если все удалось - то можно смело идти в виртуальную машину [cc lang="bash"] vzctl enter 101 [/cc] и делать все чего хочется. По поводу роутинга через другого провайдера: подсмотрев в ifconfig -a внутри виртуальной машинки мак-адрес сетевого интерфейса достаточно в /etc/dhcp3/dhcpd.conf на хост-машине (я же говорил - она еще и роутер) прописать что-то вроде: [cc lang="text"] host gretchin { hardware ethernet 00:18:51:80:8A:D9; fixed-address 192.168.1.101; server-name "gretchin"; option routers 192.168.1.2; } [/cc] где 192.168.1.2 - второй роутер в той же сети. По материалам:
  1. help.ubuntu.com
  2. ubuntuforums.org
  3. Howtoforge
  4. forum.openvz.org
  5. Gentoo Wiki
  6. OpenVZ-Users-Guide.pdf
PS: не забывайте про GNU Screen. Это избавляет от многих проблем, особенно при конфигурации сети.

DDoS

Привалило мне сие несчастье некоторое время назад. Ничем не примечательный сайт, ДДоСят уже неделю. В процессе борьбы выросло небольшое детище на Ruby, именуемое Bananoid. От слова bann. И живет оно на Github'е. Пока оно меня спасает, но непростительно есть 50-100% CPU. Ну что ж, будем лечить. Хочу особо поблагодарить Критика, Devil'a и Andrew за помощь в бою.

PowerDNS URL records and redirector

В PowerDNS есть пара плюшек, которые я раньше не замечал. Одну из них - записи "URL" я сегодня попробовал, настроил и остался вполне доволен. Что же такое URL-запись? Это фича PowerDNS, при помощи которой можно делать редирект домена на заданный URL. Например, запись выглядит как [cc lang="text"] some.domain.com URL http://other.domain.com/some_domain_com [/cc] На самом деле в поле со значением записи может быть ссылка куда угодно. В конфиге сервера нужно указать [cc lang="ini"] ... fancy-records=yes urlredirector=77.120.99.180 ... [/cc] Когда приходит запрос к DNS'у для домена some.domain.com отдается 77.120.99.180, указанный в конфиге, как если бы это была обычная "А"-запись. Браузер отрезолвив имя идет на http://some.domain.com. На этом адресе висит http-сервер (я повесил lighttpd), у которого скрипт лезет в БД и для указанного домена ищет соответствующую ему URL-запись и редиректит браузер туда. Все просто и тривиально. Для lighttpd у меня конфиг дополнился такими строками: [cc lang="ini"] $SERVER["socket"] == "77.120.99.180:80" { $HTTP["host"] =~ "(.*)" { magnet.attract-raw-url-to = ("/var/www/lighttpd/pdns-url-redirector.lua") } } [/cc] То есть все что приходит незамедлительно обрабатывается упомянутым lua-скриптом. Почему lua? С ним работает mod_magnet, и мне было интересно написать этот скриптик. Вот он: [cc lang="lua"] require "luasql.mysql" env = assert (luasql.mysql()) con = assert (env:connect("dnsdb", "dns_user", "dns_pass_for_readonly_records_table", "localhost")) domain = lighty.request["Host"] mysql_replacements = { ["\0"] = "\\0", ["\n"] = "\\n", ["\r"] = "\\r", ["\'"] = "\\\'", ["\""] = "\\\"", ["\026"] = "\\Z", ["\b"] = "\\b", ["\t"] = "\\t", } function fixsql (s) return (string.gsub (tostring (s), "[%z\n\r\'\"\026\b\t]", function (str) return mysql_replacements [str] or str end )) end -- fixsql cur = assert (con:execute( string.format("SELECT content FROM records WHERE `type` = 'URL' AND `name` = '%s'", fixsql(domain) ) ) ) result = cur:fetch() if result then redirect_to = string.format("%s", result) else redirect_to = "http://daemons.org.ua/" end cur:close() con:close() env:close() --lighty.content = { string.format("SELECT content FROM records WHERE `type` = 'URL' AND `name` = '%s'", fixsql(domain) ) } --lighty.header["Content-Type"] = "text/plain" --return 200 lighty.header["Location"] = redirect_to return 301 [/cc] Комментарий начинается с "--". Закоментарены строки для отладки скрипта. Для соединения с мускулем из lua доставил пакет liblua5.1-sql-mysql-2. Скрипт писал долго, но это было интересно. И небесполезно =)
UPD: во избежание DoS/DDoS атаки на мускуль возможны два варианта апгрейда метода: 1. По крону раз в 5 минут генерить sqlite-БД состоящую из одной таблицы из двух полей - domain, target 2. Раз в 5 минут генерить сам скрипт с вынесенными в него в виде хеша записями. Тогда скрипт вообще никуда подглядывать не будет.

Lighttpd and execwrap

В качестве вэб-сервера я использую lighttpd. И сегодня я наткнулся на старую проблему - вэб-сервер работает из-под пользователя www-data, и когда пользователь pupkin загружает какой-то файл - этот файл принадлежит не pupkin'у, а www-data. И через ftp удалить его он не может, и вынужден искать некие web-file-manager'ы. Так вот я погуглил и наткнулся на execwrap. Он очень мелкий, почти ничего ему не нужно стороннего для работы, конфигурировать и использовать его крайне просто (да-да, я знаю про suExec, но он мне не сильно понравился). В результате конфиг для сайта у меня выглядит так: [cc lang="text"] $HTTP["host"] == "pupkin.com" { server.name = "pupkin.com" site-root = "/home/pupkin/www/" + server.name server.document-root = site-root + "/www" accesslog.filename = site-root + "/log/access.log" setenv.add-environment = ( "AWSTATS_FORCE_CONFIG" => server.name ) auth.backend.htpasswd.userfile = site-root + "/awstats.passwd" fastcgi.server = ( ".php" => (( "bin-path" => "/var/www/lighttpd/execwrap", "socket" => "/tmp/" + server.name + ".phpsocket", "max-procs" => 10, "bin-environment" => ( "UID" => "9999", "GID" => "9999", "TARGET" => site-root + "/cgi-bin/php", "CHECK_GID" => "1", "CGI_BIN_DIR" => site-root + "/cgi-bin/", "PHP_FCGI_CHILDREN" => "2", "PHP_FCGI_MAX_REQUESTS" => "5000" ) ))) } [/cc] где 9999 - ID пользователя и группы (у меня они часто совпадают). А в директории /home/pupkin/www/pupkin.com/cgi-bin лежит два файла - симлинк на php.ini и исполняемый файлик "php" следующего содержания: [cc lang="bash"] #!/bin/bash cd $CGI_BIN_DIR exec /usr/bin/php-cgi -c ./php.ini [/cc] Как видите, если надо то конфиг php.ini можно пользователю задать персональный. А файлик php обязательно должен принадлежать этому же пользователю. Когда все сделано - рестартуем lighttpd и смотрим, нет ли в логах ругательств с кодом ошибки 22 - это, как видно из сорса execwrap, несоответствие прав. Enjoy =) UPD: execwrap умер и воскрес тут: http://cgit.stbuehler.de/gitosis/execwrap/

Migration to PowerDNS

Наверняка многие видели сообщение об уязвимости в DNS. Во многих дистрибах линукса весьма скоро появились секьюрити-патчи, которые эту уязвимость исправляли. Уязвимость, может, и не слишком уж страшная, но она напомнила мне о PowerDNS, который я с интересом рассматривал в начале 2008го года. Расматривал я его в основном из-за родной интеграции с MySQL. Мне весьма понравилось как она реализована. Однако у меня были уже рабочие конфиги BIND9, и я просто ленился испытать PowerDNS на собственной шкуре. А зря боялся, как оказалось. Упомянутая уязвимость не задела PowerDNS, и этим мое внимание было вновь привлечено к нему. И переход таки состоялся.

Что дал переход

Во-первых, я получил возможность использовать найденый вчера poweradmin. Штука оказалась немного неуклюжая, но порадовала меня тем, что не надо более ковыряться в конфигах. Во-вторых, при изменении/добавлении/удалении записей в зоне маркер (Serial) в SOA меняется сам. Мелочь, но приятно. В-третьих, теперь можно давать доступ к редактированию зон другим людям. Вот то, что бросилось мне в глаза. А теперь более подробно о самом переходе.

Процесс перехода

PowerDNS состоит из двух компонентов - основной сервер имен и преобразователь имен. Основной сервер имен выдает информацию только о тех записях, которые в нем есть. Преобразователь имен же помогает резолвить то, чего нету непосредственно у данного сервера. Итак, понадобится выполнить следующие действия: [cc lang="text"] apt-get install pdns-server pdns-recursor pdns-backend-mysql [/cc] Желательно во время установки стопнуть bind, потому как dpkg будет ругаться из-за неудачного запуска демона. После установки можно тушить pdns и стартовать bind до окончания миграции. В конфиге /etc/powerdns/pdns.conf надо сделать следующие изменения: [cc lang="text"] ... #allow-recursion=127.0.0.1 ... launch=gmysql ... local-address=_real_external_ip_here_ ... recursor=127.0.0.1 ... [/cc] Этим мы будем передавать все неизвестные запросы от основного сервера к recursor'у. У рекурсора в конфиге стоит local-address=127.0.0.1 по умолчанию, если мне не изменяет память. В /etc/powerdns/pdns.d/pdns.local вписываем [cc lang="text"] gmysql-host=localhost gmysql-port=3306 gmysql-dbname=_username_here_ gmysql-user=_dbname_here_ gmysql-password=_dbpass_here_ gmysql-socket=/var/run/mysqld/mysqld.sock [/cc] Проверяем, есть ли нужная БД и пользователь, и может ли он подключиться к базе. Пример начальной базы есть в /usr/share/doc/pdns-backend-mysql. Советую туда сразу добавить в конец [cc lang="sql"] ALTER TABLE records ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE; [/cc] При его тестировании было замечено что работает он бытрее с таблицами InnoDB. Наверное, из-за большого кеша у этого типа таблиц. Я не стал менять таблицы на MyISAM, однако добавил при создании таблиц default collate utf8_general_ci - для надежности. Потом надо втянуть записи имеющиеся у BIND. Для этого в комплекте есть утилита zone2sql. Рекомендую использовать ее с ключиком --gmysql - так она правильнее работает, создавая записи и в domains и в records. [cc lang="text"] zone2sql --named-conf=/etc/bind/named.conf --gmysql > import.sql [/cc] и вначале выкосил все до основных зон. Потом скормил это mysql'ю. Также можно во всех записях SOA поставить Serial в 0 - так PowerDNS будет вычислять его автоматически. Пробуем стопнуть bind9 и запустить pdns и pdns-recursor. Если все правильно - все взлетит, и в сислоге будут сообщения о состоянии полета. Проверить можно набрав [cc lang="text"] nslookup - dns.yourserver.com [/cc] и попробовать ввести что-то существующее на сервере и что-то несуществующее. У меня основной сервер без recursor'а не хотел отдавать записи типа CNAME при просмотре nslookup'ом. Пришлось установит recursor и настроить их общение. Ну а установка poweradmin для управления сервером не должна вызвать трудностей вообще.

Protecting SSH

Я пытался использовать fail2ban под Linux для отстрела ботов. Но через некоторое время он у меня отказался работать. Почему - не знаю, причины я особо не искал. И вчера заменил его на другое решение - sshguard. Первое впечатление - не слишком хорошее, потому что надо было все настраивать руками. Но немного разобравшись, быстро поставил его на все свои линукс-сервера. Итак, что потребуется: Ubuntu вместе с UFW, syslog-ng. [cc lang="bash"] apt-get install sshguard [/cc] Примечание: на данный момент у меня версия 1.0 которая в пакетах отказалась нормально парсить логи. Потому берем исходники версии 1.1, ./configure --with-firewall=iptables и после сборки стопаем syslog-ng, заменяем /usr/sbin/sshguard новым бинарником (он будет раза в 4 больше) и запускаем syslog-ng вновь. и в /etc/syslog-ng/syslog-ng.conf дописать в конец примерно следующее: [cc lang=text] destination sshguardproc { program("/usr/sbin/sshguard" template("$DATE $FULLHOST $MESSAGE\n")); }; # filter LOG_AUTH messages which also contain "ssh" filter authssh { facility(auth, authpriv); }; # copy filtered logs into the sshguard process log { source(s_all); filter(authssh); destination(sshguardproc); }; [/cc] Это будет передавать все сообщения об аутентификации sshguard'у. Он попытается их блокировать путем создания правил iptables. Однако имея ufw пришлось несколько адаптировать указанный в документации метод. /etc/ufw/before.rules, сразу же под # End required lines добавил [cc lang="bash"] :sshguard - [0:0] [/cc] и далее в списке правил [cc lang="bash"] ... -A ufw-before-input -p tcp --dport 22 -j sshguard #ufw-not-local ... [/cc] Так все на порт 22 будет проходить через эту цепочку. И в ней же sshguard будет отстреливать вредителей. Аналогичную процедуру делаем и для before6.rules с учетом именования цепочек там. Для тех кто еще не запускал ufw следует прописать политики по умолчанию в /etc/default/ufw и выполнить [cc lang="bash"] ufw enable ufw logging off [/cc] и после всего [cc lang="bash"] /etc/init.d/syslog-ng reload [/cc] Enjoy =)