Показаны сообщения с ярлыком linux. Показать все сообщения
Показаны сообщения с ярлыком linux. Показать все сообщения

понедельник, 1 июня 2020 г.

Openvpn-сервер на Linux с клиентами на Mikrotik

У нас имеется:
  • роутер mikrotik с подключением к интернет;
  • vps/vds сервер на Linux с IP адресом N.N.N.N;
мы реализуем:
  • openvpn-сервер на vps c IP адресом 192.168.188.1
  • openvpn-подключение на mikrotik с IP адресом 192.168.188.200


Выбор провайдеров vps и разбор их тарифов выходит за рамки данной статьи. Скажу только, что для openvpn-сервера подойдет любой минимальный тариф за $5 в месяц и даже меньше. Например, самый дешевый дроплет DigitalOcean подходящий вариант.

В качестве дистрибутива Linux я буду использовать Debian 10 Buster.

Поддержка возможностей Openvpn у RouterOS не полная:
  • Нет возможности работать по протоколу UDP, только по TCP.
  • Не поддерживается сжатие трафика.
  • Нет TLS аутентификации.
 Это будем иметь в виду при настройке.

Сначала нужно сгенерировать центр сертификации (CA), сертификаты сервера и клиента. Для этого в Debian 10 используется набор скриптов Easy-RSA версии 3, которая довольно сильно отличается от предыдущей второй версии. Для желающих глубокого погружения в тему отсылаю к официальной документации. Здесь же приведу необходимые команды с кратким пояснением.

Устанавливаем Easy-RSA:
~$ sudo apt install easy-rsa
Подготавливаем CA:
$ sudo make-cadir /etc/easy-rsa
$ sudo -i
# cd /etc/easy-rsa
# ./easyrsa init-pki
# ./easyrsa build-ca nopass
# ./easyrsa gen-dh
# ./easyrsa gen-crl

Создаем сертификат для сервера myserver:
# ./easyrsa gen-req myserver nopass
# ./easyrsa sign-req server myserver
Создаем сертификат для клиента c именем mikrotik:
# ./easyrsa gen-req mikrotik nopass
# ./easyrsa sign-req client mikrotik

Наконец можем установить openvpn:
$ sudo apt install openvpn

Создаем файл конфигурации openvpn сервера:
$ sudo mcedit /etc/openvpn/server/myserver.conf
и вставляем содержимое:
ca /etc/easy-rsa/pki/ca.crt
cert /etc/easy-rsa/pki/issued/myserver.crt
key /etc/easy-rsa/pki/private/myserver.key
dh /etc/easy-rsa/pki/dh.pem
crl-verify /etc/easy-rsa/pki/crl.pem

proto tcp
dev tun
topology subnet
server 192.168.188.0 255.255.255.0
client-config-dir /etc/openvpn/ccd

Далее создаем файл конфигурации для клиента:
$ sudo mkdir /etc/openvpn/ccd
$ sudo mcedit /etc/openvpn/ccd/mikrotik
с содержимым:
ifconfig-push 192.168.188.200 255.255.255.0

После этого запускаем openvpn-сервер:
$ sudo systemctl start openvpn-server@myserver

Если все получилось, то команда покажет статус "active (running)":
$ sudo systemctl status openvpn-server@myserver
Если что то пошло не так, то внимательно изучаем журнал и пытаемся понять, где ошиблись:
$ journalctl -xe
Прописываем автоматический запуск нашего openvpn сервера при старте операционной системы
$ sudo systemctl enable openvpn-server@myserver
Openvpn сервер подготовлен. Переходим к настройке роутера.
Переносим сгенерированные ранее файлы сертификата клиента openvpn на устройство, меню [Files]:
  • /etc/easy-rsa/pki/issued/mikrotik.crt
  • /etc/easy-rsa/pki/private/mikrotik.key


Импортируем в хранилище сертификатов сначала сертификат, затем приватный ключ клиента, меню [System >> Certificates >> Import]:

Добавляем клиентское подключение к openvpn-серверу, меню [PPP >> Interface >> Add >> OVPN Client >> Dial Out]:

Проверяем доступность внутреннего ip-адреса openvpn сервера со стороны клиента, меню [Tools >> Ping]

