Кратко, rootkit — это набор программ призванный спрятать некую негативную деятельность или присутствие взломщика в системе.

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

Установка rkhunter

Будем устанавливать rkhunter 1.4.0 под Debian 7.

В общем-то, установка не должна составить трудностей, так как оказалось, что rkhunter версии 1.4.0-1 есть в официальных репозиториях Debain 7. Устанавливаем:

# apt-get install rkhunter

Либо можно установить вручную скачав архив с официального сайта:

cd ~ wget http://sourceforge.net/projects/rkhunter/files/rkhunter/1.4.0/rkhunter-1.4.0.tar.gz tar xfz rkhunter-1.4.0.tar.gz cd rkhunter-1.4.0 sh installer.sh --layout default --install

Вывод последней команды:

Checking system for:
Rootkit Hunter installer files: found
A web file download command: wget found
Starting installation:
Checking installation directory «/usr/local»: it exists and is writable.
Checking installation directories:
Directory /usr/local/share/doc/rkhunter-1.4.0: creating: OK
Directory /usr/local/share/man/man8: creating: OK
Directory /etc: exists and is writable.
Directory /usr/local/bin: exists and is writable.
Directory /usr/local/lib: exists and is writable.
Directory /var/lib: exists and is writable.
Directory /usr/local/lib/rkhunter/scripts: creating: OK
Directory /var/lib/rkhunter/db: creating: OK
Directory /var/lib/rkhunter/tmp: creating: OK
Directory /var/lib/rkhunter/db/i18n: creating: OK
Installing check_modules.pl: OK
Installing filehashsha.pl: OK
Installing stat.pl: OK
Installing readlink.sh: OK
Installing backdoorports.dat: OK
Installing mirrors.dat: OK
Installing programs_bad.dat: OK
Installing suspscan.dat: OK
Installing rkhunter.8: OK
Installing ACKNOWLEDGMENTS: OK
Installing CHANGELOG: OK
Installing FAQ: OK
Installing LICENSE: OK
Installing README: OK
Installing language support files: OK
Installing rkhunter: OK
Installing rkhunter.conf: OK
Installation complete

Прочие параметры инсталлятора rkhunter вы можете узнать воспользовавшись командой:

sh installer.sh --help

Каким способом установки пользоваться — решать вам. Первый способ проще, второй потенциально позволяет установить более свежую версию.

Также стоит установить программу unhide, которая позволяет искать скрытые процессы и порты:

apt-get install unhide

Настройка rkhunter

Будем считать, что использовали способ установки из репозитория.

Конфигурационные файлы:

/etc/default/rkhunter — можно настроить периодические задачи (обновление, проверка, отчеты),
/etc/rkhunter.conf — основной конфигурационный файл

Справочная информация может быть найдена в директории /usr/share/doc/rkhunter и с помощью команды man rkhunter. Кое-какие скрипты есть в директории /usr/share/rkhunter.

Параметры, которые можно задать в /etc/default/rkhunter (параметры могут принимать значения true или false):

CRON_DAILY_RUN="« — по умолчанию значение true. Позволяет ежесуточно запускать проверку.
CRON_DB_UPDATE=»" — по умолчанию значение true. Позволяет включить еженедельные обновления баз.
DB_UPDATE_EMAIL="false" — отправлять ли отчеты об еженедельном обновлении баз. По умолчанию — false.
REPORT_EMAIL="root" — адрес электронной почты, куда отправлять отчеты. По умолчанию — root.
APT_AUTOGEN="false« — позволяет включить автоматическое обновление баз.
NICE=»0" — позволяет управлять приоритетом процесса.
RUN_CHECK_ON_BATTERY="false" — следует ли проводить автоматические проверки в случае работы компьютера от батареи.

В /etc/rkhunter.conf можно поправить следующие настройки:

PKGMGR=DPKG — судя по документации, в Debian данный параметр особого эффекта не дает, так что можно оставить по умолчанию.
DISABLE_TESTS="apps" — отключает проверку актуальности версий софта, с этим прекрасно справляются разработчики Debian.
SUSPSCAN_DIRS="/tmp /var/tmp" — указываем в какой директории искать подозрительные файлы.
OS_VERSION_FILE="/etc/debian_version" — где искать файл с версией ОС.
USE_LOCKING=1 — позволяет спользовать блокировку для защиты от ошибок в случае если запущено несколько процессов rkhunter в Debian. Может пригодиться, если вы запускаете rkhunter автоматически с помощью cron.
DISABLE_UNHIDE=2 — отключает использование утилиты unhide.rb написанной на ruby.