Готово, vpn подключение настроено и работает.

пятница, 19 декабря 2008 г.

Обновление OpenVPN до версии 2.1

Зачем это понадобилось? Раньше на маршрутизаторе работал в режиме сервера старенький openvpn-2.0.7 используя протокол udp. Работал он хорошо, но была у него проблемка. Маршрутизатор подключен к нескольким провайдерам и соответственно у него имеется несколько сетевых интерфейсов. Так вот, пока у openvpn-сервера отсутствовали подключения openvpn-клиентов, то первый клиент мог подключится через любой сетевой интерфейс. Но чуть появлялось первое клиентское подключение, то все последующие соединения могли быть установлены только через тот же самый интерфейс, т.е. через того же самого провайдера.

Формулируя другими словами, openvpn сервер версии 2.0 не может принимать клиентские udp подключения через разные сетевые интерфейсы.

Предполагаемые варианты решения:

  1. Вместо udp использовать протокол tcp. Но во-первых, существует точка зрения что пропускать протокол tcp поверх протокола tcp это плохо. Во-вторых, хотелось бы избежать изменений в конфигурационных файлах клиентов, потому что их много и некоторые находятся в других городах.
  2. Использовать bridging. По непроверенным данным, если несколько сетевых интерфейсов объединить в один мост, данной проблемы не наблюдается. Зато появляются другие, навроде свободного прохождения широковещательных пакетов между клиентами.
  3. Обновить openvpn на маршрутизаторе до версии 2.1. В описании новых возможностей прямо говорится о решении данной проблемы: "multihome feature to enable UDP-based multihoming of the server on multiple interfaces". Единственный недостаток, на текущий момент OpenVPN 2.1 имеет статус бета-версии 2.1rc15.

Еще раз подчеркну, что выше перечислены только предполагаемые варианты решения. Фактически был опробован и оставлен в работе только вариант №3.

Подробно не буду останавливаться на процессе компиляции openvpn, т.к. пакетная система для каждого дистрибутива linux своя. Универсальный же способ из configure, make и make install, которым грешат многие статьи, гарантированно превращает вашу файловую систему в помойку. Для используемой у меня Slackware я уже описывал процесс пересборки tgz пакетов, как раз на примере openvpn. Всё что необходимо сделать — это выкачать свежий архив исходников и поменять версию openvpn в slackbuild-скрипте.

Обновление openvpn-сервера в целом прошло гладко. Единственное дополнение пришлось внести в конфигурационный файл openvpn-сервера, для совместимости режима вызова внешних скриптов:

# compatibility with OpenVPN 2.0
script-security 3 system

Клиенты заработали с полностью неизмененными, старыми конфигурационными файлами. Только в логах установки соединения для старых OpenVPN 2.0 клиентов стало появлятся сообщение:

Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]:2: topology (2.0.9)

На это сообщение можно смело не обращать внимание до тех пор пока вам не вздумается на сервере OpenVPN 2.1 установить новый параметр конфигурации topology в значение, отличное от значения по умолчанию.

Несмотря на статус бета-версии никаких проблем в работе нового openvpn не наблюдается. Наоборот, новая для OpenVPN 2.1, возможность udp multihome заработала просто прекрасно. Теперь клиенты могут использовать для соединения того провайдера, который им удобнее, дешевле и т.д.

P.S. При сборке пакета для Slackware 9.1 штатный gcc-3.2.3 ниасилил сборку нового openvpn со следующим сообщением об ошибке:

ssl.c:3402:1: directives may not be used inside a macro argument
ssl.c:3401:92: unterminated argument list invoking macro "msg"
ssl.c: In function `key_method_2_read':
ssl.c:3403: invalid type argument of `->'
ssl.c:3408: syntax error before ')' token
make[2]: *** [ssl.o] Error 1

Тут ситуация не совсем понятна. Толи это убогая старая версия препроцессора С, толи разработчики OpenVPN используют приёмы программирования на грани разрешенного. Во всяком случае версия gcc-4.2.4 от новой Slackware 12.2 собрал этот пакет без проблем. Т.к. компилятор языка C написан на языке C, то сначала пришлось скомпилировать пакет с компилятором, обновить пакет gcc, а потом уж компилировать openvpn :)