Подготовка rkhunter к первому поиску руткитов

Перед выполнением проверки нужно выполнить два действия.

Прежде всего, необходимо создать базу знаний о текущих файлах, чтобы потом было с чем сравнивать. То есть необходимо быть уверенным, что система чистая. Лучшим вариантом будет выполнить это действие сразу после настройки системы. База создается командой:

rkhunter --propupd

Базу можно будет найти по следующему пути: /var/lib/rkhunter/db/rkhunter.dat

Далее требуется обновить базу знаний, содержащую, в том числе, информацию о новых руткитах. Следует выполнить после предыдущей операции и перед первой проверкой. Стоит периодически обновлять базу знаний, но это можно делать не слишком часто. Команда:

rkhunter --update

Первый запуск

rkhunter -c -sk

Результат:

System checks summary
=====================

File properties checks...
Files checked: 135
Suspect files: 0

Rootkit checks...
Rootkits checked : 309
Possible rootkits: 0

Applications checks...
All checks skipped

The system checks took: 6 minutes and 21 seconds

All results have been written to the log file (/var/log/rkhunter.log)

One or more warnings have been found while checking the system.
Please check the log file (/var/log/rkhunter.log)

На самом деле вывод более подробный, представлена только финальная часть. Как видно, лог можно найти по пути /var/log/rkhunter.log

Возможные ключи

Команды

-c, --check — выполнить поиск руткитов, результат будет выведен на стандартный вывод, а также в лог-файл.
--unlock — эта комманда просто удаляет lock-файл.
--update — будет произведена проверка на наличие обновления базы знаний. Для работы данной команды требуется, чтобы в системе был установлен один из браузеров командной строки, к примеру, wget или lynx. Желательно выполнять данную команду с некой периодичностью. При использовании в cron стоит использовать также опцию --nocolors.
--propupd [{filename | directory | package name},...] — команда позволяющая добавить в базу данных о файлах системы информацию о файле, всех файлах в директории или пакете. Это необходимо для работы одного из тестов, который сравнивает файл в текущем состоянии с тем, которое было при создании базы. Помните, добавляемый в базу файл должен быть заведомо не зараженным.
--versioncheck — эта команда заставляет rkhunter проверить наличие новой версии программы для поиска руткитов. Браузер командной строки должен присутствовать в системе. Если используется в cron желательно использовать опцию --nocolors.
--list [tests | {lang | languages} | rootkits | perl | propfiles] — эта команда выводит некоторые поддерживаемые возможности программы. Tests — выведет названия доступных тестов, languages — покажет поддерживаемые языки, rootkits — отобразит списки руткитов из базы rkhunter. Perl — выведет список модулей perl которые могут понадобиться в работе rkhunter, список этот не обязательный, но желательный. Установить модули perl можно с помощью команды cpan или утилиты dh-make-perl, которую нужно устанавливать отдельно. propfiles — отобразит список имен файлов, которые использовались для генерации базы файлов. Если никаких опций не задано, то будут показаны все списки кроме propfiles.
-C, --config-check — будет проведена проверка конфигурационных файлов. Проверяются только включенные опции (enabled). Чтобы проверить все опции можно указать --enable all --disable none в командной строке.
-V, --version — будет выведена версия rkhunter.
-h, --help — эта команда отобразить экран с краткой справкой.

Параметры

Различных параметров достаточно много, поэтому мы посмотрим только часть из них. Те, которые показались автору статьи наиболее полезными.

--appendlog — в случае использования данного параметра лог /var/log/rkhunter.log будет дополнен, а не перезаписан. По умолчанию, после того, как rkhunter отработает, основной лог перезаписывается, а предыдущее его содержимое сохраняется в файле rkhunter.log.log, при чем, хранится только один.
--cs2 — основная цветовая схема рассчитана на черный фон. Если же результат будет выведен на экран с белым фоном, то можно использовать альтернативную цветовую схему.
--cronjob — при указании данного параметра будут использованы следующие опции: --check, --nocolors и --skip-keypress, а также не будет вывода в стандартный выход. Поэтому в сочетание с данным параметром можно использовать --report-warnings-only.
--display-logfile — после того, как rkhunter закончит свою работу вывести содержимое лога. Вообще говоря, лог содержит более подробную информацию о найденных проблемах.
--lang — можно указать на каком языке выводить информацию в процессе проверки. Список доступных языков можно получить командой rkhunter --list lang. По умолчанию используется английский.
--logfile [file] — позволяет переопределить файл в который будет писаться лог. При необходимости ничего не писать в лог, можно задать в качестве пути /dev/null.
--nocolors — этот параметр позволяет включить черно-белый режим вывода результатов работы.
--nolog — подавляет запись чего-либо в лог.
--quiet — подавляет любой вывод. Может быть полезно при проверке только кода выхода. То есть если rkhunter используется из скрипта, к примеру.
--report-warnings-only — при этом выводятся только предупреждения. Может быть полезно при запуске через cron. Таким образом, предупреждения будут видны при подключении к серверу с помощью KVM, к примеру.
--sk, --skip-keypress — по умолчанию rkhunter после некоторых наборов тестов просит нажать клавишу “Ввод”. Чтобы таких запросов не поступало можно использовать эту опцию.
--syslog [facility.priority] — по умолчанию в syslog ничего не пишется. Если требуется отмечать время начала и окончания тестирования, можно использовать данный параметр.
--verbose-logging — этот параметр может использоваться, чтобы некоторые тесты писали в лог более подробную информацию. Это может пригодиться для повторного прогона, когда не понятно из-за чего возникло предупреждение. Требует дополнительного времени.

Автоматический поиск руткитов

Чтобы rkhunter начал автоматически проверять систему ежесуточно (у меня проверка начинается в 6:25) достаточно в файле /etc/default/rkhunter установить значение параметраCRON_DAILY_RUN равным true. В данном случае будет использоваться следующая команда:

/usr/bin/rkhunter --cronjob --report-warnings-only --appendlog

Как мы помним, --cronjob подразумевает под собой параметры --check, --nocolors и --skip-keypress. То есть в данном случае rkhunter запускается для проверки системы в черно-белом режиме отображения, не запрашивает каких-либо нажатий клавиш, при этом в консоль выводятся только предупреждения и лог будет дописываться, а не перезаписываться. Так как со временем файл лога будет увеличиваться  в размере, то не забудьте настроить его ротацию.

Если же вы хотите проводить поиск руткитов по другому расписанию и с другими параметрами, то команду запуска можно добавить в cron вручную.

Организация отказоустойчивой системы хранения данных — это, естественно, RAID. Стоит дать некоторое определение RAID: избыточный (резервный) массив собранный из независимых дисков. Рассматривая возможности покупки аппаратных RAID массивов, всегда приходится сталкиваться с достаточно высокой ценой. Однако, при выборе хранилища данных можно рассмотреть и другие альтернативы. Так, например, одно из возможных решений может быть реализовано на Linux (Debian) с применением недорогих комплектующих. Вот такое решение программного RAID массива мы сегодня и рассмотрим.

Постановка задачи:

  • Организовать отказоустойчивую систему хранения данных;

Условия:

  • быстрое развёртывание;
  • лёгкое управление;
  • минимальные потери при аппаратных сбоях;
  • возможность быстрого ремонта (замены) при аппаратных сбоях;
  • низкая стоимость;

Условия, которые мы поставили вполне выполнимы если мы будем использовать программный RAID массив. Для решения этой задачи не требуется высокопроизводительного и дорогостоящего оборудования, а также платного программного обеспечения.

Решение:

  • системный блок с установленным необходимым количеством жёстких дисков (наверняка, в закромах найдется старенький системник, можно использовать и новый с SATA дисками. Все зависит от того, какой дисковый объем и какая надёжность вам нужна)
  • операционная система Linux (почему именно она? Просто сейчас занимаюсь именно ей. Она бесплатна, всегда можно найти информацию по настройке и внедрению, открытые исходные коды)

Установим ее и приступим к «творению».

 apt-get install mdadm

Во время установки система попросит параметры для обслуживания уже установленных массивов или для будущих. Чтобы не заморачиваться оставьте предложенные параметры по-умолчанию (all). Далее необходимо подготовить жёсткие диски для соединения в массив, определимся, что будем использовать массив класса RAID 1. Один из наиболее надежных (полное зеркалирование) и не дорогое решение.

root# fdisk /dev/sdb 
Command (m for help):n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-41610, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-41610, default 41610):
Using default value 41610

Раздел у нас создан. Посмотрим его параметры.

Command (m for help): p
Disk /dev/sdb: 21.4 GB, 21474836480 bytes
16 heads, 63 sectors/track, 41610 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0xda185917
Device Boot Start End Blocks Id System
/dev/sdb1 1 41610 20971408+ 83 Linux