вторник, 22 июля 2008 г.

IP прокси средствами фаервола Linux

Здесь я покажу пример проксирования IP пакетов средствами межсетевого экрана операционной системы Linux.

Как известно, фаервол в Linux один — netfilter. И так как он давно встроен в ядро linux, то не понадобится устанавливать никаких дополнительных программ. Используемый дистрибутив Linux также не имеет значения.

Сначала несколько слов о том, зачем все это нужно. Например у нас есть две сети: «Сеть A» и «Сеть B» соединенные linux-маршрутизатором. Компьютеру клиента из «Сети A» необходимо получить доступ к серверу в «Сети B». Причем обе сети имеют сложную организацию, не являются простыми ethernet сегментами. У нас имеется контроль над компьютерами клиента, сервером и маршрутизатором. Над остальными частями сетей контроль отсутствует.

Проксирование ip трафика осуществляется с помощью следующих команд, выполняемых на linux-маршрутизаторе:

iptables -t nat -I PREROUTING         \
    -s 172.18.247.24 -d 172.18.55.17  \
    -j DNAT --to-destination 192.168.19.3

iptables -t nat -I POSTROUTING        \
    -s 172.18.247.24 -d 192.168.19.3  \
    -j SNAT --to-source 192.168.19.218

Первая команда создает правило фаервола, заставлюящее менять адрес назначения (destination) пакетов на адрес сервера в «Сети B». Второй вызов iptables меняет адрес источника пакетов (source) на адрес маршрутизатора в «Сети B».

С компьютера клиента нужно будет обращаться на ip адрес маршрутизатора. Например использовать URL http://172.18.55.17 или выполнить команду:

ping 172.18.55.17

Фактически же на запросы будет отвечать не маршрутизатор, а сервер. Причем со стороны сервера будет казаться что запросы поступают от ip адреса маршрутизатора в «Сети B», т.е. от 192.168.19.218. Таким образом в каждой из сетей будут бегать пакеты только между разрешенными хостами в данной сети и все будут жить долго и счастливо.

пятница, 19 октября 2007 г.

Пересборка пакетов Slackware

Иногда приходится пересобирать стандартные пакеты Slackware. Зачем? Причины могут быть разные, но чаще всего из-за того, что в стандартной сборке не указаны необходимые опции компиляции.

Пример 1. Вплоть до Slackware 12 так были вынуждены делать все, кому требовался интерпретатор языка perl с поддержкой многопоточности.
Пример 2. Не так давно я радовался, что в Slackware 12 включен пакет для создания шифрованных туннелей openvpn. К сожалению, когда дело дошло до практики мне он оказался совершенно бесполезен без возможности чтения пароля из файла. Опция конфигурации «auth-user-pass /path/to/file» и отвечает за это параметр компиляции «--enable-password-safe».

Сборка пакетов в Slackware осуществляется с помощью так называемых SlackBuild скриптов. SlackBuild скрипт — это обычный shell-скрипт, который осуществляет распаковку архива исходного кода программы, возможно наложение патчей, конфигурирование, компиляцию и запаковку в пакет Slackware. Все SlackBuild скрипты для стандартных пакетов Slackware открыты для свободного доступа и могут быть получены по адресу ftp://ftp.slackware.com/pub/slackware/slackware-<version>/source/, где <version> — это требуемая версия Slackware, одно из «8.1», «9.0», «9.1», «10.0», «10.1», «10.2», «11.0» или «12.0».

Рассмотрим подробнее процесс пересборки стандартного пакета Slackware на примере пакета openvpn. Сначала выкачиваем всё необходимое для сборки:

root@darkstar:~# mkdir /usr/src/openvpn; cd /usr/src/openvpn
root@darkstar:/usr/src/openvpn# wget --recursive --no-directories \
> ftp://ftp.slackware.com/pub/slackware/slackware-12.0/source/n/openvpn
...

root@darkstar:/usr/src/openvpn# ls -la
total 681
drwxr-xr-x 2 root root    264 2007-10-19 08:32 ./
drwxr-xr-x 6 root root    184 2007-10-19 08:30 ../
-rw-r--r-- 1 root root   1375 2007-06-10 01:25 README
-rw-r--r-- 1 root root 669076 2006-10-01 00:00 openvpn-2.0.9.tar.gz
-rw-r--r-- 1 root root    189 2006-10-01 00:00 openvpn-2.0.9.tar.gz.asc
-rw-r--r-- 1 root root   3729 2007-06-12 04:09 openvpn.SlackBuild
-rw-r--r-- 1 root root   6942 2007-06-12 03:48 openvpn.conf.sample
-rw-r--r-- 1 root root    888 2007-06-10 01:23 slack-desc

Прежде всего здесь нас интересует файл openvpn.SlackBuild. Применим следующий патч:

@@ -23,8 +23,8 @@
 VERSION=2.0.9
 ARCH=${ARCH:-i486}
 BUILD=${BUILD:-1}
-#TAG=${TAG:-_SBo}
-unset TAG
+TAG=${TAG:-_SBo}
+# unset TAG
 CWD=`pwd`
 TMP=${TMP:-/tmp}
 PKG=$TMP/pkg-$PRGNAM
@@ -60,6 +60,7 @@
   --sysconfdir=/etc/openvpn \
   --localstatedir=/var \
   --enable-lzo \
+  --enable-password-safe \
   --build=$ARCH-slackware-linux
 
 make || exit 1

Внесенные изменения:

  1. Включена поддержка поля TAG в наименовании пакета. TAG — это идентификатор создателя пакета, добавляется в самом конце имени файла, после номера сборки. В стандартных пакетах отсутствует, а в дополнительно устанавливаемых крайне желателен.
  2. Добавлена опция конфигурирования «--enable-password-safe», то, собственно ради чего вся пересборка и затевается.

Запускаем процесс пересборки пакета:

root@darkstar:/usr/src/openvpn# chmod +x openvpn.SlackBuild
root@darkstar:/usr/src/openvpn# TAG=nmu OUTPUT=`pwd` ./openvpn.SlackBuild
...

root@darkstar:/usr/src/openvpn# ls -la *.tgz
-rw-r--r-- 1 root root 316375 2007-10-18 17:39 openvpn-2.0.9-i486-1nmu.tgz

Если все прошло без ошибок в текущей директории получим файл openvpn-2.0.9-i486-1nmu.tgz. Обновить уже установленный пакет можно с помощью команды:

root@darkstar:/usr/src/openvpn# upgradepkg openvpn-2.0.9-i486-1nmu.tgz

+==============================================================================
| Upgrading openvpn-2.0.9-i486-1 package using ./openvpn-2.0.9-i486-1nmu.tgz
+==============================================================================

Pre-installing package openvpn-2.0.9-i486-1nmu...

Removing package /var/log/packages/openvpn-2.0.9-i486-1-upgraded-2007-10-18,17:44:08...

Installing package openvpn-2.0.9-i486-1nmu... 
PACKAGE DESCRIPTION:
openvpn: openvpn (secure IP tunnel daemon)
openvpn:
openvpn: OpenVPN is a full-featured SSL VPN which can accomodate a wide range
openvpn: of configurations, including remote access, site-to-site VPNs, WiFi
openvpn: security, and enterprise-scale remote access with load balancing,
openvpn: failover, and fine-grained access-controls.
openvpn:
openvpn: OpenVPN's home on the net is:  http://openvpn.net
openvpn:
Executing install script for openvpn-2.0.9-i486-1nmu...

Package openvpn-2.0.9-i486-1 upgraded with new package ./openvpn-2.0.9-i486-1nmu.tgz.

Все, стандартный пакет Slackware пересобран с необходимыми нам опциями и успешно установлен в системе. Вообще изучение стандартных SlackBuild скриптов это хорошая отправная точка для написания собственных. В конце пара ссылок:

http://www.linuxpackages.net/howto.php
Документация по сборке пакетов для Slackware.
http://www.slackbuilds.org
Репозитарий SlackBuild скриптов для многих программ, официально не входящих в дистрибутив.

четверг, 2 августа 2007 г.

Правильная установка perl модулей в Slackware