Индификатор созданного раздела — 83, это стандартный раздел Linux. Он нам не подходит. Его необходимо сменить на «fd» (linux raid autodetect). Полный список можно посмотреть указав «L» вместо «fd», потом система задаст повторный вопрос.

Command (m for help): t
Selected partition 1
Hex code (type L to list codes):fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Раздел создан, указан необходимый тип, для проверки можно ввести команду «p» и посмотреть результат, если все устраивает, то пора записать разделы на диск и приступить ко второму жёсткому диску.

Command (m for help): p
Disk /dev/sdb: 21.4 GB, 21474836480 bytes
16 heads, 63 sectors/track, 41610 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0xda185917
Device Boot Start End Blocks Id System
/dev/sdb1 1 41610 20971408+ fd Linux raid autodetect
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

Аналогично готовим второй жёсткий диск

После завершения подготовки дисков можно приступать к непосредственному созданию массива. Создание RAID массива выполняется с помощью программы
mdadm (ключ --create). Добавим опцию --level, для указания типа RAID массива, который хотим получить, в нашем случае первого (1) уровня. С помощью ключа --raid-devices укажем устройства, поверх которых будет собираться RAID массив.

root#  mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdd1 
mdadm: size set to 20971328K
mdadm: array /dev/md0 started.

Если во время сборки не хватает физических дисков, но вы планируете добавить их позже, т.е. собрать не полный RAID массив (degraded) можно указать слово missing вместо имени устройства. Для RAID 5 это может быть только один диск, для RAID 6 — не более двух, для RAID 1 сколько угодно, но должен быть как минимум один рабочий. Массив создан, теперь необходимо убедится, что собранный RAID массив собран правильно.

root#  cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]

md0 : active (auto-read-only) raid1 sdd1[1] sdb1[0]       20971328 blocks [2/2][UU]          resync=PENDING unused devices: <none>

Система сообщает, что создан RAID 1 массив, в который входят два устройства - sdd1 и sdb1. Проверка состояния нашего массива показывает [UU] — означает, что все в порядке, а ([_U] или [U_] означает, что массив поврежден. Имя нашего RAID массива md0.

Файловая система создана, но она еще не готова принимать к размещению данных. Можно посмотреть статус массива.

root# cat /proc/mdstat 
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sdd1[1] sdb1[0]
      20971328 blocks [2/2] [UU]
      [==>..................]  resync =10.7%(2260416/20971328) finish=8.4minspeed=36824K/sec
unused devices: <none>

Теперь нужно создать файл конфигурации нашего RAID массива. Система сама не запоминает какие RAID массивы ей нужно создать и какие компоненты в них входят. Эта информация находится в файле конфигурации mdadm.conf. Параметры, которые следует добавить в этот файл, можно получить при помощи команды mdadm --detail --scan --verbose.

root# mdadm --detail --scan --verbose 
ARRAY /dev/md0 level=raid1 num-devices=2 metadata=00.90 UUID=ddddad18:ae4cb9be:cb5f3c5d:d16ad809
 devices=/dev/hdb1,/dev/hdd1

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

root# mdadm --detail --scan --verbose | awk '/ARRAY/ {print}' >> /etc/mdadm/mdadm.conf 

Настройка уведомления о состоянии RAID массива по email

Создаем новые диски с использование LVM

Теперь все готово.

 

 

apt-get install openssh-server rkhunter ssmtp mc htop iftop iotop nmap unhide lsb-release iptraf sshguard

 

для просмотра текущей нагрузки на сеть

iptraf

Поверяем установленную версию

cat /etc/issue

lsb_release -a

cat /etc/lsb-release

cat /etc/debian_version

Создание программного RAID на Debian

 Установка локалей под Debian

 Как научить сервер сообщать вам по почте о логине root

Защита ssh от брутфорса

Настройка автозагрузки правил iptables в Debian

для увеличения количества доступной памяти под Linux

Мониторинг работы системы

Exim 4: ACL and others to reject spams

 

Introduction

This article is an explained example of exim 4 ACL configuration. For a larger point of view see «Spam Filtering for Mail Exchangers».

With this configuration we got approximately (for one person) 1 spam per day and we reject 20 per day (see the exim rejectlog file).

The context is a host server with a public IP (82.224.147.80, www.maretmmanu.org), wich is also used as local mail server:

######################################################################
#                    MAIN CONFIGURATION SETTINGS                     #
######################################################################
# If exim is used localy in batch mode (exim4 -bs) then "$host" is empty, the ": :" adds the empty string.
hostlist   own_hosts = 127.0.0.1 : : 192.168.113.114 : 192.168.113.113 : 82.224.147.80
domainlist public_domains = maretmmanu.org

Remote host IP checking

We allow connections from our own hosts and a white-list (Some hosts from big internet providers) with no more check. We refuse connections with some hosts (marketing company etc).

acl_check_host:
        accept
                hosts = +own_hosts : /etc/exim4/filters/host_white.list

        deny
                log_message = match host_reject.list
                hosts = /etc/exim4/filters/host_reject.list
        accept

Remote host IP checking by DNS black-list

Hosts listed by the dns list <a style="color: purple;" href="http://www.spamhaus.org/sbl/" rel="nofollow" target="_blank">sbl-xbl.spamhaus.org</a>"" are spammers or relays for spams. Often if you refuse the connection for one of these hosts then a new try is done by another relay some seconds later (see my old reject log). A better solution is to do the rejection when the RCPT is received. Then the spammer does not try again (see the new reject log).

acl_check_rcpt:
 . . .
        drop
                log_message = match sbl-xbl.spamhaus.org
                dnslists = sbl-xbl.spamhaus.org

HELO checking

Often spammers send for the HELO argument the name or the IP of your host. Here my own domain is maretmmanu.org"" and my own IP is 82.224.147.80.

acl_check_helo:
        accept
                hosts = +own_hosts

	# If the HELO pretend to be this host
	deny	condition = ${if or {
					{eq {${lc:$sender_helo_name}}{maretmmanu.org}}
					{eq {${lc:$sender_helo_name}}{82.224.147.80}}
				    } {true}{false} }
        # by default we accept
        accept

Sender checking

We refuse some senders, from some marketing companies.

acl_check_sender:
        deny    senders = /etc/exim4/filters/sender_reject.list
        accept

Recipient: emails addresses to catch spams

You can publish a sacrified email address in a web page to trap spammers (some spammers crawl other web pages to get emails). When this email address matches then an error is returned and all the message reception is droped. There are changes that the spammer software will not retry with this recipient removed.

When you write to a suspicious company wich could send you spam or when you write in a newsgroup, you can use a special email, with date (like echant-td-n040531@maretmmanu.org) or with an included identifier (like echant-tr-lemonde@maretmmanu.org). Then if you receive spam for this email you can put it in the drop list (in this example: /etc/exim4/filters/recipients_drop.list).

acl_check_rcpt:
 . . .
        drop
                log_message   = match recipients_drop.list.
                recipients = /etc/exim4/filters/recipients_drop.list

I use this script in cron.daily/ to update my emails with a date incorporated. The letter before the date is used to trace the origine (web, news, email).

#!/bin/bash

# Update my email wich include the today date
set -e
T=$(tempfile)
D=$(date '+%y%m%d')

function mod_file {
    EMAIL="$1"
    LETTRE="$2"
    CONF="$3"
    if [ -f "$CONF" -a -r "$CONF" ]; then
        lockfile-create "$CONF"
        sed "s/${EMAIL}-td-${LETTRE}[0-9]{6}@maretmmanu.org/${EMAIL}-td-${LETTRE}${D}@maretmmanu.org/g" <"$CONF" >"$T"
        cp "$T" "$CONF"
        lockfile-remove "$CONF"
    fi
}

# The first line will replace echant-td-n040625@maretmmanu.org
# with echant-td-n040626@maretmmanu.org
mod_file echant n /home/manu/.kde/share/config/knoderc
mod_file echant e /home/manu/.sylpheed/accountrc
mod_file echant e /home/manu/.initvar
# For apache we should reload but it is done by
# logrotate from time to time.
mod_file echant w /etc/apache-extern/httpd.conf

rm $T

Recipient: no hack

(From /usr/share/doc/exim4-doc-html/html/C043.txt.gz):

Deny if the local part contains @ or % or / or | or !. These are rarely found in genuine local parts, but are often tried by people looking to circumvent relaying restrictions.

Also deny if the local part starts with a dot. Empty components aren't strictly legal in RFC 2822, but Exim allows them because this is common. However, actually starting with a dot may cause trouble if the local part is used as a file name (e.g. for a mailing list).

acl_check_rcpt:
 . . .
        # refuse if the recipient string is a hack,
        # see exim file example C043.txt.gz
        deny
                local_parts = ^.*[@%!/|] : ^\.

Recipient: no relay

I refuse to relay spams:

acl_check_rcpt:
 . . .
        # For the rest, the domain of the recipient address
        # must be my public domain. (no relay)
        require
                log_message = no relay.
                domains     = +public_domains

Recipient: manual redirect by the sender

The idea is to send an automatic reply, using mail"" command in a filter, to inform that an email is blocked and that the user must use an other email address. This can be used to change a user email which receive to much spam or to protect a public email address.

In a filter:

### reply for echant@maretmmanu.org
if $original_local_part is "echant" then
    seen mail from drop@maretmmanu.org subject "Re: $h_subject" file .echant_reponse.txt
    finish
endif

greylist

Greylisting use the fact that most of the time spammers softwares do not take account tempory errors to retry later. It's very effective. You can use a daemon like greylistd.

When exim send a «tempory error»:

  • nether if the host is in a white list of «good» hosts
  • nether if there is no sender: it is a bounce message
  • nether if the HELO argument is well configured and the host name seams owned by the sender.
  • if the greylist daemon want to

The two lines with «set acl_m9» are used to send the request to the daemon and get the result. The /24"" is here because some big MTA can be spreaded on multiple hosts.

######################################################################
#                    MAIN CONFIGURATION SETTINGS                     #
######################################################################
# Mandatory to use  "verify = helo"
helo_try_verify_hosts = !+own_hosts
 . . .
######################################################################
#                          ACL CONFIGURATION                         #
######################################################################
# ACL "subroutine" used by acl_check_rcpt below. Used to detect
# hosts wich have not their own registered domain-name (probably spammer).
# Return ok if the HELO argument correspond to the connected HOST and
# if the argument does not contain an IP in decimal or hexa.
# I have created this ACL subroutine because we can't do a list of "or"
# in ACL (it's a list of "and"), so I use a negation of "and":
# no (no A and no B) = A or B.
acl_clean_helo:
        accept
                verify     = helo
                condition  = ${if match{$sender_helo_name}{N(d{1,3}[.-]d{1,3}[.-]d{1,3}[.-]d{1,3})|([0-9a-f]{8})|([0-9A-F]{8})N}{false}{true}}

acl_check_rcpt:
 . . . 

        # Greylisting, if the HELO argument seems bad or
        # a dialin name (with IP included in the name). Some hosts from big
        # providers are in a white list to avoid testing. When there is no
        # sender then it is a bounce message, so no greylist.
        defer
                message = Please try later.
                !hosts      = /etc/exim4/filters/host_white.list
                !senders    = :
                !acl        = acl_clean_helo
                log_message = greylisted.
                set acl_m9  = ${mask:$sender_host_address/24} $sender_address $local_part@$domain
                set acl_m9  = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}
                condition   = ${if eq {$acl_m9}{grey}{true}{false}}