Способ описанный в статье «Установка perl модулей» прекрасно работает. Но пользоваться им, значит идти в обход пакетной системы дистрибутива, что влечет следующие недостатки:

  1. Невозможность удалить perl модуль. CPAN.pm только обещает эти возможности в будущем.
  2. Некорректное обновление модулей. При установке новой версии модуля поверх старой, если должны быть удалены некоторые файлы из старой версии, этого сделано не будет. В лучшем случае это означает мусор в файловой системе, в худшем различные неприятные побочные эффекты.
  3. Невозможность получить список уже установленных модулей.
  4. Замусоривание файловой системы, невозможность определить какой файл к какой программе относится.

Предварительная сборка tgz пакетов Slackware позволяет устранить все вышеперечисленные недостатки. Кроме того, сборку пакетов можно производить не на рабочем сервере, а на отдельной машине, например виртуальной. Что в свою очередь даёт преимущества:

  1. Отсутствует необходимость в средствах сборки на рабочем сервере: make, компилятор, линковщик и т.д. Это экономит место на диске сервера и делает его более безопасным.
  2. Экономия времени, если рабочих серверов больше одного. Однажды собранные пакеты можно установить на много серверов. Установка готового пакета занимает секунды, сборка модуля длится гораздо дольше.

Переходим к практической части. Вначале необходимо сконфигурировать утилиту cpan, как написано в уже упомянутой статье «Установка perl модулей». Далее, для автоматизации процесса сборки Slackware пакетов из perl модулей нам поможет замечательная утилита cpan2tgz. С её помощью можно по имени модуля собрать Slackware пакет, а также пакеты всех отсутствующих зависимых модулей. На сайте автора утилиты cpan2tgz выбираем пакет под вашу версию Slackware, скачиваем и устанавливаем его:

root@slack12:~# wget http://software.jaos.org/slackpacks/12.0/cpan2tgz-0.6.2-norch-1.tgz
...
root@slack12:~# installpkg cpan2tgz-0.6.2-noarch-1.tgz
Installing package cpan2tgz-0.6.2-noarch-1... 
PACKAGE DESCRIPTION:
cpan2tgz: cpan2tgz - create Slackware packages from CPAN Perl modules
cpan2tgz: 
cpan2tgz: Packaged by cpan2tgz
cpan2tgz: 
cpan2tgz: cpan2tgz by Jason Woodward 
cpan2tgz: 
cpan2tgz: http://software.jaos.org/
cpan2tgz: 
Executing install script for cpan2tgz-0.6.2-noarch-1...

Чтобы получить пакеты, например, runtime части web фремворка Catalyst можем воспользоватся командой:

root@slack12:~# cpan2tgz Catalyst

Начнется сборка пакетов, при этом большую часть времени работает утилита cpan, скачивая, распаковывая и устанавливая perl модули. После установки модуля cpan2tgz запаковывает его в tgz пакет с соблюдением стандартов. По умолчанию готовые пакеты помещаются в директорию /usr/src . В данном случае список состоит из:

perl-catalyst-runtime-5.7007-noarch-1.tgz
perl-cgi-simple-1.1-noarch-1.tgz
perl-class-accessor-0.31-noarch-1.tgz
perl-class-data-inheritable-0.06-noarch-1.tgz
perl-class-inspector-1.16-noarch-1.tgz
perl-compress-raw-zlib-2.005-i486-1.tgz
perl-compress-zlib-2.005-noarch-1.tgz
perl-data-dump-1.08-noarch-1.tgz
perl-file-modified-0.07-noarch-1.tgz
perl-html-parser-3.56-i486-1.tgz
perl-html-tagset-3.10-noarch-1.tgz
perl-http-body-0.9-noarch-1.tgz
perl-http-request-ascgi-0.5-noarch-1.tgz
perl-io-compress-base-2.005-noarch-1.tgz
perl-io-compress-zlib-2.005-noarch-1.tgz
perl-libwww-perl-5.806-noarch-1.tgz
perl-module-pluggable-3.6-noarch-1.tgz
perl-path-class-0.16-noarch-1.tgz
perl-sub-uplevel-0.14-noarch-1.tgz
perl-test-exception-0.25-noarch-1.tgz
perl-text-simpletable-0.03-noarch-1.tgz
perl-tree-simple-1.17-noarch-1.tgz
perl-tree-simple-visitorfactory-0.10-noarch-1.tgz
perl-version-0.7203-i486-1.tgz
perl-yaml-0.65-noarch-1.tgz

Теперь можно скопировать эти пакеты на рабочий сервер и установить c помощью команды:

root@slack12:~# installpkg *.tgz

Всё.

четверг, 26 июля 2007 г.

Slackware 12

Наконец-то добрался до Slackware 12. Как обычно, сначала любую новую операционую систему я пробую устанавливать в виртуальной машине. Инсталяция прошла гладко, ни на шаг не отступая от классической схемы установки Slackware — консоль, разбиение диска с помощью fdisk, выбор пакетов для установки из списка. Как обычно выбираю абсолютный минимум необходимых пакетов. Отметил, что теперь по умолчанию предлагается форматировать разделы диска в ext3, вместо raiserfs как было раньше. Порадовало наличие пакета openvpn. До 12-ой версии Slackware похоже был последним дистрибутивом, содержащим веб сервер apache1. Теперь он заменен сразу на apache2.2!, кто-то наверное обрадуется, а мне немного грустно, т.к. возможностей apache1 мне хватало абсолютно.

Для каждой виртуальной машины я выделяю 48Мб памяти. Для Slackware с версий 9.1 по 11 этого вполне хватало не только для загрузки, но и для адекватной работы в качестве девелоперской машины LAMP сервером, естественно без иксов. Но вот загружается Slackware 12 и первое впечатление — дааа, потяжелела слакварь, курсор в консоле еле ворочается, память занята вся и ещё немало подкачки отъела.

Однако проблема довольно быстро решается:

  1. Отключаем появившиеся в Слаке новомодные сервисы, необходимые только для десктопа. Для этого снимаем атрибут исполняемого файла с:

    • /etc/rc.d/rc.hald
    • /etc/rc.d/rc.messagebus
    • /etc/rc.d/rc.udev
  2. В /etc/rc.d/rc.modules отключаем загрузку ненужных модулей ядра, а именно:

    # /sbin/modprobe psmouse proto=imps
    # /sbin/modprobe pcspkr
    # /sbin/modprobe -q parport_pc 2> /dev/null
    # /sbin/modprobe agpgart 2> /dev/null
    # /sbin/modprobe capability

    После этого в памяти оставался ещё не нужный нам модуль ядра ipv6. Его отключаем добавлением следующих строчек в /etc/modprobe.d/blacklist:

    alias net-pf-10 off
    blacklist ipv6
  3. Многие знают, что Slackware 12, тоже одним из последних, перешел на ядро 2.6. Но не все знают, что теперь в Slackware 12 есть две сборки ядра, называемые huge и generic. По умолчанию грузится huge, где большинство модулей вкомпилены в ядро. Так не возникают проблемы при загрузкой с разных файловых систем, но это ядро занимает много памяти. Чтобы переключится на generic ядро скорее вам всего нужно будет собрать initrd, содержащий как минимум модуль ядра для корневой файловой системы. Краткие объяснения и инструкция содержатся в файле /boot/README.initrd. В моём случае понадобилось выполнить следующую команду:

    mkinitrd -c -k 2.6.21.5-smp -m ext3

    Добавляем пункт загрузки с generic ядра в меню lilo, для этого вставляем строки в файл /etc/lilo.conf:

    image = /boot/vmlinuz-generic-smp-2.6.21.5-smp
      initrd = /boot/initrd.gz
      root = /dev/XXXN
      label = Linux-generic
      read-only

После этих действий система стала вести себя более отзывчиво :-). 48 Мб опять хватает. В общем я доволен. Мы получили дистрибутив, который с одной стороны идет в ногу со временем, включающий последние достижения Open Source, обновленные версии всех программ. С другой стороны Slackware строго придерживается собственных традиций, устанавливаются оригинальные версии программ, без патчей. Позволяется максимально возможную гибкость в настройке системы. В общем, я всё больше убеждаюсь, что Slacware лучшая ОС для серверных решений.

понедельник, 16 июля 2007 г.

Фильтрация спама для Qmail c помощью SpamAssassin

Все написанное производилось для Slackware 9.1. Описание установки и настройки Qmail, а также описание установки SpamAssassin не приводится. Почта пользователей сервера myserver.ru хранится в домашних каталогах пользователей в Maildir формате.