anti-virus: windows executables in attachment

It's a very basic anti-virus: every emails with a windows executable as attachment is rejected.

acl_check_data:
 . . .
        deny    message = This message contains an attachment of a type which we do not accept (.$found_extension)
                demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url

anti-virus:clamav

I keep this chapter but I have removed clamav from my computer since there are some vulnerabilities announced times to times and because, with other spam filters, it seems not very usefull.

We used an anti-virus not to avoid virus (we have just linux hosts) but to remove unwanted emails.

######################################################################
#                    MAIN CONFIGURATION SETTINGS                     #
######################################################################
av_scanner = clamd:/var/run/clamd.ctl
 . . .
######################################################################
#                          ACL CONFIGURATION                         #
######################################################################
acl_check_data:
 . . .
        deny    message = This message contains a virus or other harmful content ($malware_name)
                demime = *
                malware = *

anti-spam external detector: spamassassin

We add a X-SA-Score:"" in the header of all emails, a X-SA-Report:"" for all email with spam score >0, we consider it a spam if score >5 (adding X-SA-Status: Yes"" and we don't accept the email if score >7.

Because of the accept"" we must put this acl block at the end of the acl_check_data.

######################################################################
#                    MAIN CONFIGURATION SETTINGS                     #
######################################################################
spamd_address = 127.0.0.1 783
 . . .
######################################################################
#                          ACL CONFIGURATION                         #
######################################################################
acl_check_data:
 . . .
        ## spamassassin, spams are never big and spamassassin can die on big emails, so we
        ## limit its use under 500ko.
        accept  condition = ${if >={$message_size}{500k}{yes}{no}}
        warn    message = X-SA-Score: $spam_score
                spam = nobody:true
        warn    message = X-SA-Report: $spam_report
                spam = nobody:true
                condition = ${if >{$spam_score_int}{0}{true}{false}}
        warn    message = X-SA-Status: Yes
                spam = nobody:true
                condition = ${if >{$spam_score_int}{50}{true}{false}}
        deny    message = This message scored $spam_score spam points.
                spam = nobody:true
                condition = ${if >{$spam_score_int}{70}{true}{false}}

In your ~/.forward"" you can redirect spams (5< score ≤7) in a special inbox:

#   Exim filter   <<== do not edit or remove this line!
if $h_X-SA-Status: matches "^Yes" then
     save $home/.Mailboxes/incoming/spam
     finish
endif

Checking source of email associated with your domain in whois

If you have an email published in a whois database (spammers scan these databases) but want emails just from your registrar, you can add this in your ~/.forward"" filter:

#   Exim filter   <<== do not edit or remove this line!
if $original_local_part is "echant-tr-myregistrar"
  then
  if $sender_address_domain is "myregistrar.net" then
    deliver marcel
  else
    save $home/.Mailboxes/incoming/spam
    finish
  endif
endif

All in one

######################################################################
#                    MAIN CONFIGURATION SETTINGS                     #
######################################################################

hostlist   own_hosts = 127.0.0.1 : 192.168.109.24 : 192.168.109.23 : 82.224.147.80
domainlist public_domains = maretmmanu.org
 . . .
# Mandatory to use  "verify = helo"
helo_try_verify_hosts = !+own_hosts

av_scanner = clamd:/var/run/clamd.ctl
spamd_address = 127.0.0.1 783

acl_smtp_rcpt = acl_check_rcpt
acl_smtp_mail = acl_check_sender
acl_smtp_connect = acl_check_host
acl_smtp_data = acl_check_data
acl_smtp_helo = acl_check_helo

 . . .
######################################################################
#                          ACL CONFIGURATION                         #
######################################################################
acl_check_host:
        accept
                hosts = +own_hosts : /etc/exim4/filters/host_white.list

        deny
                log_message = match host_reject.list
                hosts = /etc/exim4/filters/host_reject.list

        accept

acl_check_helo:
        accept  hosts = +own_hosts

	# If the HELO pretend to be this host
	deny	condition = ${if or {
					{eq {${lc:$sender_helo_name}}{maretmmanu.org}}
					{eq {${lc:$sender_helo_name}}{82.224.147.80}}
				    } {true}{false} }

        # by default we accept
        accept

acl_check_sender:
        deny    senders = /etc/exim4/filters/sender_reject.list
        accept

# ACL "subroutine" used by acl_check_rcpt below.
# Return ok if the HELO argument correspond to the connected HOST and
# if the HELO argument does not contain an IP in decimal or hexa.
# I have created this ACL subroutine because we can't do a list of "or"
# in ACL (it's a list of "and"), so I use a negation of "and":
# no (no A and no B) = A or B.
acl_clean_helo:
        accept
                verify     = helo
                condition  = ${if match{$sender_helo_name}{N(d{1,3}[.-]d{1,3}[.-]d{1,3}[.-]d{1,3})|([0-9a-f]{8})|([0-9A-F]{8})N}{false}{true}}

acl_check_rcpt:
        # refuse if the recipient string is a hack,
        # see exim file example C043.txt.gz
        deny
                local_parts = ^.*[@%!/|] : ^\.

        # Relaying with no more check for my own hosts.
        accept
                hosts = +own_hosts

        # For the rest, the domain of the recipient address
        # must be my public domain. (no relay)
        require
                log_message = no relay.
                domains     = +public_domains

        # Reffuse all the message if the recipient is only used by spammers.
        drop
                log_message   = match recipients_drop.list.
                recipients = /etc/exim4/filters/recipients_drop.list

        drop
                log_message = match sbl-xbl.spamhaus.org
                dnslists = sbl-xbl.spamhaus.org

        # Greylisting, if the HELO argument seems bad or
        # a dialin name (with IP included in the name). Some hosts from big
        # providers are in a white list to avoid testing. When there is no
        # sender then it is a bounce message, so no greylist.
        defer
                message = Please try later.
                !hosts      = /etc/exim4/filters/host_white.list
                !senders    = :
                !acl        = acl_clean_helo
                log_message = greylisted.
                set acl_m9  = ${mask:$sender_host_address/24} $sender_address $local_part@$domain
                set acl_m9  = ${readsocket{/var/run/greylistd/socket}{$acl_m9}{5s}{}{}}
                condition   = ${if eq {$acl_m9}{grey}{true}{false}}

        # Default rule: accept except if recipient address is unrouteable.
        accept
                message = unrouteable address
                verify = recipient

acl_check_data:

        accept  hosts = +own_hosts

        # if there is a windows executable as attachment then we reject
        deny    message = This message contains an attachment of a type which we do not accept (.$found_extension)
                demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url

        # clamav
        deny    message = This message contains a virus or other harmful content ($malware_name)
                demime = *
                malware = *

        ## spamassassin, spams are never big and spamassassin can die on big emails, so we
        ## limit its use under 500ko.
        accept  condition = ${if >={$message_size}{500k}{yes}{no}}
        warn    message = X-SA-Score: $spam_score
                spam = nobody:true
        warn    message = X-SA-Report: $spam_report
                spam = nobody:true
                condition = ${if >{$spam_score_int}{0}{true}{false}}
        warn    message = X-SA-Status: Yes
                spam = nobody:true
                condition = ${if >{$spam_score_int}{50}{true}{false}}
        deny    message = This message scored $spam_score spam points.
                spam = nobody:true
                condition = ${if >{$spam_score_int}{70}{true}{false}}
        # accept by default
        accept

IPerf — утилита командной строки, предназначенная для тестирования пропускной способности канала связи. Она включает в себя генератор TCP и UDP трафика и используется для определения скорости прохождения трафика между двумя узлами в сети. IPerf (для Windows) представляет из себя небольшой исполняемый файл размером около 100кб, в котором содержатся клиентская и серверная части. Он не требует установки, достаточно просто скопировать ее на оба компьютера и запустить сначала серверную часть программы, а затем клиентскую.

 

В самом простом варианте запуск IPerf происходит следующим образом:

iperf -s — на сервере.

iperf5

 

iperf -c 192.168.1.56 — на клиенте, где 192.168.1.56 — IP-адрес сервера.

iperf4

 

По умолчанию используется TCP порт 5001, тестирование проходит в течение 10 секунд. Этого вполне достаточно для быстрой оценки скорости соединения, однако возможности IPerf этим не ограничиваются. Например:

iperf -s -i10 -p80 — сервер прослушивает 80 порт и выдает результат с интервалом в 10 секунд.

iperf2

 

iperf -c 192.168.1.60 -p80 -t120 — клиент соединяется с 80 портом сервера, тестирование в течение 120 секунд.

iperf1

 

Приведу полный список опций программы:

  • -f -  в каком формате показывать скорость (Kbits, Mbits, KBytes, Mbytes);
  • -i -  с какими интервалами отображать промежуточные результаты;
  • -l — размер буфера (по умолчанию 8 KB);
  • -m —  показывать максимальный размер TCP сегмента (MSS);
  • -p — указать порт, по которому будет происходить соединение (по умолчанию 5001);
  • -u — использовать UDP вместо TCP;
  • -w — размер окна TCP;
  • -B — указание для сервера, на каком интерфейсе принимать трафик;
  • -C — режим совместимости со старыми версиями;
  • -M —  позволяет изменить максимальный размер TCP сегмента (MSS);
  • -N — меняет некоторые опции TCP (отключение алгоритма Нагла);
  • -V —  использовать IPV6;
  • -h — вывод справки.

Опции для сервера:

  • -s —  запустить как сервер и отображать всю информацию на экран;
  • -D — запустить как сервис (в фоновом режиме) и не отображать информацию.

Опции клиента:

  • -b — используемая полоса для UDP (по умолчанию 1Mbit/sec);
  • -c — запустить как клиент и соединиться с сервером;
  • -d — тестировать линию в обе стороны;
  • -n — установить размер передаваемого трафика (нельзя использовать c ключом -t);
  • -r — не делать двунаправленное тестирование;
  • -t - указать время тестирования (по умолчанию 10 сек);
  • -F — не генерировать трафик, а передавать готовый файл;
  • -I — ввод данных, передаваемых из STDIN (стандартный поток ввода);
  • -L — порт, на котором клиент будет принимать двунаправленный трафик;
  • -P —  запуск нескольких потоков параллельно;
  • -T - время жизни пакета для групповой рассылки (по умолчанию 1).

Программа IPerf очень проста и удобна в использовании, однако для эстетов тех, кто не любит работать в командной строке, есть графический интерфейс для IPerf, написанный на JavaJPerf. Установки он также не требует, но для его работы необходима установленная платформа Java.

iperf3

 

В общем, IPerf  — удобный инструмент для измерения скорости и качества сетевого соединения, который стоит всегда иметь под рукой. Программа абсолютно бесплатна, загрузить ее можно с сайта SourceForge.