Спам — достал. Способов борьбы с ним тьма, но что-то же выбрать надо. Что мне понравилось в SpamAssassin, это отсутствие необходимости постоянно в ручную обучать его новому спаму, чтобы он работал эффективно. То есть, при желании это можно делать, но пользователей обучить нереально, а сисадмину и так есть чем занятся :-).

Для работы SpamAssassin использует огромную базу правил. Каждому правилу назначается определенный вес. При проверке письма веса всех «сработавших» правил суммируются. Если сумма превысила пороговое значение, письмо помечается как спам. База всех правил постоянно пополняется, весовые коэффициенты уточняются. SpamAssassin предоставляет утилиту для обновления базы правил, которую можно запускать в автоматическом режиме по расписанию.

Есть два способа обращаться к SpamAssasin:

  1. в режиме утилиты командной строки — spamassasin,
  2. в режиме клиента spamc для демона spamd.

Второй вариант работает быстрее, т.к. не тратится время на запуск и инициализацию программы. Однако расходует больше памяти, т.к. демон должен быть постоянно запущен. Как показала практика, SpamAssassin достаточно тяжел в работе, на принятие решения по одному письму уходит от 2-х до 7 секунд работы программы. А памяти на серверах обычно много и она дешева. Поэтому используем второй вариант. Для автоматического запуска демона spamd при загрузке сервера прописываем в файле /etc/rc.d/rc.M строчки:

# Start the SpamAssasin daemon:
if [ -x /etc/rc.d/rc.spamd ]; then
  /etc/rc.d/rc.spamd start
fi

Вики SpamAssasin предлагает три способа интеграции с qmail:

  1. Через программу Simscan глобально на этапе приема письма по smtp;
  2. Через программу qmail-scanner глобально на этапе пересылки/доставки письма;
  3. Через скрипт ifspamh и редактирование файла ~/.qmail для индивидуального почтового ящика на этапе локальной доставки письма;

Используем третий способ, как самый безопасный для экспериментов на работающем сервере. Устанавливаем скрипт ifspamh:

cd /usr/local/bin
wget http://www.gbnet.net/~jrg/qmail/ifspamh/ifspamh
chmod +x ifspamh

Скрипт ifspamh «из коробки» не заработал, пришлось немного подпилить. Вместо оболочки ksh, которую я не устанавливал прописал запуск из bash. На работоспособность скрипта это не повлияло. Подправил пути поиска утилит spamc, forward (входит в qmail) и 822field. Утилита 822field входит в состав пакета mess822. Мне повезло, пакет mess822 для Slackware 9.1 был на linuxpackages.net. А если бы не было, так не беда — сам бы собрал, просто ленив я стал...

Для каждого пользователя, которому нужна фильтрация спама редактируем файл ~/.qmail:

|/usr/local/bin/ifspamh spam@myserver.ru
./Maildir/

Теперь весь обнаруженный спам будет пересылаться на ящик spam@myserver.ru, эдакий спамоотстойник сервера. Доставки в локальный ящик не будет. Письма не удаляются, администратор всегда сможет найти ложно отфильтрованное письмо в отстойнике. Теперь проверим работу обновления базы правил SpamAssassin, для этого используется утилита sa-update. Запустим её без параметров, если все пройдёт успешно, то в каталоге /var/lib/spamassassin/<version>/ появятся обновленные базы правил. Чтобы обновления вступили в силу, демон spamd необходимо перезапустить. Прописать запуск sa-update в автоматическом режиме по расписанию я пока не решился. Но тем не менее crontab изменить пришлось:

# 0 2 * * * sa-update && /etc/rc.d/rc.spamd restart
0 3 * * * find ~spam/Maildir -ctime +31 -type f -exec rm {} \;

Как вы заметили, я добавил очистку ящика spam@myserver.ru, чтобы этот отстойник не переполнился. Если письмо в течении месяца никому так и не понадобилось, то его можно спокойно удалить.

За прошедший (не очень продолжительный) период работы не было ни одного ложного срабатывания. Эффективность обнаружения спама около 97%. Всё.

пятница, 29 июня 2007 г.

Оптимизация загрузки Slackware

Сразу обозначу с какой целью производится оптимизация. В конторе, где я работаю, Slackware Linux используется на большинстве серверов. Для тестирования решений, разработки новых программ, сборки slackware пакетов я также использую Slackware, но только внутри виртуальной машины. Соответственно вся оптимизация применяется для виртуальной машины. Особенности работы:
  • не используется графический режим, устанавливаются и работают только консольные программы. Фреймбуфер тоже не используется.
  • доступ только через ssh, как потом на рабочем сервере.
Всё сказанное здесь верно для всех известных версий Slackware, статья тестировалась на Slackware 11. Можно использовать описанные здесь приёмы и для рабочих машин, но делать это с осторожностью.
  1. Настройка загрузчика lilo. Произвоится редактированием файла /etc/lilo.conf. Задаем параметры:
    # графический режим консоли - текстовый
    vga = normal
    # задержка перед автоматической загрузкой - 5 секунд
    timeout = 50
    
    Если не планируется пересобирать ядро или менять параметры его загрузки, можно вообще отключить вывод меню:
    # prompt
    
    После изменения /etc/lilo.conf, не забудьте запустить lilo, чтобы изменение настроек вступило в силу.
  2. Отключение лишних консолей. Редактируем файл /etc/inittab. Оставим одну из шести консолей, остальные комментируем:
    c1:1235:respawn:/sbin/agetty 38400 tty1 linux
    # c2:1235:respawn:/sbin/agetty 38400 tty2 linux
    # c3:1235:respawn:/sbin/agetty 38400 tty3 linux
    # c4:1235:respawn:/sbin/agetty 38400 tty4 linux
    # c5:1235:respawn:/sbin/agetty 38400 tty5 linux
    # c6:12345:respawn:/sbin/agetty 38400 tty6 linux
    
  3. Отключение загрузки неиспользуемых модулей ядра. Смотрим файл /etc/rc.d/rc.modules. Здесь можно отключить загрузку модулей agp и эмуляции scsi:
    # /sbin/modprobe agpgart
    ...
    # /sbin/modprobe ide-scsi
    
  4. Отключение неиспользуемых демонов. С помощью комманды: chmod -x /etc/rc.d/rc.xxxxx снимаем атрибут исполняемого файла, со всех файлов в каталоге /etc/rc.d, кроме:
    /etc/rc.d/rc.4
    /etc/rc.d/rc.6
    /etc/rc.d/rc.K
    /etc/rc.d/rc.M
    /etc/rc.d/rc.S
    /etc/rc.d/rc.inet1
    /etc/rc.d/rc.inet2
    /etc/rc.d/rc.modules-2.4.33.3
    /etc/rc.d/rc.netdevice
    /etc/rc.d/rc.sshd
    /etc/rc.d/rc.syslog
    
  5. Отключение неиспользуемых демонов 2. Чтобы отключить демон отсроченного запуска комманд и обновление индекса шрифтов, комментируем следующие строчки в файле /etc/rc.d/rc.M :
    # Start atd (manages jobs scheduled with 'at'):
    # if [ -x /usr/sbin/atd ]; then
    #   /usr/sbin/atd -b 15 -l 1
    # fi
    ...
    # Update the X font indexes:
    # if [ -x /usr/X11R6/bin/fc-cache ]; then
    #   echo "Updating X font indexes:  /usr/X11R6/bin/fc-cache"
    #   /usr/X11R6/bin/fc-cache
    # fi
    
  6. Отключение демонов 3. Для экстремалов. Можно (но не рекомендуется) отключить демона журналирования syslog:
    chmod -x /etc/rc.d/rc.syslog
    
    Тогда отпадает надобность в демоне запуска заданий по расписанию, используемом для ротации журналов. Комментируем строчки в файле /etc/rc.d/rc.M :
    # Start crond (Dillon's crond):
    # If you want cron to actually log activity to /var/log/cron, then change
    # -l10 to -l8 to increase the logging level.
    # if [ -x /usr/sbin/crond ]; then
    #   /usr/sbin/crond -l10 >>/var/log/cron 2>&1
    # fi
    
Теперь остается перезагрузить виртуальную машину и убедится что всё работает. Самое время сделать снимок состояния виртуальной машины для многократного использования в будущем.