Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мегоубернастройка сервера UBUNTU 10.04 lts.doc
Скачиваний:
0
Добавлен:
20.09.2019
Размер:
614.91 Кб
Скачать

4. Назначаем права администратору домена и добавляем сервер в домен

Дадим группе Domain Admins права администратора домена для этого выполним следующее:

net rpc rights grant "Domain Admins" SeMachineAccountPrivilege SeTakeOwnershipPrivilege \

SeBackupPrivilege SeRestorePrivilege SeRemoteShutdownPrivilege SePrintOperatorPrivilege \

SeAddUsersPrivilege SeDiskOperatorPrivilege –Unx-admin%admin

Ответом должно быть Successfully granted rights.

Теперь любой пользователь входящий в эту группу будет иметь права администратора домена.

Добавим наш сервер в домен

net rpc join -U nx-admin%admin

Ответом должно быть Joined domain EXAMPLE.

Проверить добавлен сервер в домен или нет можно командой

net rpc testjoin

Ответом должно быть Join to 'EXAMPLE' is OK

Команды для администрирования samba c помощью smbldap-tools

Добавление пользователя: smbldap-useradd -a -P username

Удаление пользователя: smbldap-userdel username

Добавление группы: smbldap-groupadd -a groupname

Добавление пользователя в группу: smbldap-groupmod -m username groupname

Удаление пользователя из группы: smbldap-groupmod -x username groupname

Добавление компьютера в домен: smbldap-useradd -t 0 -w username

Установить основную группу пользователя: smbldap-usermod -g groupname username

Если для администрирования будет использоваться Gosa то этими командами пользоваться нельзя, так так пользователей и группы добавленные этими командами Gosa видеть не будет.

Настроить Gosa можно перейдя по данной ссылке (пункт 5):

http://help.ubuntu.ru/wiki/samba_pdc_ldap_ubuntu_10_04

Postfix и куча примочек

Итак, установка постфикса является очень длительным и проблематичным делом, я попробую описать точную настройку, с минимум ненужной информации, описав все самое важное. Если чтото не получается, советую ознакомится с форумом, по данной теме http://forum.ubuntu.ru/index.php?topic=127090.0

apt-get install openssh-server

установим все обновления (их наверняка набралось уже порядочно):

apt-get update

apt-get dist-upgrade

reboot

Установим нужные пакеты

apt-get install postfix postfix-mysql postfix-ldap postfix-doc postfix-tls libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql dovecot-imapd dovecot-pop3d dovecot-common mysql-client mysql-server apache2 libapache2-mod-php5 php5 php5-mysql

Отвечаем на вопросы

Новый пароль для MySQL пользователя «root»:

admin

Повторите ввод пароля для MySQL пользователя «root»:

admin

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

Здесь просто жмем <OK>.

Общий тип почтовой настройки:

Internet - сайт

Системное почтовое имя:

nx2.trest91.ru

Создадим базу данных mysql для хранения всей информации для почтового сервера

mysqladmin -u root -p create mail

Enter password:

admin

mysql -u root -p

Создадим специального пользователя mail_admin и паролем admin для доступа к нашей базе данных mail с привилегиями SELECT, INSERT, UPDATE и DELETE. Доступ ему будет разрешен только с локального компьютера (т.е. с самого сервера):

GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY 'admin';

GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost.localdomain' IDENTIFIED BY 'admin';

FLUSH PRIVILEGES;

Теперь создадим нужные нам таблицы в базе данных mail

use mail;

CREATE TABLE domains (

domain varchar(50) NOT NULL,

PRIMARY KEY (domain) )

TYPE=MyISAM;

CREATE TABLE forwardings (

source varchar(80) NOT NULL,

destination TEXT NOT NULL,

PRIMARY KEY (source) )

TYPE=MyISAM;

CREATE TABLE transport (

domain varchar(128) NOT NULL DEFAULT '',

transport varchar(128) NOT NULL DEFAULT '',

UNIQUE KEY domain (domain)

) ENGINE=MyISAM;

CREATE TABLE users (

email varchar(80) NOT NULL,

password varchar(20) NOT NULL,

quota varchar(20) DEFAULT '0',

PRIMARY KEY (email)

) TYPE=MyISAM;

(здесь мы задаем квоту для пользователей по умолчанию без лимита - 0)

quit;

(при заполнении мускуль может ругатся на синтаксис, читаем сообщение об ошибке и исправляемся)

Настройка Postfix

Сейчас нам необходимо указать Postfix, где ему искать информацию в базе данных. Для этого создадим шесть текстовых файлов. Как вы можете заметить, я указываю Postfix соединяться с MySQL через IP адрес 127.0.0.1 вместо localhost. Это связано с тем, что Postfix запущенный в chroot окружении не сможет иметь доступа к MySQL сокету, если будет пытаться использовать localhost для подключения.

Проверим, что mysql «слушает» локальный IP адрес

cat /etc/mysql/my.cnf | grep bind

bind-address = 127.0.0.1

Если пришлось поменять /etc/mysql/my.cnf, то перезапустим mysql

service mysql restart

и проверяем, что он действительно слушает этот адрес:

netstat -tap | grep mysql

tcp 0 0 localhost:mysql *:* LISTEN 5908/mysqld

(здесь 5908- это номер процесса, у Вас будет другой).

Теперь создадим файлы для того, чтобы postfix знал, где что искать в нашей базе данных: nano /etc/postfix/mysql-virtual_domains.cf

user = mail_admin

password = admin

dbname = mail

query = SELECT domain AS virtual FROM domains WHERE domain='%s'

hosts = 127.0.0.1

nano /etc/postfix/mysql-virtual_forwardings.cf

user = mail_admin

password = admin

dbname = mail

query = SELECT destination FROM forwardings WHERE source='%s'

hosts = 127.0.0.1

nano /etc/postfix/mysql-virtual_mailboxes.cf

user = mail_admin

password = admin

dbname = mail

query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s'

hosts = 127.0.0.1

nano /etc/postfix/mysql-virtual_email2email.cf

user = mail_admin

password = admin

dbname = mail

query = SELECT email FROM users WHERE email='%s'

hosts = 127.0.0.1

nano /etc/postfix/mysql-virtual_transports.cf

user = mail_admin

password = admin

dbname = mail

query = SELECT transport FROM transport WHERE domain='%s'

hosts = 127.0.0.1

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

chmod o= /etc/postfix/mysql-virtual_*.cf

chgrp postfix /etc/postfix/mysql-virtual_*.cf

Проверяем права доступа к этим файлам:

ls -al /etc/postfix/mysql-virtual*.cf

-rw-r—– 1 root postfix 134 2010-11-26 11:24 /etc/postfix/mysql-virtual_domains.cf

-rw-r—– 1 root postfix 119 2010-11-26 11:25 /etc/postfix/mysql-virtual_email2email.cf

-rw-r—– 1 root postfix 132 2010-11-26 11:24 /etc/postfix/mysql-virtual_forwardings.cf

-rw-r—– 1 root postfix 188 2010-11-26 11:25 /etc/postfix/mysql-virtual_mailboxes.cf

-rw-r—– 1 root postfix 128 2010-11-26 11:25 /etc/postfix/mysql-virtual_transports.cf

Создаем нового пользователя и группу с названием vmail с домашней директорией /home/vmail , где будут находится почтовые ящики:

groupadd -g 5000 vmail \\

useradd -g vmail -u 5000 vmail -d /home/vmail -m

Предварительная настройка postfix (нам еще придется ее менять чуть позже).

postconf -e 'myhostname = nx2.trest91.ru'

postconf -e 'mydestination = nx2.trest91.ru, localhost, localhost.localdomain'

postconf -e 'mynetworks = 127.0.0.0/8'

postconf -e 'virtual_alias_domains ='

postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf'

postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf'

postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf'

postconf -e 'virtual_mailbox_base = /home/vmail'

postconf -e 'virtual_uid_maps = static:5000'

postconf -e 'virtual_gid_maps = static:5000'

postconf -e 'smtpd_sasl_auth_enable = yes'

postconf -e 'broken_sasl_auth_clients = yes'

postconf -e 'smtpd_sasl_authenticated_header = yes'

postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination'

postconf -e 'smtpd_use_tls = yes'

postconf -e 'smtpd_tls_cert_file = /etc/postfix/smtp.crt'

postconf -e 'smtpd_tls_key_file = /etc/postfix/smtp.key'

postconf -e 'transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf'

postconf -e 'virtual_create_maildirsize = yes'

postconf -e 'virtual_mailbox_extended = yes'

postconf -e 'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps'

Создание SSL-сертификатов

Создаем CA.

Создадим папку, в которой будем генерить все сертификаты

mkdir ~/CA_clean

Нам нужно вначале подготовить конфигурационный файл для создания CA

nano ca.conf

[req]

distinguished_name =req_distinguished_name

x509_extensions = v3_ca

prompt = no

[req_distinguished_name]

C= RU

ST = Ural Region

L = Ekaterinburg

O = TREST

OU = ROOTCA

CN = trest91.ru

emailAddress = admin@trest91.ru

[v3_ca]

basicConstraints = CA:true

nsComment = "CA certificate of TREST"

nsCertType = sslCA, emailCA

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

[ usr_cert ]

nsComment = "Certificate issued by TREST"

;nsBaseUrl = http://ca.trest91.ru/

;nsRevocationUrl = http://ca.trest91.ru/crl.crl

;issuerAltName = URI:http://ca.trest91.ru/ca.crt

;crlDistributionPoints = URI:http://ca.trest91.ru/crl.crl

Создаем частный ключ ключ CA

openssl genrsa -des3 -out ca.key 4096

Enter pass phrase for ca.key:

Введите пароль для файла ca.key (два раза для подтверждения) и не забывайте его!

Verifying - Enter pass phrase for ca.key:

Он будет нужен для подписывания всех ключей

Создаем открытый ключ CA. Мы говорим, что ключи нашего CA имеют «срок жизни» 10 лет (-days 3650).

openssl req -new -x509 -nodes -sha1 -days 3650 -key ca.key -out ca.crt -config ca.conf

Enter pass phrase for ca.key:

(вводим выбранный нами на предыдущем шаге пароль закрытого ключа CA)

Создаем сертификат для подписывания:

openssl pkcs12 -export -in ca.cer -inkey ca.key -out ca.pfx

openssl x509 -trustout -inform PEM -in ca.crt -outform DER -out ca.pfx

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

mkdir SERVERS

mkdir SERVERS/nx2.trest91.ru

Создаем файлы конфигураций для ключей

nano SERVERS/nx2.trest91.ru/openssl.conf

[ req ]

default_bits = 2048

distinguished_name = req_distinguished_name

prompt = no

req_extensions = v3_req

[ req_distinguished_name ]

C = RU

ST = Ural Region

L = Ekaterinburg

O = TREST

CN = nx2.trest91.ru

emailAddress = admin@trest91.ru

[ v3_req ]

basicConstraints = CA:FALSE

subjectKeyIdentifier = hash

Теперь сгенерим ключи для нашего сервера

openssl genrsa -passout pass:1234 -des3 -out SERVERS/nx2.trest91.ru/server.key.1 2048

Здесь 1234 — парольная фраза для промежуточного ключа. Она нам нужна только временно, т.к. мы в результате хотим получить ключ без пароля (требование postfix).

Убираем из ключа парольную фразу:

openssl rsa -passin pass:1234 -in SERVERS/nx2.trest91.ru/server.key.1 -out SERVERS/nx2.trest91.ru/server.key

Генерим запрос на подпись нашего ключа

openssl req -config SERVERS/nx2.trest91.ru/openssl.conf -new -key SERVERS/nx2.trest91.ru/server.key -out SERVERS/nx2.trest91.ru/server.csr

rm -f SERVERS/nx2.trest91.ru/server.key.1

Теперь нам нужно подписать наш созданный ключ от имени своего CA

Сделаем конфигурационный файл для подписи (срок действия подписи 5 лет - 1828 дней):

nano sign.config

[ ca ]

default_ca = CA_own

[ CA_own ]

certs = .

new_certs_dir = ca.db.certs

database = ca.db.index

serial = ca.db.serial

RANDFILE = ca.db.rand

certificate = ca.crt

private_key = ca.key

default_days = 1825

default_crl_days = 1

default_md = sha1

preserve = no

policy = policy_anything

x509_extensions = usr_cert

[ policy_anything ]

countryName = optional

stateOrProvinceName = optional

localityName = optional

organizationName = optional

organizationalUnitName = optional

commonName = supplied

emailAddress = optional

[usr_cert]

basicConstraints = CA:false

subjectKeyIdentifier = hash

authorityKeyIdentifier = keyid:always,issuer:always

mkdir ca.db.certs

Для первого подписанного ключа создаем его номер и формируем индексный файл (для остальных - не нужно!)

echo '01' > ca.db.serial

cp /dev/null ca.db.index

openssl ca -batch -config sign.config -out SERVERS/nx2.trest91.ru/server.crt -infiles SERVERS/nx2.trest91.ru/server.csr

Enter pass phrase for ca.key:

(введем пароль закрытого ключа CA)

Проверим подпись (на всякий случай):

openssl verify -CAfile ca.crt SERVERS/nx2.trest91.ru/server.crt

SERVERS/nx2.trest91.ru/server.crt: OK

rm -f ca.db.serial.old

rm -rf ca.db.index.old

cp SERVERS/nx2.trest91.ru/server.key /etc/ssl/private/oban.key

cp SERVERS/nx2.trest91.ru/server.crt /etc/ssl/certs/oban.crt

chmod og= /etc/ssl/private/oban.key

mkdir /usr/share/ca-certificates/aaa

cp ca.crt /usr/share/ca-certificates/aaa/

После этого переконфигурируем наши корневые сертификаты

dpkg-reconfigure ca-certificates

(ответим, что мы хотим доверять новым сертификатам и выберем в списке наш новый сертификат для активации)

Нашим клиентам, которые будут связываться с нашим первером с использованием шифрования (TLS, SSL) или с нашим веб-сервером по протоколу HTTPS нужно установить доверие к нашему CA. Тем или иным способом передайте им открытый ключ нашего CA - ca.crt.

Внимание! Никогда никому не передавайте созданные приватные ключи *.key и не делайте их доступными!

Настройка saslauthd

Авторизация почтовых пользователей на нашем сервере будет происходить через pam, к которому будет обращаться демон авторизации sasl.

mkdir -p /var/spool/postfix/var/run/saslauthd

nano /etc/default/saslauthd

Установим параметр START в yes и заменим строку OPTIONS=»-c -m /var/run/saslauthd» на OPTIONS=»-c -m /var/spool/postfix/var/run/saslauthd -r»

nano /etc/pam.d/smtp

auth sufficient pam_mysql.so user=mail_admin passwd=admin host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1

account sufficient pam_mysql.so user=mail_admin passwd=admin host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1

chmod o= /etc/pam.d/smtp

nano /etc/postfix/sasl/smtpd.conf

pwcheck_method: saslauthd

mech_list: plain login

allow_plaintext: true

chown postfix /etc/postfix/sasl/smtpd.conf

chmod og= /etc/postfix/sasl/smtpd.conf

Добавляем пользователя postfix в группу sasl

adduser postfix sasl

/etc/init.d/postfix restart

/etc/init.d/saslauthd restart

mysql -u root -p

Введем пароль mysql

admin

USE mail;

INSERT INTO domains (domain) VALUES ('trest91.ru');

INSERT INTO users (email, password, quota) VALUES ('admin@trest91.ru', ENCRYPT('admin'), '10M');

quit;

(квоту пользователю мы задаем в размере 10Мбайт)

Для проверки авторизации нам нужно сгенерить строку, которую нужно передать при авторизации (обратите внимание на обратные слеши перед @ и 0):

perl -MMIME::Base64 -e 'print encode_base64("admin\@trest91.ru\0admin\@trest91.ru\0admin");'

YWRtaW5AYmJiLnJ1AGFkbWluQGJiYi5ydQBzZWNyZXQ=

Теперь проверим авторизацию

telnet 127.0.0.1 25

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is '^]'.

220 nx2.trest91.ru ESMTP Postfix (Ubuntu)

EHLO testing

250-nx2.trest91.ru

250-PIPELINING

250-SIZE 10240000

250-VRFY

250-ETRN

250-STARTTLS

250-AUTH PLAIN LOGIN

250-AUTH=PLAIN LOGIN

250-ENHANCEDSTATUSCODES

250-8BITMIME

250 DSN

AUTH PLAIN YWRtaW5AYmJiLnJ1AGFkbWluQGJiYi5ydQBzZWNyZXQ=

(здесь вставляем полученную ранее строку авторизации)

235 2.7.0 Authentication successful

QUIT

Если мы получим ответ, отличный от «Authentication successful», то мы где-то ошиблись. Проверить, в чем именно, можно, посмотрев файлы /var/log/auth.log и /var/log/mail.log

На данном пункте я впервые очень надолго застрял. Моя проблема состояла в том, что я неправильно заполнил базу мускуля. Проблема решилась полной переустановкой MySQL.

Теперь сделаем аутентификацию по openldap. Установим нужные пакеты:

apt-get install libpam-ldap

и ответим на вопросы:

LDAP server Uniform Resource Identifier:

ldap://10.0.0.3/

Обратите внимание — не ldapi!

Distinguished name of the search base:

dc=trest91,dc=ru

LDAP version to use:

3

Make local root Database admin:

Да

Does the LDAP database require login?

Нет

LDAP account for root:

cn=admin,dc=trest91,dc=ru

LDAP root account password:

admin

Редактируем файл

nano /etc/ldap.conf

и добавляем в него одну строку после закомментаренной #bind_policy hard

bind_policy soft

Редактируем файл

nano /etc/pam.d/smtp

и добавляем в него строки

auth sufficient pam_ldap.so

account sufficient pam_ldap.so

Теперь можем проверить аутентификацию ldap-пользователя

perl -MMIME::Base64 -e 'print encode_base64("admin\0admin\0admin");'

YWRtaW4AYWRtaW4Ac2VjcmV0

telnet 127.0.0.1 25

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is '^]'.

220 nx2.trest91.ru ESMTP Postfix (Ubuntu)

EHLO testing

250-nx2.trest91.ru

250-PIPELINING

250-SIZE 10240000

250-VRFY

250-ETRN

250-STARTTLS

250-AUTH PLAIN LOGIN

250-AUTH=PLAIN LOGIN

250-ENHANCEDSTATUSCODES

250-8BITMIME

250 DSN

AUTH PLAIN YWRtaW4AYWRtaW4Ac2VjcmV0

235 2.7.0 Authentication successful

QUIT

nano /etc/postfix/ldap-mailboxes.cf

server_host = 10.0.0.3

server_port = 389

version = 3

bind = yes

bind_dn = cn=admin,dc=trest91,dc=ru

bind_pw = admin

search_base = ou=Users,dc=trest91,dc=ru

query_filter = (mail=%s)

result_attribute = mail

result_filter = %d/%u/

chgrp postfix /etc/postfix/ldap-mailboxes.cf

chmod o= /etc/postfix/ldap-mailboxes.cf

и меняем строку virtual_mailbox_maps = … в файле /etc/postfix/main.cf

nano /etc/postfix/main.cf

virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf ldap:/etc/postfix/ldap-mailboxes.cf

Для проверки в том же файле временно меняем строку

#smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

на

smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination

(это запрещает доставку писем с локального IP-адреса не в наши виртуальные домены)

/etc/init.d/postfix restart

telnet 127.0.0.1 25

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is '^]'.

220 nx2.trest91.ru ESMTP Postfix (Ubuntu)

HELO test

250 oban.trest91.ru

MAIL FROM: aaa@aa.aa (вроде так вводить… честно не помню)

250 2.1.0 Ok

RCPT TO: admin@trest91.ru

QUIT

Вернем обратно строку в файле /etc/postfix/main.cf:

nano /etc/postfix/main.cf

smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

nano /etc/postfix/main.cf

smtpd_tls_auth_only = yes

smtpd_tls_cert_file = /etc/ssl/certs/nx2.crt

smtpd_tls_key_file = /etc/ssl/private/nx2.key

smtpd_use_tls = yes

/etc/init.d/postfix restart

nano /etc/aliases

postmaster: root

clamav: root

root: admin@trest91.ru

newaliases

Настройка dovecot

cp /etc/pam.d/smtp /etc/pam.d/dovecot

nano /etc/dovecot/dovecot-ldap.conf

uris = ldap://10.0.0.3/

dn = cn=admin,dc=trest91,dc=ru

dnpass = admin

ldap_version = 3

base = ou=Users,dc=trest91,dc=ru

deref = searching

scope = subtree

user_attrs = mail=mail=maildir:/home/vmail/trest91.ru/%n/

user_filter = (&(uid=%n))

nano /etc/dovecot/dovecot-sql.conf

driver = mysql

connect = host=127.0.0.1 user=mail_admin password=admin dbname=mail

user_query = SELECT email, CONCAT('/home/vmail/',CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1))) AS home, concat('*:storage=', quota) as quota_rule FROM users WHERE email='%u'

nano /etc/dovecot/dovecot.conf

disable_plaintext_auth = yes

ssl = yes

ssl_cert_file = /etc/ssl/certs/nx2.crt

ssl_key_file = /etc/ssl/private/nx2.key

mail_location = maildir:/home/vmail/%d/%n

mail_uid = vmail

mail_gid = vmail

maildir_copy_with_hardlinks = yes

В блоке auth default { должно быть выбрано

mechanisms = plain

и раскомментарено

passdb pam {

}

закомментарим

# userdb passwd {

# }

и раскомментарим

# SQL database </usr/share/doc/dovecot-common/wiki/AuthDatabase.SQL.txt>

userdb sql {

# Path for SQL configuration file

args = /etc/dovecot/dovecot-sql.conf

}

# LDAP database </usr/share/doc/dovecot-common/wiki/AuthDatabase.LDAP.txt>

userdb ldap {

# Path for LDAP configuration file

args = /etc/dovecot/dovecot-ldap.conf

}

В блоке protocol imap { добавляем строку

mail_plugins = quota imap_quota

В блоке protocol pop3 { добавляем строку

mail_plugins = quota

В блоке plugin { добавляем строки

quota = maildir:Quota

quota_rule = *:storage=0

quota_rule2 = Trash:ignore

quota_warning = storage=95%% /usr/local/bin/quota-warning.sh 95

quota_warning2 = storage=80%% /usr/local/bin/quota-warning.sh 80

Создадим скрипт, который будет посылать пользователям напоминания при превышении ими квоты

nano /usr/local/bin/quota-warning.sh

#!/bin/sh

PERCENT=$1

FROM="admin@trest91.ru"

qwf="/tmp/quota.warning.$$"

echo "From: $FROM

To: $USER

To: admin@trest91.ru

Subject: Your email quota is $PERCENT% full

Content-Type: text/plain; charset="UTF-8"

Your mailbox is now $PERCENT% full." >> $qwf

cat $qwf | /usr/sbin/sendmail -f $FROM "$USER"

rm -f $qwf

exit 0

chmod a+x /usr/local/bin/quota-warning.sh

chown root.root /etc/dovecot/dovecot-ldap.conf

chown root.root /etc/dovecot/dovecot-sql.conf

chmod og= /etc/dovecot/dovecot-ldap.conf

chmod og= /etc/dovecot/dovecot-sql.conf

/etc/init.d/dovecot restart

telnet 127.0.0.1 110

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is '^]'.

+OK Dovecot ready.

user admin@trest91.ru

+OK

pass admin

+OK Logged in.

quit

telnet 127.0.0.1 110

Trying 127.0.0.1…

Connected to 127.0.0.1.

Escape character is '^]'.

+OK Dovecot ready.

user admin

+OK

pass admin

+OK Logged in.

quit

После этой проверки, кстати, автоматически создадутся папки для хранения почты:

Установка horde

apt-get install horde3 imp4 turba2 sork-passwd-h3

nano /etc/apache2/sites-available/default-ssl

Заменяем

DocumentRoot /var/www

<Directory />

Options FollowSymLinks

AllowOverride None

</Directory>

<Directory /var/www/>

Options Indexes FollowSymLinks MultiViews

AllowOverride None

Order allow,deny

allow from all

</Directory>

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

<Directory "/usr/lib/cgi-bin">

AllowOverride None

Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

Order allow,deny

Allow from all

</Directory>

на

DocumentRoot /usr/share/horde3

<Directory />

Options FollowSymLinks

AllowOverride Limit

</Directory>

<Directory /usr/share/horde3>

Options Indexes FollowSymLinks MultiViews

AllowOverride Limit

Order allow,deny

allow from all

</Directory>

Alias /horde3 /usr/share/horde3

и

SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem

SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

на

SSLCertificateFile /etc/ssl/certs/nx2.crt

SSLCertificateKeyFile /etc/ssl/private/nx2.key

a2enmod ssl

a2ensite default-ssl

/etc/init.d/apache2 restart

nano /etc/horde/horde3/conf.php

//echo "Horde3 configuration disabled by default because the administration/install wizard gives the whole world too much access to the system. Read /usr/share/doc/horde3/README.Debian.gz on how to allow access.";

//exit (0);

gzip -d /usr/share/doc/horde3/examples/scripts/sql/create.mysql.sql.gz

nano /usr/share/doc/horde3/examples/scripts/sql/create.mysql.sql

-- IMPORTANT: Change this password.

PASSWORD('admin')

mysql --user=root –password=admin < /usr/share/doc/horde3/examples/scripts/sql/create.mysql.sql

и заходим браузером на https://nx2.trest91.ru

lynx

Тут подключаем текстовый редактор и переходим на сайт

В первый раз нас пустят с администраторскими привилегиями. Настроим систему аутентификации. Вначале войдем в Управление - Приложения - Портал (horde) и выберем закладку Authentication.

Зададим пользователя-администратора admin в поле «Which users should be treated as administrators (root, super-user) by Horde?».

admin@trest91.ru

Затем выберем способ аутентификации - через IMAP (выберем IMAP authentication в поле «What backend should we use for authenticating users to Horde?»).

Вот тут интересный момент, мои браузеры не обновлялись и я не мог найти дальнейшие настройки конфигурации. Дело в том что в текстовых браузерах нет автоматического обновления страниц, поэтому листаем в самый конец и тыкаем на Generate Портал Configuration. Делать это нужно после каждого изменения настроек (изменили – тыкнули).

В поле «Configuration type» выберем Separate values.

В поле «The hostname or IP address of the server» оставим localhost

В поле «The server port to which we will connect. IMAP is generally 143, while IMAP-SSL is generally 993.» выберем 143 (в данном случае мы используем локальный IMAP-сервер, так что это нам подходит)

В поле «The connection protocol» выберем imap/notls

Переходим во вкладку Database и конфигурируем доступ к созданной ранее базе данных.

В поле «What database backend should we use?» выбираем MySQL

В поле «Username to connect to the database as» вводим admin

В поле «Password to connect with» вводим пароль, который мы вводили в скрипте создания базы данных- admin

В поле «How should we connect to the database?» выбираем TCP/IP

В поле «Database server/host» вводим localhost

В поле «Port the DB is running on, if non-standard» оставляем 3306

В поле «Database name to use» вводим admin

В поле «Internally used charset» оставляем utf-8

Переходим в закладку Mailer и настраиваем доступ к SMTP-серверу:

В поле «What method should we use for sending mail?» выбираем Use a SMTP server

В поле «SMTP authentication» выбираем PLAIN

Переходим в закладку Preference System и выбираем SQL Database в поле «What preferences driver should we use?».

Переходим в закладку Datatree System и выбираем SQL Database в поле «What backend should we use for Horde DataTree storage?».

Переходим в закладку Cache System и выбираем Store objects in filesystem в поле «If you want to enable the Horde Cache, select a driver here. This is used to speed up portions of Horde by storing commonly processed objects.». В поле «The location to store the cached files» выбираем /tmp

Переходим в закладку Virtual File Storage и выбираем Files on the local system в закладке «What VFS driver should we use?»

Переходим в закладку Custom Session Handler и настраиваем доступ к созданной ранее базе данных:

В поле «What sessionhandler driver should we use?» выбираем MySQL based sessions

В поле «What protocol will we use to connect to the database?» выбираем TCP/IP

В поле «What password do we authenticate to the database server with?» вводим пароль, который мы вводили в скрипте создания базы данных - admin

Остальные поля оставляем по умолчанию.

Теперь нажмем кнопку Generate Портал Configuration.

Скопируем показанный внизу на странице сгенеренный код и запишем его в файл /etc/horde/horde3/conf.php (важно скопировать ВЕСЬ текст, заменив ВЕСЬ текст, имеющийся в файле).

Вот тут нас и спасает наш встроенный текстовый редактор. Наводим на документ и нажимаем CTRL+X+E, ставим символ,удаляем его и сохраняем в /etc/horde/horde3/conf.php

Закроем окно броузера.

sudo /etc/horde/imp4/servers.php

$servers['imap'] = array(

'name' => 'IMAP Server',

'server' => '127.0.0.1',

'hordeauth' => full,

'protocol' => 'imap/notls',

'port' => 143,

'maildomain' => '',

'smtphost' => '127.0.0.1',

'smtpport' => 25,

'realm' => '',

'preferred' => '',

'quota' => array('driver'=>imap),

);

и закомментируем все остальные примеры ниже.

Войдем заново на https://nx2.trest91.ru уже под администратором

admin@trest91.ru

admin

Зайдем в Управление - Приложения - Почта (imp) и выберем закладку Server.

В поле «Should we display a list of servers (defined in config/servers.php) for users to choose from? The options are 'shown', 'hidden', and 'none'. If the server list is hidden then you can use the 'preferred' mechanism to auto-select from it based on an HTTP virtualhost or another piece of data. If it is shown, the user will be able to pick from any of the options. If none, no server list will be shown and the defaults will be used unless another mechanism changes them.» выберем Hidden.

Нажмем кнопку Generate Почта Configuration, скопируем сгенеренный текст конфигурации и запишем в файл /etc/horde/imp4/conf.php

nano /etc/horde/passwd3/backends.php

Закомментируем все кроме

$backends['sql'] = array (

'name' => 'Exampe SQL Server',

'preferred' => '',

'password policy' => array(

'minLength' => 3,

'maxLength' => 8,

'maxSpace' => 0,

'minUpper' => 0,

'minLower' => 0,

'minNumeric' => 0,

'minSymbols' => 0

),

'driver' => 'sql',

'params' => array(

'phptype' => 'mysql',

'hostspec' => 'localhost',

'username' => 'mail_admin',

'password' => 'admin',

'encryption' => 'crypt',

'database' => 'mail',

'table' => 'users',

'user_col' => 'email',

'pass_col' => 'password',

'show_encryption' => false

// The following two settings allow you to specify custom queries for

// lookup and modify functions if special functions need to be

// performed. In places where a username or a password needs to be

// used, refer to this placeholder reference:

// %d -> gets substituted with the domain

// %u -> gets substituted with the user

// %U -> gets substituted with the user without a domain part

// %p -> gets substituted with the plaintext password

// %e -> gets substituted with the encrypted password

//

// 'query_lookup' => 'SELECT user_pass FROM horde_users WHERE user_uid = %u',

// 'query_modify' => 'UPDATE horde_users SET user_pass = %e WHERE user_uid = %u',

)

);

можете изменить политику паролей — какие пароли допустимы:

'minLength' — минимальная длина паролей

'maxLength' — максимальная длина паролей

'minUpper' — минимальное количество заглавных букв в паролях

'minLower' — минимальное количество прописных букв в паролях

'minNumeric' — минимальное количество цифровых символов в паролях

'minSymbols' — минимальное количество прочих символов букв в паролях)

Зайдем в Управление - Приложения - Пароль (passwd) и в поле «Should we display a list of backends (defined in config/backends.php) for users to choose from? The options are 'shown', 'hidden'. If the backend list is hidden then you can use the 'preferred' mechanism to auto-select from it based on an HTTP virtualhost or another piece of data. If it is shown, the user will be able to pick from any of the options.» выберем Hidden.

Нажмем кнопку Generate Пароль Configuration, скопируем сгенеренный текст конфигурации и запишем в файл /etc/horde/passwd3/conf.php

nano /etc/horde/horde3/registry.php

и для приложений imp, passwd и turba заменим

'status' => 'inactive',

на

'status' => 'active',

Для настройки адресной книги выполним

mysql -u horde -p horde < /usr/share/doc/turba2/examples/scripts/sql/turba.sql

admin

Зайдем в Управление - Приложения — Адресная книга (turba) и нажмем кнопку Create Адресная книга Configuration, скопируем сгенеренный текст конфигурации и запишем в файл /etc/horde/turba2/conf.php

Установка amavisd-new, SpamAssassin и ClamAV

apt-get install amavisd-new spamassassin clamav clamav-daemon zoo unzip bzip2 libnet-ph-perl libnet-snpp-perl libnet-telnet-perl nomarch lzop pax

nano /etc/amavis/conf.d/15-content_filter_mode

Раскомментируем

@bypass_virus_checks_maps = (

\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

и

@bypass_spam_checks_maps = (

\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

nano /etc/amavis/conf.d/50-user

Добавим посередке параметр

$pax='pax';

и

@lookup_sql_dsn = (['DBI:mysql:mail; host=127.0.0.1; port=3306', 'mail_admin' ,'admin']);

$sql_select_policy = 'SELECT "Y" as local FROM domains WHERE CONCAT("@",domain) IN (%k)';

nano /etc/amavis/conf.d/20-debian_defaults

Дальше — список параметров, которые используются у меня с кратким пояснением, зачем и почему.

$enable_db = 1; # enable use of BerkeleyDB/libdb (SNMP and nanny)

$enable_global_cache = 1; # enable use of libdb-based cache if $enable_db=1

$spam_check_negative_ttl = 30*60;

$spam_check_positive_ttl = 30*60;

Это позволяет держать небольшой кеш уже проверенных писем и не проверять точно такие же письма заново, если они уже есть в кеше. Проверка идет по сигнатуре, которую amavis генерирует сам. Полезно, когда, в частности, один и тот же спам валится на несколько адресов. ttl-параметры - это срок жизни сигнатуры в кеше (с положительным и отрицательным результатом проверки на спам). В моем случае, процент попадания в кеш порядка 8.

$sa_spam_subject_tag = '***SPAM*** ';

$sa_spam_report_header = 1;

$sa_tag_level_deflt = undef; # add spam info headers if at, or above that level

$sa_tag2_level_deflt = 4.5; # add 'spam detected' headers at that level

$sa_kill_level_deflt = 6.9; # triggers spam evasive actions

$sa_dsn_cutoff_level = 6.9; # spam level beyond which a DSN is not sent

$sa_quarantine_cutoff_level = 11.9;

$sa_spam_subject_tag - добавление указанной строки в начало темы письма. Удобно для получателей.

$sa_spam_report_header - добавление заголовков с подробным отчетом о результатах проверки. Учтите только, что эти заголовки будут вставлены только в письма, признанные спамом. Подробный отчет - это объяснения каждого сработавшего правила spamassassin, типа вот такого:

X-Spam-Report:

* 1.4 MSGID_MULTIPLE_AT Message-ID contains multiple '@' characters

* 0.0 HTML_MESSAGE BODY: HTML included in message

* 0.0 BAYES_50 BODY: Bayesian spam probability is 40 to 60%

* [score: 0.5000]

* 1.8 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding

* 1.3 AWL AWL: From: address is in the auto white-list

$sa_tag_level_deflt - добавлять заголовки с результатом проверки на спам в сообщения с указанной оценкой и выше. Здесь - всегда добавлять эти заголовки. Заголовки вот такие:

Х-Spam-Flag: YES

X-Spam-Score: 4.54

X-Spam-Level:

X-Spam-Status: Yes, score=4.54 required=4.5 tests=[AWL=1.336, BAYES_50=0.001,

HTML_MESSAGE=0.001, MIME_BASE64_TEXT=1.753, MSGID_MULTIPLE_AT=1.449]

если опознан спам и

X-Spam-Flag: NO

X-Spam-Score: -0.708

X-Spam-Level:

X-Spam-Status: No, score=-0.708 required=4.5 tests=[AWL=0.403, BAYES_05=-1.11,

SPF_PASS=-0.001]

если сообщение «чистое». Еще раз подчеркну, что в этом случае заголовка «X-Spam-Report:» не будет. Если нужен - нужно править сам amavis.

$sa_tag2_level_deflt - уровень, начиная с которого сообщение признается спамом.

$sa_kill_level_deflt - уровень, начиная с которого выполняется правило по обработке спама (описание ниже)

$sa_dsn_cutoff_level - уровень, начиная с которого не отсылается сообщение о невозможности доставки. Очень советую его иметь равным $sa_kill_level_deflt, иначе Вас, скорее всего, внесут в какой-нибудь черный список. Особенно это любит делать, например, att.com

$sa_quarantine_cutoff_level - уровень начиная с которого письмо не сохраняется в карантине (/var/lib/amavis/virusmails/…)

$final_virus_destiny = D_DISCARD; # (data not lost, see virus quarantine)

$final_banned_destiny = D_BOUNCE; # D_REJECT when front-end MTA

$final_spam_destiny = D_DISCARD;

$final_bad_header_destiny = D_PASS; # False-positive prone (for spam)

$virus_admin = "admin\@trest91.ru"; # due to D_DISCARD default

Параметры задают правила обработки «нехороших» сообщений:

$final_virus_destiny - просто игнорировать (сами письма сохраняются в карантине)

$final_banned_destiny - письма с запрещенными вложениями по типу файлов: сообщить отправителю о невозможности доставки

$final_spam_destiny - игнорировать (это и есть то самое правило обработки спама, о котором шла речи выше)

$final_bad_header_destiny - некорректные заголовки писем пропускать.

$virus_admin - адрес, куда доставлять сообщения о вирусах и отраженных письмах с запрещенными вложениями (postmaster), чтобы можно было проверить содержимое писем в карантине. О письмах со спамом, попавшим в карантин, сообщений не будет.

Настройки, связанные с вирусами и запрещенными вложениями лучше оставить «по умолчанию».

Конкретные уровни оценки выставьте сами (я использую именно такие, и они меня полностью удовлетворяют, по крайней мере, по прошествии довольно большого времени и накопленной bayes-овской базы и с регулярными обновлениями правил spamassassin). Недавно специально проверял - за три дня ложных срабатываний было 0 (менял D_DISCARD на D_PASS у $final_spam_destiny).

Сделаем так, чтобы amavis не проверял исходящие письма на спам, а только входящие (на вирусы он будет проверять все письма). Вставим строки

# add these for SASL SA bypass

$policy_bank{'MYUSERS'} = { # mail from submission and smtps ports

originating => 1, # Since amavisd-new 2.5.0

# declare that mail was submitted by our smtp client

bypass_spam_checks_maps => [1], # don't spam-check this mail

bypass_banned_checks_maps => [1], # don't banned-check this mail

bypass_header_checks_maps => [1], # don't header-check this mail

};

nano /etc/amavis/conf.d/21-ubuntu_defaults

и закомментируйте строки

#$final_virus_destiny = D_DISCARD; # (defaults to D_BOUNCE)

#$final_banned_destiny = D_DISCARD; # (defaults to D_BOUNCE)

#$final_spam_destiny = D_DISCARD; # (defaults to D_REJECT)

#$final_bad_header_destiny = D_PASS; # (defaults to D_PASS), D_BOUNCE suggested

#$virus_admin = undef;

#$spam_admin = undef;

adduser clamav amavis

/etc/init.d/amavis restart

/etc/init.d/clamav-daemon restart

/etc/init.d/clamav-freshclam restart

Укажем, чтобы postfix проверял почту через amavis

postconf -e 'content_filter = amavis:[127.0.0.1]:10024'

postconf -e 'receive_override_options = no_address_mappings'

sudo nano /etc/postfix/master.cf

добавим в конец следующие строки

amavis unix - - - - 2 smtp

-o smtp_data_done_timeout=1200

-o smtp_send_xforward_command=yes

127.0.0.1:10025 inet n - - - - smtpd

-o content_filter=

-o local_recipient_maps=

-o relay_recipient_maps=

-o smtpd_restriction_classes=

-o smtpd_client_restrictions=

-o smtpd_helo_restrictions=

-o smtpd_sender_restrictions=

-o smtpd_recipient_restrictions=permit_mynetworks,reject

-o mynetworks=127.0.0.0/8

-o strict_rfc821_envelopes=yes

-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks

-o smtpd_bind_address=127.0.0.1

/etc/init.d/postfix restart

Для периодической очистки карантина вставим в cron

crontab -e

1 0 * * * find /var/lib/amavis/virusmails/* -mtime +60 | xargs rm &> /dev/null

(ежедневная очистка всех файлов из карантина, старше 60 дней)

Установка Razor, Pyzor And DCC и настройка SpamAssassin

apt-get install razor pyzor

cd /tmp

wget http://launchpadlibrarian.net/11564361/dcc-server_1.3.42-5_i386.deb

wget http://launchpadlibrarian.net/11564359/dcc-common_1.3.42-5_i386.deb

dpkg -i dcc-common_1.3.42-5_i386.deb

dpkg -i dcc-server_1.3.42-5_i386.deb

cd ~

(Для работы клиента DCC нам нужно пробросить на шлюзе UDP порт 6277 на наш почтовый сервер)

nano /etc/spamassassin/local.cf

Добавляем в конец

#dcc

use_dcc 1

dcc_path /usr/bin/dccproc

#pyzor

use_pyzor 1

pyzor_path /usr/bin/pyzor

#razor

use_razor2 1

razor_config /etc/razor/razor-agent.conf

#bayes

use_bayes 1

use_bayes_rules 1

bayes_auto_learn 1

nano /etc/spamassassin/v310.pre

раскомментируем такую строчку

loadplugin Mail::SpamAssassin::Plugin::DCC

spamassassin --lint

(Мы не должны получить никакого сообщения, если у нас все в норме.)

sa-update --no-gpg

crontab -e

23 4 */2 * * /usr/bin/sa-update --no-gpg &> /dev/null

( Это позволит обновлять набор правил каждый 2 день в 4 часа 23 минуты. )

su amavis

cd

razor-admin -create

razor-admin -register

Register successful. Identity stored in /var/lib/amavis/.razor/identity-XXXXXXXXXX

exit

После этого у нас появится директория /var/lib/amavis/.razor/ в которой будет лежать информация о серверах razor и о имени/пароле для доступа к ним (сгенеренные автоматически).

Зададим правила отчета о спаме в horde. Зайдем броузером на https://nx2.trest91.ru под административной записью и зайдя в Управление - Приложения - Почта (imp) и выберем закладку Message and Spam.

В поле «Should we report the spam message via an external program (e.g. /usr/local/bin/spamassassin -r)? If you include the placeholder %u in this string, it will be replaced with the current username. If you include the placeholder %l in this string, it will be replaced with the current short username. If you include the placeholder %d in this string, it will be replaced with the current domain name.» введем /usr/local/bin/spamassassin -r а в поле «Should we report the innocent message via an external program (e.g. /usr/local/bin/spamassassin -k)? If you include the placeholder %u in this string, it will be replaced with the current username» введем /usr/local/bin/spamassassin -k

ln -s /var/lib/amavis/.pyzor /var/www/.pyzor

ln -s /var/lib/amavis/.razor /var/www/.razor

ln -s /var/lib/amavis/.spamassassin /var/www/.spamassassin

chmod -R g+rw /var/lib/amavis/.pyzor

chmod -R g+rw /var/lib/amavis/.razor

chmod -R g+rw /var/lib/amavis/.spamassassin

chmod g+x /var/lib/amavis/.pyzor

chmod g+x /var/lib/amavis/.razor

chmod g+x /var/lib/amavis/.spamassassin

adduser www-data amavis

/etc/init.d/apache2 restart

nano /etc/mail/spamassassin/local.cf

вставим туда строку

bayes_path /var/lib/amavis/.spamassassin/bayes

Вставим периодическое обновление нашей bayes-базы (будем делать это каждую ночь).

nano /etc/cron.d/amavisd-new

вставим строку

1 0 * * * amavis sa-learn --force-expire --sync

Таким образом, при приеме писем postfix при помощи amavis будет проверять письма в том числе по bayes-базе, которая формируется автоматически (обучение идет из писем с достаточно большим значением уровня спама; письма с очень малым показателем также участвуют в обучении — они помечаются, как ham, т. е. не-спам; письма со средним значением уровня спама в автоматическом обучении не участвуют). Кроме этого, в пополнении базы данных принимают участие и пользователи, когда помечают письма, как спам или не-спам (innocent). Чем больше писем участвует в обучении (и как спам, и как ham), тем лучше работает bayes-база данных спама.

Дополнительные правила для защиты от спама

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

Дело в том, что процесс передачи/получения письма начинается с представления серверов друг другу. После соединения по порту 25 (SMTP), компьютер - инициатор выдает команду

HELO hostname.domain.ltd

Принимающий сервер уже на этом этапе может отсечь кучу спама. Как это сделать? Очень просто. Нормально сконфигурированный сервер обязан в сообщении HELO передать свое истинное имя; причем это имя должно соответствовать IP-адресу, с которого осуществляется соединение; а IP-адрес должен резолвится в обратной зоне в это имя. Если это не так - Вы имеете полное право отсечь соединение прямо на этом этапе. Плюсы: не тратится лишний трафик на прием сообщений, которые заведомо являются спамом; экономятся вычислительные затраты на дальнейшие проверки писем на спам и вирусы. Необходим какой-то трафик для проведения проверок по DNS (но он заведомо меньше трафика на прием писем). Отсечь «нормальное» письмо бояться не стоит: неверная настройка почтового сервера, который Вы отсекли - не Ваша головная боль.

Для того, чтобы такие проверки проводились на этапе приемки писем, в файл /etc/postfix/main.cf нужно вставить следующие строки:

strict_rfc821_envelopes = yes

disable_vrfy_command = yes

smtpd_delay_reject = yes

smtpd_helo_required = yes

smtpd_client_restrictions = sleep 1, reject_unauth_pipelining, permit_sasl_authenticated, permit_mynetworks, reject_unknown_client_hostname, permit

smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname, permit

smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unknown_sender_domain, permit

smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unlisted_recipient, check_policy_service inet:127.0.0.1:10023, permit

Если Вы не собираетесь использовать postgrey не вставляйте check_policy_service inet:127.0.0.1:10023,

Подробнее об этих параметрах:

strict_rfc821_envelopes - запрет на использование заголовков в стиле RFC822. Если кратко - этот стандарт не имеет отношения к SMTP, а к формату самих писем, и не должен использоваться на этапе общения между серверами. Даже их названия об этом говорят: 821: SIMPLE MAIL TRANSFER PROTOCOL, 822: STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES.

disable_vrfy_command - запрет на использование команды VRFY. Эта команда зачастую используется для сбора с сервера существующих адресов почты для дальнейшей рассылки на них спама.

smtpd_delay_reject - подождать команды RCPT TO перед (возможным) отказом от приема письма. Нужно из-за того, что некоторые сервера неверно реагируют на отказ от приема писем до посылки ими команды RCPT TO

smtpd_helo_required - требовать от сервера обязательно представиться командой HELO. Это дает возможность проведения нужных нам проверок.

Проверки на каждом этапе происходят последовательно, в указанном в каждой команде порядке. Если условие выполнено, дальнейшие проверки не производятся.

smtpd_client_restrictions - ограничения на этапе установления связи по протоколу SMTP

sleep 1 - пауза на 1 секунду для отсекания совсем нетерпеливых спам-хостов (обычно они просто сразу же рвут соединение - им нужно разослать как можно больше спама, поэтому ждать им - как серпом…)

reject_unauth_pipelining - отсечь хосты, которые пытаются слать команды в конвейере, даже не проверив, поддерживает ли это наш сервер. Это часто делают именно спам-хосты для увеличения скорости передачи

permit_sasl_authenticated - разрешить для авторизованных клиентов (пользователи)

permit_mynetworks - разрешить при соединении из моей подсети

reject_unknown_client_hostname -отказать в случае, если 1) не удалось сопоставить IP адрес имени хоста (по PTR-записи в DNS), 2) не удалось сопоставить имя IP-адресу хоста (прямой запрос DNS), 3) адрес, полученный из DNS по имени не совпадает с IP-адресом , с которого идет соединение. Отсекается ОЧЕНЬ много спам-хостов (в моем случае - процентов 80)

permit - в другом случае продолжать прием

smtpd_helo_restrictions - ограничения на этапе команды HELO:

permit_mynetworks - разрешить при соединении из моей подсети

permit_sasl_authenticated - разрешить при аутентификации (пользователи)

reject_invalid_helo_hostname - отказать при нарушении синтаксиса имени хоста в HELO (случается очень редко, тем не менее…)

reject_non_fqdn_helo_hostname - отказать, если имя хоста в HELO не в полной форме (не должно быть просто server, а должно быть типа server.domain.ltd)

reject_unknown_helo_hostname - отказать, если у хоста, указанного в команде HELO, в DNS нет записи типа MX или A (множество зобми-хостов)

permit - в другом случае продолжать прием

smtpd_sender_restrictions - проверки по команде MAIL FROM (имя отправителя)

permit_mynetworks - разрешить при соединении из моей подсети

permit_sasl_authenticated - разрешить при аутентификации (пользователи)

reject_non_fqdn_sender - отказать, если имя отправителя не в полной форме (должно быть не name или name@domain а name@domain.ltd)

reject_unknown_sender_domain - отказать, если наш сервер не является «родным» для отправителя и домен отправителя не имеет в DNS записи MX или A, или если он имеет неверную запись MX (например, пустую)

permit - в другом случае продолжать прием

smtpd_recipient_restrictions - проверки по команде RCPT TO (имя получателя)

reject_unauth_pipelining - отсечь хосты, которые пытаются слать команды в конвейере

permit_sasl_authenticated - разрешить для авторизованных клиентов (пользователи)

permit_mynetworks - разрешить при соединении из моей подсети

reject_unauth_destination - отказать, если домен-адресат: 1) не перечислен в списке доменов, для которых мы форвардим почту ($relay_domains) и не содержит команд переадресации (типа user@another@domain); 2) не является «нашим» (т.е. не перечислен в списках $mydestination, $inet_interfaces, $proxy_interfaces, $virtual_alias_domains, или $virtual_mailbox_domains ) и не содержит команд переадресации (типа user@another@domain). Это - традиционные правила, чтобы наш сервер не служил т.н. Open Relay, через который спамеры рассылают почту третьим лицам.

reject_non_fqdn_recipient - отказать, если имя получателя не в полной форме (должно быть не name или name@domain а name@domain.ltd)

reject_unknown_recipient_domain - отказать, если мы не являемся «родным» сервером для получателя и домен получателя не имеет в DNS записи MX или A, или если он имеет неверную запись MX (например, пустую)

reject_unlisted_recipient - отказать, если адрес получателя не указан в списках получателей домена (не перечислен в $local_recipient_maps или $virtual_alias_maps или $virtual_mailbox_maps или $relay_recipient_maps, в зависимости от того, в какой именно таблице найден домен получателя)

check_policy_service inet:127.0.0.1:10023 - проверка у стороннего сервиса (в данном случае - postgrey, о нем чуть позже)

permit - продолжать прием

Такая конфигурация позволяет отсечь просто КУЧУ спама.

Установка postgrey

Теперь о postgrey. Это еще один способ борьбы со спамом Работает он так. При приходе письма (конечно, если оно «прорвалось» через все проверки, указанные выше) сервер запоминает три параметра (так называемый триплет): от кого оно послано, кому послано, и кем (т.е. адрес сервера, который его посылает), и сообщает передающему серверу «Я сейчас занят, повторите чуть позже», после чего начинает отсчет времени для конкретного триплета. Большинство спамеров, как мы знаем, ждать не любят, и либо пытаются повторить посылку сразу же (на что получают тот же ответ), либо просто прекращают свои попытки. Наш же сервер, если обнаружит повторное письмо с тем же триплетом по прошествии некоторого времени (по умолчанию - 5 минут), спокойно его примет. При этом этот триплет будет запомнен на какое-то время (35 дней), так что следующие письма с тем же триплетом пройдут без задержки. Если это Ваш постоянный корреспондент, то задержек больше не будет вообще.

apt-get install postgrey

nano /etc/default/postgrey

Отредактируйте строку

POSTGREY_OPTS="--inet=127.0.0.1:10023"

добавив параметры –delay=N (в секундах; по умолчанию 300) и –max-age=N (в сутках; по умолчанию 35):

POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=300 --max-age=35"

Стоит заглянуть еще в два файла: это /etc/postgrey/whitelist_clients и /etc/postgrey/whitelist_recipients. В первом перечислены домены-отправители, письма от которых принимаются автоматом (по разным причинам), во втором - адреса-получатели, письма на которые также принимаются сразу всегда (например, abuse@). Можете при необходимости дописать в эти файлы свои строки.

Установка spf, , sender id, dkim, domainkey

Зачастую спамеры пытаются «замаскироваться» под обычных отправителей, т.е. подделывают обратный адрес (mail from:).

Есть способ а) обезопасить себя от таких «подделок» и б) проверять на этапе приема, не подделан ли обратный адрес.

Для этого в настоящее время существует четыре варианта. Советую использовать все.

Основная идея у всех вариантов похожа: в запись DNS Вашего домена вставляется некая информация, проверив которую принимающий сервер может определить, есть ли у отправителя разрешение на отсылку писем от имени указанного домена.

Использование SPF

В DNS-запись своего домена нужно вставить следующую строку:

Trest91.ru. IN TXT "v=spf1 a mx -all"

Эта запись означает, что домен trest91.ru использует версию SPF1 и разрешает от своего имени посылать почту серверу, указанному в записи MX и A домена, и запрещает всем остальным.

На этапе приема сервер запросит в DNS запись MX и A Вашего домена, и, если полученный IP-адрес не совпадает с IP-адресом отправителя, то письмо будет отклонено.

Вместо -all на этапе тестирования можно вставить ~all (в этом случае письмо будет не отклонено, а сервер-получатель получит «предупреждение» о возможной подделке адреса отправителя - т.н. softfail).

Для того, чтобы Ваш почтовый сервер производил проверку по SPF, нужно установить пакеты:

apt-get install python-policyd-spf python-spf

nano /etc/postfix/main.cf

вставьте строку

spf-policyd_time_limit = 3600s

В строку smtpd_recipient_restrictions вставьте

check_policy_service unix:private/policy-spf,

nano /etc/postfix/master.cf

вставьте строки

policy-spf unix - n n - - spawn

user=nobody argv=/usr/bin/policyd-spf

Проверка на SPF нужна только для входящих писем, исходящие письма с Вашего сервера проверять не надо.

/etc/init.d/postfix reload

Использование Domainkey и DKIM

Эта технология несколько отличается от SPF. DKIM - это несколько улучшенный вариант Domainkey, однако лучше использовать оба сервиса, тем более, что установка очень похожа. Для использования Domankey и DKIM установим пакеты

apt-get install dk-filter dkim-filter

Выбирайте все опции «по умолчанию» при установке - сейчас мы сконфигурируем их вручную. Вначале сгенерим ключи

dkim-genkey -d trest91.ru -s mail

У Вас в текущей директории появится два файла: mail.private и mail.txt

smkdir /etc/mail/trest91.ru

mv mail.private /etc/mail/trest91.ru/mail

chown root /etc/mail/trest91.ru/mail

chmod 644 /etc/mail/trest91.ru/mail

mv mail.txt trest91.ru.txt

nano /etc/default/dk-filter

вставим туда строку

DAEMON_OPTS="$DAEMON_OPTS -d trest91.ru -k -s /etc/mail/dk-keys.conf -S mail"

и строку

SOCKET="inet:8892@localhost"

nano /etc/default/dkim-filter

Строка

SOCKET="inet:8891@localhost" # Ubuntu default - listen on loopback on port 8891

должна быть раскомментарена.

nano /etc/dkim-filter.conf

поменяем в нем строку

Domain trest91.ru

и следующие строки

Selector mail

AutoRestart no

Background yes

Canonicalization simple

DNSTimeout 5

Mode sv

SignatureAlgorithm rsa-sha256

SubDomains yes

X-Header no

AlwaysAddARHeader yes

On-BadSignature reject

Statistics /var/log/dkim-filter/dkim-stats

KeyList /etc/mail/dkim-keys.conf

nano /etc/mail/dkim-keys.conf

*@trest91.ru:trest91.ru:/etc/mail/trest91.ru/mail

nano /etc/mail/dk-keys.conf

*@trest91.ru:/etc/mail/trest91.ru/mail

mkdir /var/log/dkim-filter

chown dkim-filter /var/log/dkim-filter

nano /etc/postfix/main.cf

добавим в него строки

milter_default_action = accept

milter_protocol = 2

#smtpd_milters = inet:localhost:8891,inet:localhost:8892 ; for internal delivery only

non_smtpd_milters = inet:localhost:8891,inet:localhost:8892

Мы хотим, чтобы подписывались только исходящие письма, поэтому строка smtpd_milters закомментарена.

nano /etc/amavis/conf.d/21-ubuntu_defaults

содержит раскомментаренную строку

$enable_dkim_verification = 1;

Последнее, что нам осталось сделать - это внести изменения в DNS-записи нашего домена:

mail._domainkey.trest91.ru. IN TXT "g=*; k=rsa; p=XXXXXXXXXX" ; ----- DKIM mail for trest91.ru

_domainkey.trest91.ru. IN TXT "o=-"

вместо XXXXXXXXXX - значение, записанное в «p=» в файле trest91.ru.txt для соответствующего домена, который появился при генерации ключей.

Важное замечание: в записи _domainkey.trest9.ru. вместо «o=-» на этапе тестирования можно вставить «o=~». Первое означает, что ВСЕ письма от вашего домена подписываются, а второе - что подписываются только некоторые письма.

Кроме этого, на этапе тестирования в запись mail._domainkey.trest91.ru. (внутри кавычек) можно добавить ключ t=y; :

mail._domainkey.trest91.ru. IN TXT "g=*; k=rsa; t=y; p=XXXXXXXXXX" ; ----- DKIM mail for trest91.ru

_domainkey.trest91.ru. IN TXT "o=~"

ВАЖНО: При внесении изменений в зону DNS не забудьте увеличить номер зоны в записи SOA!

/etc/init.d/dk-filter restart

/etc/init.d/dkim-filter restart

Если они запустились нормально, перезапускаем postfix

/etc/init.d/postfix restart

Протестировать только что установленные сервисы можно послав тестовое письмо на адрес check-auth@verifier.port25.com

В ответ Вы получите письмо с результатами проверки всех четырех сервисов. Если в ответе будет примерно следующее:

==========================================================

Summary of Results

==========================================================

SPF check: pass

DomainKeys check: pass

DKIM check: pass

Sender-ID check: pass

то все работает нормально.

Проверяем работу антиспама и антивируса

Для проверки работы антивируса пошлите себе с внешнего почтового аккаунта (например, gmail) письмо, содержащее следующую строку (это - не вирус, а стандартное тестовое письмо EICAR для проверки антивируса):

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

и проверьте логи /etc/log/mail.log

cat /var/log/mail.log | grep "Blocked INFECTED"

Вы должны увидеть примерно такую запись:

Nov 30 22:02:22 oban amavis[21994]: (21994-01) Blocked INFECTED (Eicar-Test-Signature(69630e4574ec6798239b091cda43dca0:69)), [209.85.161.169] [209.85.161.169] <username@gmail.com> -> <admin@trest91.ru>, quarantine: n/virus-nGy-KxAsczIP, Message-ID: <AANLkTinxbYap5wcw8pstUQiLCuR1GjQQNPcWT_SCKtAo@mail.gmail.com>, mail_id: nGy-KxAsczIP, Hits: -, size: 2159, dkim_id=@gmail.com,username@gmail.com, 157 ms

Это письмо попадет в карантин (в нашем случае — в /var/lib/amavis/n/virus-nGy-KxAsczIP)

Для проверки антиспама пошлите себе с внешнего почтового аккаунта (например, gmail) письмо, содержащее следующую строку (это стандартный антиспам-тест GTUBE):

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

и проверьте логи /etc/log/mail.log

cat /var/log/mail.log | grep "Blocked SPAM"

Nov 30 22:37:29 oban amavis[22916]: (22916-01) Blocked SPAM, [209.85.161.41] [209.85.161.41] <username@gmail.com> -> <admin@trest91.ru>, Message-ID: <AANLkTinwyt0y-nk2yynQ40LfGmv9kO5vv082zubwwrk+@mail.gmail.com>, mail_id: ZD4iIEb5EZHD, Hits: 1002.473, size: 2168, dkim_id=@gmail.com,username@gmail.com, 2727 ms

Установка fail2ban

Еще одно добавление к серверу. Дело в том, что все сервера так или иначе «торчащие» в интернет, становятся целью для атак, и наш почтовый сервер - не исключение. Одна из атак - попытка «взлома» паролей пользователей. Такая атака обычно проводится с перебором паролей, и рано или поздно может быть удачной. В нашем случае - это атака на аутентификацию пользователей по IMAP, POP3, SMTP.

Бороться достаточно просто - есть прекрасная программа fail2ban, которая после N неудачных попыток просто прописывает в файрволле правила, запрещающие доступ с атакующего IP-адреса на определенный срок (чаще всего - на час через 3 неудачных попытки). Такие «паузы» делают подобные атаки практически бессмысленными.

apt-get install fail2ban

sudo nano /etc/fail2ban/filter.d/dovecot.conf

[Definition]

failregex = (?: pop3-login|imap-login): (?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed).*rip=(?P<host>\S*),.*

ignoreregex =

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf_orig

nano /etc/fail2ban/jail.conf

ignoreip = 127.0.0.1 10.0.0.0/16

bantime = 3600

destemail = admin@trest91.ru

[ssh]

enabled = true

port = ssh

filter = sshd

banaction = iptables-allports

sendmail-whois

logpath = /var/log/auth.log

maxretry = 3

[dovecot]

enabled = true

port = imap2,imap3,imaps,pop3,pop3s

filter = dovecot

logpath = /var/log/mail.log

banaction = iptables-allports

sendmail-whois

maxretry = 3

[sasl]

enabled = true

port = smtp,ssmtp

filter = sasl

banaction = iptables-allports

sendmail-whois

logpath = /var/log/mail.warn

maxretry = 3

Пример записи в /etc/log/auth.log которая будет «поймана»

Nov 25 10:19:41 oban sshd[30769]: Failed password for root from AA.BB.CC.DD port 60031 ssh2

Примеры записей в /etc/log/mail.log которые будут «пойманы»

Nov 27 23:41:57 oban dovecot: imap-login: Aborted login (no auth attempts): rip=AA.BB.CC.DD, lip=10.0.0.6

Nov 27 23:40:18 oban dovecot: pop3-login: Disconnected (no auth attempts): rip=AA.BB.CC.DD, lip=10.0.0.6, TLS handshaking: SSL_accept() failed: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

nano /etc/fail2ban/filter.d/sasl.conf

#failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [A-Za-z0-9+/]*={0,2})?$

failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed

Примеры записей в /etc/log/mail.log которые будут «пойманы»

Nov 24 19:21:20 oban postfix/smtpd[458]: warning: unknown[AA.BB.CC.DD]: SASL LOGIN authentication failed: generic failure

Nov 24 22:32:35 oban postfix/smtpd[2593]: warning: unknown[AA.BB.CC.DD]: SASL LOGIN authentication failed: authentication failure

Можно проверить срабатывание написанных нами правил:

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/dovecot.conf

fail2ban-regex /var/log/mail.warn /etc/fail2ban/filter.d/sasl.conf

Если в лог-файлах были попытки неверной аутентификации, мы получим по ним «отчет».

/etc/init.d/fail2ban restart

Установка mailman

sudo apt-get install mailman

Ответим на вопросы

Поддерживаемые языки:

Выберем русский и английский (en и ru)

Язык по умолчанию для Mailman:

ru (Russian)

Нас предупредят, что Отсутствует список рассылки сайта. Мы его создадим чуть позже.

Т.к. mailman не поддерживает utf8, часть операций с mailman производим с указанием LANG=C

Исправим ошибки (они неизбежны при установке) и проверим:

LANG=C sudo check_perms -f

LANG=C sudo check_perms

Мы получим что-то типа такого списка

/var/lib/mailman/mail bad group (has: root, expected list)

/var/lib/mailman/templates bad group (has: root, expected list)

/var/lib/mailman/locks bad group (has: root, expected list)

/var/lib/mailman/logs bad group (has: root, expected list)

/var/lib/mailman/bin bad group (has: root, expected list)

/var/lib/mailman/cgi-bin bad group (has: root, expected list)

/var/lib/mailman/cron bad group (has: root, expected list)

/var/lib/mailman/scripts bad group (has: root, expected list)

/var/lib/mailman/icons bad group (has: root, expected list)

/var/lib/mailman/Mailman bad group (has: root, expected list)

Problems found: 10

Re-run as list (or root) with -f flag to fix

Это нормально, т.к. все это — ссылки.

chown -R list /var/lib/mailman/archives/*

chmod o+x/var/lib/mailman/archives/private

nano /etc/mailman/mm_cfg.py

DEFAULT_EMAIL_HOST = 'trest91.ru'

DEFAULT_URL_HOST = 'lists.trest91.ru'

MTA=None # Misnomer, suppresses alias output on newlist

nano /etc/postfix/master.cf

Если в нем строка mailman имеет вид

mailman unix - - n - - pipe

то изменим ее на

mailman unix - n n - - pipe

nano /etc/apache2/sites-available/mailman

<VirtualHost *:80>

ServerName lists.trest91.ru

Alias /images/ /usr/share/images/

RedirectMatch ^/$ http://lists.trest91.ru/cgi-bin/mailman/listinfo

ScriptAlias /mailman/ /usr/lib/cgi-bin/mailman/

ScriptAlias /cgi-bin/mailman/ /usr/lib/cgi-bin/mailman/

<Directory /usr/lib/cgi-bin/mailman/>

AllowOverride None

Options ExecCGI

Order allow,deny

Allow from all

</Directory>

Alias /pipermail/ /var/lib/mailman/archives/public/

<Directory /var/lib/mailman/archives/public>

AddDefaultCharset KOI8-R

Options Indexes MultiViews FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

Alias /archives/ /var/lib/mailman/archives/public/

<Directory /var/lib/mailman/archives/public>

AddDefaultCharset KOI8-R

DirectoryIndex index.html

Options Indexes MultiViews FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

CustomLog /var/log/apache2/lists.log combined

<Directory /var/lib/mailman/archives/>

Options Indexes FollowSymLinks

AllowOverride None

</Directory>

</VirtualHost>

a2ensite mailman

/etc/init.d/apache2 restart

mysql -u mail_admin -p

admin

use mail;

INSERT INTO transport (domain, transport) VALUES ('lists.trest91.ru', 'mailman:');

quit;

nano /etc/postfix/master.cf

и убедимся, что он содержит

mailman unix - n n - - pipe

flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}

nano /etc/postfix/main.cf

и добавим в него

# For mailman

relay_domains = lists.trest91.ru

mailman_destination_recipient_limit = 1

/etc/init.d/apache2 restart

/etc/init.d/postfix reload

LANG=C sudo /etc/init.d/mailman start

Создание листа рассылки

LANG=C sudo newlist mailman

admin

Введем адрес администратора листа рассылки

admin@trest91.ru

admin

Нажмите Enter.

Добавим в таблицу forwardings базы данных mail следующие записи:

mailman@trest91.ru mailman@lists.trest91.ru

mailman-admin@trest91.ru mailman-admin@lists.trest91.ru

mailman-bounces@trest91.ru mailman-bounces@lists.trest91.ru

mailman-confirm@trest91.ru mailman-confirm@lists.trest91.ru

mailman-join@trest91.ru mailman-join@lists.trest91.ru

mailman-leave@trest91.ru mailman-leave@lists.trest91.ru

mailman-owner@trest91.ru mailman-owner@lists.trest91.ru

mailman-request@trest91.ru mailman-request@lists.trest91.ru

mailman-subscribe@trest91.ru mailman-subscribe@lists.trest91.ru

mailman-unsubscribe@trest91.ru mailman-unsubscribe@lists.trest91.ru

mysql -u mail_admin -p

admin

use mail;

INSERT INTO forwardings (source, destination) VALUES ('mailman@trest91.ru', 'mailman@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-admin@trest91.ru', 'mailman-admin@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-bounces@trest91.ru', 'mailman-bounces@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-confirm@trest91.ru', 'mailman-confirm@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-join@trest91.ru', 'mailman-join@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-leave@trest91.ru', 'mailman-leave@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-owner@trest91.ru', 'mailman-owner@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-request@trest91.ru', 'mailman-request@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-subscribe@trest91.ru', 'mailman-subscribe@lists.trest91.ru ');

INSERT INTO forwardings (source, destination) VALUES ('mailman-unsubscribe@trest91.ru', 'mailman-unsubscribe@lists.trest91.ru );

quit;

LANG=C sudo /etc/init.d/mailman stop

LANG=C sudo /etc/init.d/mailman start

Нам нужно вставить в DNS-зону для нашего домена запись типа

lists CNAME oban.trest91.ru.

чтобы у нас был доступ к нашим спискам рассылки через веб.

Теперь мы можем зайти с паролем администратора листа mailman браузером на http://lists.trest91.ru для дальнейшей настройки листа рассылки.

Установка автоответчика

Создадим файл ./autoresponse следующего содержания (отличие от варианта, лежащего на http://nefaria.com/project_index/autoresponse/ в том, что для совместимости с mailman мы используем -autoresponse вместо +autoresponse):

nano ~/autoresponse

Для экономия времени текст за решеткой # можно не печатать

#!/bin/bash

#+--------------------------------------------------------+

#|autoresponse 1.6.3 - an autoresponder script for postfix|

#| Charles Hamilton - musashi@nefaria.com |

#| This program is GNU/GPL software |

#+--------------------------------------------------------+

shopt -s -o nounset

shopt -s extglob

if [ "${#}" -eq "0" ]; then

printf "%s\n" "Autoresponse v. 1.6.2"

printf "%s\n" "Type -h for help"

exit 0

fi

declare RECIPIENT="unset"

declare SENDER="unset"

declare SASL_USERNAME="unset"

declare CLIENT_IP="unset"

declare AUTHENTICATED="unset"

declare AUTORESPONSE_MESSAGE="unset"

declare DISABLE_AUTORESPONSE="unset"

declare ENABLE_AUTORESPONSE="unset"

declare DELETE_AUTORESPONSE="unset"

declare SEND_RESPONSE="unset"

declare RESPONSES_DIR="/var/spool/autoresponse/responses"

declare SENDMAIL="/usr/sbin/sendmail"

declare RATE_LOG_DIR="/var/spool/autoresponse/log"

declare LOGGER="/usr/bin/logger"

#There are two different modes of operation:

# MODE="0" represents the actions that can not be executed from the command line

# MODE="1" represents the actions that can be executed from the command line

declare MODE="0"

#Time limit, in seconds that determines how often an

#autoresponse will be sent, per e-mail address (3600 = 1 hour, 86400 = 1 day)

declare RESPONSE_RATE="86400"

while getopts "r:s:S:C:e:d:E:D:h" SWITCH; do

case "${SWITCH}" in

r) #Set the recipient's address

RECIPIENT="`echo ${OPTARG} | tr '[:upper:]' '[:lower:]'`"

SEND_RESPONSE="1"

;;

s) #Set the sender's address

SENDER="`echo ${OPTARG} | tr '[:upper:]' '[:lower:]'`"

SEND_RESPONSE="1"

;;

S) #If SASL_USERNAME exists then the user was authenticated

SASL_USERNAME="${OPTARG}"

if [ -z "${SASL_USERNAME}" ]; then

AUTHENTICATED="0"

else

AUTHENTICATED="1"

fi

;;

C) #IP address of client (sender)

CLIENT_IP="${OPTARG}"

;;

e) #Set the filename of the user's autoresponse message

#This is used for creating/editing new autoresponse messages

AUTORESPONSE_MESSAGE="${OPTARG}"

MODE="1"

;;

d) #Disable an existing autoresponse message

DISABLE_AUTORESPONSE="${OPTARG}"

MODE="1"

;;

E) #Enable an existing autoresponse message

ENABLE_AUTORESPONSE="${OPTARG}"

MODE="1"

;;

D) #Delete an existing autoresponse message

DELETE_AUTORESPONSE="${OPTARG}"

MODE="1"

;;

h|*) #Print the help dialog and exit

echo -e "\n${0} [-r {recipient email} -s {sender email} -S {sasl username} -C {client ip}] [-e {email address}] [-d {email address}] [-E {email address}] [-D {email address}] [-h]\n"

echo -e " -r, -s, -S, and optionally -C must be used together to specify a recipient, sender, sasl username, and client IP of an autoresponse message."

echo -e " Normally you configure these in postfix's \"master.cf\" but they can be used from the terminal as well (only for testing purposes!)."

echo -e " If this is executed from a terminal, you'll need to hit CTRL-D when you are finished typing your autoresponse message.\n"

echo " -e is used to create a new autoresponse or edit an existing one for the specified user."

echo -e " If a disabled autoresponse message exists, it will be ignored and a new message will be created.\n"

echo -e " -d is used to disable an existing active autoresponse message.\n"

echo " -E is used to enable an existing autoresponse message. If both a disabled AND and an active autoresponse message exist,"

echo -e " the active message will be overwritten by the disabled one.\n"

echo -e " -D is used to delete an existing autoresponse message, it will not delete disabled autoresponse messages.\n"

echo -e " -h prints this help menu\n"

exit 0

;;

esac

done

#If a SASL authenticated user wants to set their autoresponse message via e-mail...

if [ "${AUTHENTICATED}" = "1" ] && [ "${RECIPIENT/@*/}" = "${SENDER/@*/-autoresponse}" ] && [ "${MODE}" = "0" ]; then

if [ -f "${RESPONSES_DIR}/${SENDER}" ]; then

#Delete a user's existing autoresponse message.

(${0} -D "${SENDER}")

if [ ! -f "${RESPONSES_DIR}/${SENDER}" ]; then

${LOGGER} -i -t autoresponse -p mail.notice "Autoresponse disabled for address: ${SENDER} by SASL authenticated user: ${SASL_USERNAME} from: ${CLIENT_IP}"

(echo -e "From: ${RECIPIENT}\nTo: ${SENDER}\nSubject: Out of Office\n\n"

echo "Autoresponse disabled for ${SENDER} by SASL authenticated user: ${SASL_USERNAME} from: ${CLIENT_IP}") | ${SENDMAIL} -i -f "${RECIPIENT}" "${SENDER}"

else

${LOGGER} -i -t autoresponse -p mail.notice "Autoresponse could not be disabled for address: ${SENDER}"

fi

elif [ ! -f "${RESPONSES_DIR}/${SENDER}" ]; then

#Read from STDIN and save this as the user's autoresponse message.

#This will overwrite any pre-existing autoresponse messages!

cat > "${RESPONSES_DIR}/${SENDER}"

if [ -f "${RESPONSES_DIR}/${SENDER}" ]; then

${LOGGER} -i -t autoresponse -p mail.notice "Autoresponse enabled for address: ${SENDER} by SASL authenticated user: ${SASL_USERNAME} from: ${CLIENT_IP}"

(echo -e "From: ${RECIPIENT}\nTo: ${SENDER}\nSubject: Out of Office\n\n"

echo "Autoresponse enabled for ${SENDER} by SASL authenticated user: ${SASL_USERNAME} from: ${CLIENT_IP}") | ${SENDMAIL} -i -f "${RECIPIENT}" "${SENDER}"

else

${LOGGER} -i -t autoresponse -p mail.notice "Autoresponse could not be enabled for address: ${SENDER}"

fi

fi

#Log any unauthenticated shenanigans. We're attempting to prevent two scenarios here:

#

#(1) A user sends an e-mail to user-autoresponse@domain.tld from user@domain.tld through an open relay

# in an unauthorized attempt to set an autoresponse for the real user@domain.tld. The open relay

# will relay the message but because it will not authenticate with the mail server for domain.tld

# AUTHENTICATED will equal 0 and the user portion of the recipient address will equal user-autoresponse.

# Since we do not allow unauthenticated users to set autoresponse messages, we log this attempt as

# suspicious and exit cleanly so that postfix doesn't generate a bounce message.

#

#(2) A user sends e-mail to user-autoresponse@domain.tld from user@domain.tld through a mail server

# that requires authentication, (but allows relaying) and has autoresponse configured. This will result in

# an autoresponse toggle message being sent to the real user@domain.tld, notifying them that their

# autoresponse message has been enabled or disabled when in fact it has not. This scenario is rarer

# than the first and it is mainly meant to protect against compromised accounts and/or potential abuse

# by legitimate users of the rogue mail server.

#

elif [ "${AUTHENTICATED}" = "0" ] && [ "${RECIPIENT/@*/}" = "${SENDER/@*/-autoresponse}" ] || [ "${SENDER/@*/-autoresponse}" = "${RECIPIENT/@*/-autoresponse-autoresponse}" ] && [ "${MODE}" = "0" ]; then

${LOGGER} -i -t autoresponse -p mail.warning "Unauthenticated attempt to set autoresponse message for ${SENDER/-autoresponse/} from ${CLIENT_IP}!"

exit 0

#Finally, if the user recipient address does not equal user-autoresponse then we assume that it's

#just a normal message. We check to see if the recipient has an autoresponse message set; if one

#has not already been sent to the sender within our timeframe, we send it and then we deliver the

#original message to the original recipient.

elif [ "${RECIPIENT/@*/}" != "${SENDER/@*/-autoresponse}" ] && [ "${MODE}" = "0" ]; then

rate_log_check() {

#Only send one autoresponse per e-mail address per the time limit (in seconds) designated by the RESPONSE_RATE variable

if [ -f "${RATE_LOG_DIR}/${RECIPIENT}/${SENDER}" ]; then

declare ELAPSED_TIME=`echo $[\`date +%s\` - \`stat -c %X "${RATE_LOG_DIR}/${RECIPIENT}/${SENDER}"\`]`

if [ "${ELAPSED_TIME}" -lt "${RESPONSE_RATE}" ]; then

${LOGGER} -i -t autoresponse -p mail.notice "An autoresponse has already been sent from ${RECIPIENT} to ${SENDER} within the last ${RESPONSE_RATE} seconds"

SEND_RESPONSE=0

fi

fi

}

if [ -f "${RESPONSES_DIR}/${RECIPIENT}" ]; then

rate_log_check

#If SEND_RESPONSE still equals "1" after the rate_log_check function, send an autoresponse.

if [ "${SEND_RESPONSE}" = "1" ] && [ "${RECIPIENT}" != "${SENDER}" ]; then

(cat "${RESPONSES_DIR}/${RECIPIENT}") | sed -e "0,/^$/ { s/^To:.*/To: <${SENDER}>/ }" -e '0,/^$/ { /^Date:/ d }' | ${SENDMAIL} -i -f "${RECIPIENT}" "${SENDER}"

mkdir -p "${RATE_LOG_DIR}/${RECIPIENT}"

touch "${RATE_LOG_DIR}/${RECIPIENT}/${SENDER}"

${LOGGER} -i -t autoresponse -p mail.notice "Autoresponse sent from ${RECIPIENT} to ${SENDER}"

fi

fi

exec ${SENDMAIL} -i -f "${SENDER}" "${RECIPIENT}"

fi

#Check to see if we are editing or creating a new autoresponse for a user.

#This should only be used from the command line unlike -D, -d, and -E which

#could be used via postfix pipe or in other areas where no user interaction

#is required.

if [ "${AUTORESPONSE_MESSAGE}" != "unset" ] && [ "${MODE}" = "1" ]; then

#Check to see if an autoresponse message exists for the email address specified by the "AUTORESPONSE_MESSAGE" parameter, if one exists

#then edit the existing one, if one does not exist, create a new one. This action will ignore any disabled autoresponse messages.

if [ -f "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}" ]; then

vi "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}"

elif ! [ -f "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}" ]; then

vi "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}"

if [ -f "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}" ]; then

#Insert our mail headers; people who will be setting autoresponses from the command line

#hopefully will know better than to screw with these when editing an existing autoresponse.

sed -i "1i\From: ${AUTORESPONSE_MESSAGE}\nTo: THIS GETS REPLACED\nSubject: Out Of Office\n\n" "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}"

fi

fi

if [ -f "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}" ]; then

chown autoresponse.autoresponse "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}"

chmod 600 "${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE}"

else

echo "Editing ${RESPONSES_DIR}/${AUTORESPONSE_MESSAGE} aborted!"

exit 1

fi

#Are we disabling an existing autoresponse message?

elif [ "${DISABLE_AUTORESPONSE}" != "unset" ] && [ "${MODE}" = "1" ]; then

if [ -f "${RESPONSES_DIR}/${DISABLE_AUTORESPONSE}" ]; then

mv -i "${RESPONSES_DIR}/${DISABLE_AUTORESPONSE}" "${RESPONSES_DIR}/${DISABLE_AUTORESPONSE}_DISABLED"

elif ! [ -f "${RESPONSES_DIR}/${DISABLE_AUTORESPONSE}" ]; then

echo "${RESPONSES_DIR}/${DISABLE_AUTORESPONSE} does not exist thus, it cannot be disabled!"

exit 1

fi

#Are we enabling an existing autoresponse message?

elif [ "${ENABLE_AUTORESPONSE}" != "unset" ] && [ "${MODE}" = "1" ]; then

if [ -f "${RESPONSES_DIR}/${ENABLE_AUTORESPONSE}_DISABLED" ]; then

mv -i "${RESPONSES_DIR}/${ENABLE_AUTORESPONSE}_DISABLED" "${RESPONSES_DIR}/${ENABLE_AUTORESPONSE}"

elif ! [ -f "${RESPONSES_DIR}/${ENABLE_AUTORESPONSE}_DISABLED" ]; then

echo "There is no disabled autoresponse for ${ENABLE_AUTORESPONSE}"

exit 1

fi

#Are we deleting an existing autoresponse message (this does not delete disabled autoresponse messages)?

elif [ "${DELETE_AUTORESPONSE}" != "unset" ] && [ "${MODE}" = "1" ]; then

if [ -f "${RESPONSES_DIR}/${DELETE_AUTORESPONSE}" ]; then

rm "${RESPONSES_DIR}/${DELETE_AUTORESPONSE}"

elif ! [ -f "${RESPONSES_DIR}/${DELETE_AUTORESPONSE}" ]; then

echo "${RESPONSES_DIR}/${DELETE_AUTORESPONSE} does not exist thus, it cannot be deleted!"

exit 1

fi

fi

#===КОНЕЦ ФАЙЛА===

useradd -d /var/spool/autoresponse -s `which nologin` autoresponse

mkdir -p /var/spool/autoresponse/log /var/spool/autoresponse/responses

cp ~/autoresponse /usr/local/sbin/

chown -R autoresponse.autoresponse /var/spool/autoresponse

chmod -R 0770 /var/spool/autoresponse

nano /etc/postfix/master.cf

найдем строку

smtp inet n - - - - smtpd

сразу после нее вставим

-o content_filter=autoresponder:dummy

В конце файла вставляем

autoresponder unix - n n - - pipe

flags=Fq user=autoresponse argv=/usr/local/sbin/autoresponse -s ${sender} -r ${recipient} -S ${sasl_username} -C ${client_address}

postconf -e 'autoresponder_destination_recipient_limit = 1'

postconf -e 'recipient_delimiter = - '

/etc/init.d/postfix restart

Теперь для того, чтобы при Вашем отсутствии на работе (например, отпуск) всем, кто послал Вам письмо, автоматически отправлялось сообщение о Вашем отсутствии, нужно послать по адресу <ваш логин>-autoresponse@trest91.ru то письмо, которое Вы хотите установить в качестве автоответчика, например admin-autoresponse@trest91.ru (здесь и далее замените trest91.ru на Ваш домен).

Если все прошло нормально, Вы получите ответ с темой «Out Of Office» следующего содержания: «Autoresponse enabled for admin@trest91.ru by SASL authenticated user: admin@trest91.ru from: x.x.x.x», где x.x.x.x - IP-адрес хоста, с которого было отправлено письмо.

Теперь при посылке Вам письма все автоматически в ответ будут получать то письмо, которое вы установили в качестве автоответчика, сами письма будут сохраняться у Вас в папке «Входящие» как обычно.

Для того, чтобы убрать сообщение автоответчка, пошлите еще раз любое письмо на адрес <ваш логин>-autoresponse@trest91.ru и Вы получите в ответ письмо с темой «Out Of Office» следующего содержания: «Autoresponse disabled for admin@trest91.ru by SASL authenticated user: admin@trest91.ru from: x.x.x.x», где x.x.x.x - IP-адрес хоста, с которого было отправлено письмо.

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

Письма для включения/выключения автоответчика должны быть посланы с Вашего адреса, иначе они не «сработают».

Установка munin

apt-get install munin-node munin logtail

nano /etc/apache2/conf.d/munin

поменяем (если необходимо) строку

# Allow from localhost 127.0.0.0/8 ::1

на

Allow from all

/etc/init.d/apache2 restart

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

nano /usr/share/munin/plugins/amavis-debian

#!/bin/sh

#

# Plugin to monitor the amavis mail filter for Debian

# (based upon a plugin authored by Geoffroy Desvernay)

#

# This plugin is built and tested on Debian Etch using:

# munin 1.2.5-1

# amavisd-new 2.4.2-6.1

#

# With some minor modification it should also work on non-debian systems

# This, however, is up to you

#

# Munin graph will sum up: Passed CLEAN, Blocked VIRUS, Blocked SPAM, Other

#

# Parameters understood:

# config (required)

# autoconf (optional)

#

# Config variables:

# AMAVIS_LOG - file where amavis logs are written

# STATEFILE - file which is needed to keep track of AMAVIS_LOG

# LOGTAIL - location of logtail

# BC - location of bc

#

# Enjoy!

# Fili Wiese

#

AMAVIS_LOG=${logfile:-/var/log/mail.log}

STATEFILE=/var/lib/munin/plugin-state/amavis.offset

LOGTAIL=${logtail:-`which logtail`}

BC=${bc:-`which bc`}

mktempfile () {

mktemp

}

if [ "$1" = "autoconf" ]; then

if [ -f "${AMAVIS_LOG}" -a -n "${LOGTAIL}" -a -x "${LOGTAIL}" -a -n "${BC}" -a -x "${BC}" ] ; then

echo yes

exit 0

else

echo no

exit 1

fi

fi

if [ "$1" = "config" ]; then

echo 'graph_title Amavis filter statistics'

echo 'graph_category postfix'

# echo 'graph_order total clean spam virus other'

echo 'graph_order sent clean spammy header spam virus'

echo 'graph_vlabel Mails filtered'

echo 'graph_scale no'

# echo 'total.label Total'

# echo 'total.draw AREA'

# echo 'total.colour DDDDDD'

echo 'sent.label Sent BYPASS'

echo 'sent.draw LINE1'

echo 'sent.colour 0099FF'

echo 'clean.label Passed CLEAN'

echo 'clean.draw LINE1'

echo 'clean.colour 32FA00'

echo 'spammy.label Passed SPAMMY'

echo 'spammy.draw LINE1'

echo 'spammy.colour FFCC00'

echo 'header.label Passed BAD-HEADER'

echo 'header.draw LINE1'

echo 'header.colour 99CC00'

echo 'spam.label Detected SPAM'

echo 'spam.draw LINE1'

echo 'spam.colour FF0000'

echo 'virus.label Blocked VIRUS'

echo 'virus.draw LINE1'

echo 'virus.colour 880088'

# echo 'other.label Other'

# echo 'other.draw LINE1'

# echo 'other.colour 0099FF'

exit 0

fi

sent=0

clean=0

virus=0

spam=0

spammy=0

header=0

other=0

total=0

ARGS=0

`$LOGTAIL /etc/hosts 2>/dev/null >/dev/null`

if [ $? = 66 ]; then

if [ ! -n "$logtail" ]; then

ARGS=1

fi

fi

TEMP_FILE=`mktempfile munin-amavis.XXXXXX`

if [ -n "$TEMP_FILE" -a -f "$TEMP_FILE" ]

then

if [ $ARGS != 0 ]; then

$LOGTAIL ${AMAVIS_LOG} $STATEFILE | grep 'amavis\[.*\]:' | grep -v 'TIMED OUT' > ${TEMP_FILE}

else

$LOGTAIL ${AMAVIS_LOG} $STATEFILE | grep 'amavis\[.*\]:' | grep -v 'TIMED OUT' > ${TEMP_FILE}

fi

# total=`cat ${TEMP_FILE} | wc -l`

sent=`grep 'Passed CLEAN, MYUSERS' ${TEMP_FILE} | wc -l`

clean=`grep 'Passed CLEAN,' ${TEMP_FILE} | wc -l`

clean=`echo ${clean}-${sent} | ${BC}`

spammy=`grep 'Passed SPAMMY,' ${TEMP_FILE} | wc -l`

header=`grep 'Passed BAD-HEADER' ${TEMP_FILE} | wc -l`

spam=`grep 'Blocked SPAM,' ${TEMP_FILE} | wc -l`

virus=`grep 'INFECTED' ${TEMP_FILE} | wc -l`

# other=`echo ${total}-${clean}-${virus}-${other}-${spam} | ${BC}`

/bin/rm -f $TEMP_FILE

fi

echo "sent.value ${sent}"

echo "clean.value ${clean}"

echo "spammy.value ${spammy}"

echo "header.value ${header}"

echo "spam.value ${spam}"

echo "virus.value ${virus}"

#echo "other.value ${other}"

#echo "total.value ${total}"

nano /usr/share/munin/plugins/amavis_

#!/usr/bin/perl -w

#

# Plugin to monitor amavisd-new statistics. Values are retrieved by querying

# the BerkeleyDB database 'snmp.db', in which amavisd-new stores its

# statistics.

#

# The plugin requires the Perl module BerkeleyDB.

#

# To use, setup /etc/munin/plugin-conf.d/amavis e.g. as follows:

#

# [amavis_*]

# env.amavis_db_home /var/lib/amavis/db

# user amavis

#

# Where env.amavis_db_home is the path to the amavisd-new BerkeleyDB files

# (/var/amavis/db by default).

#

# Then create symlinks in the Munin plugin directory named "amavis_time",

# "amavis_cache" and "amavis_content", or use munin-node-configure.

#

# Parameters:

#

# config

# autoconf

# suggest

#

# Config variables:

#

# amavis_db_home - where the amavisd-new berkeley db files are located

#

# Magic markers

#%# family=auto

#%# capabilities=autoconf

#%# capabilities=suggest

use strict;

no warnings 'uninitialized';

use BerkeleyDB;

my($dbfile) = 'snmp.db';

my($db_home) = # DB databases directory

defined $ENV{'amavis_db_home'} ? $ENV{'amavis_db_home'} : '/var/amavis/db';

if ($ARGV[0] and $ARGV[0] eq "autoconf") {

if (-x "/usr/sbin/amavisd-agent") {

print "yes\n";

exit 0;

} else {

print "no (/usr/sbin/amavisd-agent not found or not executable)\n";

exit 1;

}

} elsif ($ARGV[0] and $ARGV[0] eq "suggest") {

print "time\n";

print "cache\n";

print "content\n";

exit 0;

}

my $stats_type = "";

if ($0 =~ /^(?:|.*\/)amavis_(cache|content|time)$/) {

$stats_type = $1;

} else {

print "You need to create a symlink to this plugin called either amavis_cache, amavis_time or amavis_content to be able to use it.\n";

exit 2;

}

if ($ARGV[0] and $ARGV[0] eq "config") {

if ($stats_type eq "cache") {

print "graph_title Amavis cache hit / miss ratio\n";

print "graph_args --lower-limit 0 --upper-limit 100 --rigid\n";

print "graph_category mail\n";

print "graph_info The ratio of cache hits and misses for AMaViSd-new.\n";

print "graph_order hits misses\n";

print "graph_scale no\n";

print "graph_vlabel %\n";

print "hits.label Cache hits\n";

print "hits.draw AREA\n";

print "hits.max 100\n";

print "hits.min 0\n";

print "misses.label Cache misses\n";

print "misses.draw STACK\n";

print "misses.max 100\n";

print "misses.min 0\n";

} elsif ($stats_type eq "content") {

print "graph_title Amavis scanned mails\n";

print "graph_category mail\n";

print "graph_period minute\n";

print "graph_vlabel msgs / \${graph_period}\n";

foreach my $type (qw(total clean spam spammy virus)) {

print "$type.label " . ucfirst($type) . " mails \n";

print "$type.type DERIVE\n";

print "$type.min 0\n";

}

print "clean.info Legitimate mail.\n";

print "spammy.info Mails with a spam score above the tag2 level.\n";

print "spam.info Mails with a spam score above the kill level for spam.\n";

print "virus.info Mails with a virus.\n";

print "total.info Total number of scanned mails.\n";

} elsif ($stats_type eq "time") {

print "graph_title Amavis average scan time\n";

print "graph_info Average time spent in each phase of the mail scanning process, per mail.\n";

print "graph_category mail\n";

print "graph_vlabel sec / mail\n";

print "graph_scale no\n";

print "msgs.label Total number of messages\n";

print "msgs.graph no\n";

print "msgs.type DERIVE\n";

print "msgs.min 0\n";

foreach my $type (qw(decoding receiving sending spamcheck viruscheck total)) {

print "${type}.label " . ucfirst($type) . "\n";

print "${type}.type DERIVE\n";

print "${type}.min 0\n";

print "${type}.cdef ${type},1000,/,msgs,/\n";

}

}

exit 0;

}

my ($env, $db, @dbstat, $cursor);

@dbstat = stat("$db_home/$dbfile");

my $errn = @dbstat ? 0 : 0+$!;

$errn == 0 or die "stat $db_home/$dbfile: $!";

$env = BerkeleyDB::Env->new(

-Home => $db_home,

-Flags => DB_INIT_CDB | DB_INIT_MPOOL,

-ErrFile => \*STDOUT,

-Verbose => 1,

);

defined $env or die "BDB no env: $BerkeleyDB::Error $!";

$db = BerkeleyDB::Hash->new(-Filename => $dbfile, -Env => $env);

defined $db or die "BDB no db: $BerkeleyDB::Error $!";

my %values = ();

my ($eval_stat, $stat, $key, $val);

$cursor = $db->db_cursor; # obtain read lock

defined $cursor or die "db_cursor error: $BerkeleyDB::Error";

while (($stat = $cursor->c_get($key, $val, DB_NEXT)) == 0) {

$values{$key} = $val;

}

$stat == DB_NOTFOUND or die "c_get: $BerkeleyDB::Error $!";

$cursor->c_close == 0 or die "c_close error: $BerkeleyDB::Error";

$cursor = undef;

$eval_stat = $@;

if ($eval_stat ne '') { chomp($eval_stat); die "BDB $eval_stat\n"; }

for my $k (sort keys %values) {

if ($values{$k} =~ /^(?:C32|C64) (.*)\z/) {

$values{$k} = $1;

}

}

if ($stats_type eq "cache") {

my $hits = $values{'CacheHits'};

my $misses = $values{'CacheMisses'};

my $misses_ratio = $misses * 100.00 / ($hits + $misses);

my $hits_ratio = $hits * 100.00 / ($hits + $misses);

printf("hits.value %.1f\n", $hits_ratio);

printf("misses.value %.1f\n", $misses_ratio);

} elsif ($stats_type eq "content") {

printf("total.value %d\n", $values{'InMsgs'});

my $clean = $values{'ContentCleanMsgs'};

if (defined($values{'ContentCleanTagMsgs'})) {

$clean += $values{'ContentCleanTagMsgs'};

}

printf("clean.value %d\n", $clean);

printf("spam.value %d\n", $values{'ContentSpamMsgs'});

printf("spammy.value %d\n", $values{'ContentSpammyMsgs'});

printf("virus.value %d\n", $values{'ContentVirusMsgs'});

} elsif ($stats_type eq "time") {

printf("decoding.value %d\n", $values{'TimeElapsedDecoding'});

printf("receiving.value %d\n", $values{'TimeElapsedReceiving'});

printf("sending.value %d\n", $values{'TimeElapsedSending'});

printf("spamcheck.value %d\n", $values{'TimeElapsedSpamCheck'});

printf("viruscheck.value %d\n", $values{'TimeElapsedVirusCheck'});

printf("total.value %d\n", $values{'TimeElapsedTotal'});

printf("msgs.value %d\n", $values{'InMsgs'});

}

$db->db_close == 0 or die "BDB db_close error: $BerkeleyDB::Error $!";

nano /usr/share/munin/plugins/postgrey

#!/bin/bash

#

# Plugin to monitor incoming Postgrey

#

# Parameters understood:

#

# config (required)

# autoconf (optional)

#

mktempfile () {

mktemp -t

}

MAIL_LOG=${logfile:-/var/log/mail.log}

STATEFILE=/var/lib/munin/plugin-state/postgrey.offset

LOGTAIL=${logtail:-`which logtail`}

if [ "$1" = "autoconf" ]; then

if [ -f "${MAIL_LOG}" -a -n "${LOGTAIL}" -a -x "${LOGTAIL}" ] ; then

echo yes

exit 0

else

echo no

exit 1

fi

fi

if [ "$1" = "config" ]; then

echo 'graph_title Postgrey daily filtering'

echo 'graph_order delayed passed whitelisted'

echo 'graph_category mail'

echo 'graph_vlabel Count'

echo 'graph_scale no'

## echo 'graph_args --base 1000 -l 0'

echo 'delayed.label delayed'

# echo 'delayed.type DERIVE'

echo 'passed.label passed'

# echo 'passed.type DERIVE'

echo 'whitelisted.label whitelisted'

# echo 'whitelisted.type DERIVE'

exit 0

fi

delayed=0

passed=0

whitelisted=0

ARGS=0

`$LOGTAIL /etc/hosts 2>/dev/null >/dev/null`

if [ $? = 66 ]; then

if [ ! -n "$logtail" ]; then

ARGS=1

fi

fi

TEMP_FILE=`mktempfile munin-postgrey.XXXXXX`

if [ -n "$TEMP_FILE" -a -f "$TEMP_FILE" ]

then

if [ $ARGS != 0 ]; then

$LOGTAIL ${MAIL_LOG} $STATEFILE | grep 'post[fix|grey]' > ${TEMP_FILE}

else

$LOGTAIL ${MAIL_LOG} $STATEFILE | grep 'post[fix|grey]' > ${TEMP_FILE}

fi

delayed=`grep 'Recipient address rejected.*Greylisted' ${TEMP_FILE} | wc -l`

# passed=`grep 'postgrey\[[0-9]*\]: delayed [0-9]* seconds:' ${TEMP_FILE} | wc -l`

passed=`grep 'postgrey\[[0-9]*\]: action=pass' ${TEMP_FILE} | wc -l`

whitelisted=`grep 'postgrey\[[0-9]*\]: whitelisted:' ${TEMP_FILE} | wc -l`

/bin/rm -f $TEMP_FILE

fi

echo "delayed.value ${delayed}"

echo "passed.value ${passed}"

echo "whitelisted.value ${whitelisted}"

nano /usr/share/munin/plugins/postfix_filtered_awk

#!/bin/bash

#

# Plugin to monitor incoming Postfix mail.

#

# Parameters understood:

#

# config (required)

# autoconf (optional)

#

# requires logtail

# If you are using a postfix policy daemon (such as policyd) to track certain block conditions, place a line

# in your /etc/munin/plugin-conf.d/munin-node like:

#

# [postfix_filtered]

# env.policy my policy string

#

# When env.policy is set, this plugin will match the string you supply as env.policy and return the number of instances

# of that string as an output called "policy.value".

#

# If you are NOT using a postfix policy daemon, as above, use the line

#

# [postfix_filtered]

# env.policy none

#

# and this plugin will suppress output of policy.value

POLICY=''

[ "${policy}" = 'none' ] || POLICY="${policy}"

export POLICY

#LOGDIR=${logdir:-/var/log/mail}

#MAIL_LOG=$LOGDIR/${logfile:-info}

MAIL_LOG=/var/log/mail.info

LOGTAIL=${logtail:-`which logtail`}

STATEFILE=/var/lib/munin/plugin-state/postfix_mailfiltered_test.offset

if [ "$1" = "autoconf" ]; then

if [ -f "${MAIL_LOG}" -a -n "${LOGTAIL}" -a -x "${LOGTAIL}" ] ; then

echo yes

exit 0

else

echo no

exit 1

fi

fi

if [ "$1" = "config" ]; then

echo 'graph_title Postfix message filtering'

echo 'graph_category mail'

echo 'graph_vlabel Mails per second'

# echo 'graph_args --base 1000 --logarithmic'

echo 'graph_args --base 1000 -l 0'

if [ -z "$POLICY" ]

then

echo 'graph_order rbl helo client sender recipient relay allowed'

else

echo 'graph_order rbl policy helo client sender recipient relay allowed'

echo 'policy.label policy blocked'

echo 'policy.min 0'

echo 'policy.draw LINE1'

echo 'policy.type ABSOLUTE'

fi

echo 'allowed.draw LINE2'

echo 'allowed.type ABSOLUTE'

echo 'allowed.colour 00ff00'

echo 'rbl.draw LINE2'

echo 'rbl.type ABSOLUTE'

echo 'rbl.colour 1010ff'

for i in helo client sender recipient relay;

do

echo "$i.min 0"

echo "$i.type ABSOLUTE"

echo "$i.draw LINE1";

done

echo 'allowed.label allowed'

echo 'rbl.label RBL blocked'

echo 'helo.label HELO rejected'

echo 'client.label Client rejected'

echo 'sender.label Sender rejected'

echo 'recipient.label recipient unknown'

echo 'relay.label relay denied'

exit 0

fi

$LOGTAIL ${MAIL_LOG} $STATEFILE | \

awk 'BEGIN { na= 0; nb= 0; nc= 0; nd= 0; ne= 0; nf= 0; ng= 0; nh= 0 ; st= ENVIRON["POLICY"] }

{

if (index($0, "queued as")) { na++ }

else if (index($0, "Relay access denied")) { nb++ }

else if (index($0, "blocked using")) { nc++ }

else if (index($0, "Helo command rejected")) { nd++ }

else if (index($0, "Client host rejected")) { ne++ }

else if (index($0, "Sender address rejected")) { nf++ }

else if (index($0, "Recipient address rejected")) { ng++ }

else if (st && index($0, st)) { nh++ }

}

END { print "allowed.value " na"\nrelay.value " nb"\nrbl.value " nc"\nhelo.value " nd"\nclient.value " ne"\nsender.value " nf"\nrecipient.value " ng ; if (st) print "policy.value " nh }'

cd /usr/share/munin/plugins

chmod a+x amavis_ amavis-debian postgrey postfix_filtered_awk

cd ~

ln -s /usr/share/munin/plugins/amavis_ /etc/munin/plugins/amavis_cache

ln -s /usr/share/munin/plugins/amavis_ /etc/munin/plugins/amavis_content

ln -s /usr/share/munin/plugins/amavis_ /etc/munin/plugins/amavis_time

ln -s /usr/share/munin/plugins/amavis-debian /etc/munin/plugins/amavis-debian

ln -s /usr/share/munin/plugins/postgrey /etc/munin/plugins/postgrey

ln -s /usr/share/munin/plugins/postfix_mailstats /etc/munin/plugins/postfix_mailstats

ln -s /usr/share/munin/plugins/postfix_filtered_awk /etc/munin/plugins/postfix_filtered_awk

ln -s /usr/share/munin/plugins/fail2ban /etc/munin/plugins/fail2ban

nano /etc/munin/plugin-conf.d/munin-node

вставим в него строки

[amavis-debian]

user root

group adm

[postgrey]

group adm

[amavis_*]

env.amavis_db_home /var/lib/amavis/db

user amavis

[postfix_mailstats]

group adm

[postfix_filtered_awk]

group adm

[fail2ban]

user root

service munin-node restart

и через 5-10 минут получим графики. Они обновляются раз в пять минут.

Заключение

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

Так же я бы порекомендовал ознакомится со списком приложений, находящихся внизу по данному адресу: http://help.ubuntu.ru/wiki/почтовый_сервер_со_всем_фаршем_на_10.04_lts

SQUID

apt-get install squid

nano /etc/squid/squid.conf

http_port 3128 transparent

Находим следующий блок:

#acl localnet src 10.0.0.0/24 # RFC1918 possible internal network

#acl localnet src 172.16.0.0/12 # RFC1918 possible internal network

#acl localnet src 192.168.0.0/16 # RFC1918 possible internal network

Для повышения безопасности сервер будет обслуживать запросы только из локальной сети, IP адреса в моей локальной сети из диапазона 192.168.1.0/24,

Где: 192.168.1.0-подсеть, /24-количество бит в маске-идентификаторе сети (255.255.255.0)

#acl localnet src 10.0.0.0/24 # RFC1918 possible internal network

#acl localnet src 172.16.0.0/12 # RFC1918 possible internal network

acl localnet src 192.168.1.0/24 # RFC1918 possible internal network

Разрешаем доступ из localnet:

http_access allow localnet

Находим и раскоментируем, правило кеширования

cache_dir ufs /var/spool/squid 4096 32 256

Если на сервер не много оперативной памяти-1Gb то имеет смысл установить лимит ее использования, нашим сервером. Нам необходимо найти и раскоментировать:

memory_pools on

memory_pools_limit 50 MB

Для уведомления пользователей об ошибках можно установить страницу ошибок на русском задается она в параметре error_directory и установить кодировку Windows-1251, для желающих можно зайти в директроию /usr/share/squid/errors/ и там посмотреть список папок.

error_directory /usr/share/squid/errors/Russian-1251

Нам необходимо перестроить кеш который хранится в /usr/sbin/squid

/usr/sbin/squid -z

/etc/init.d/squid start

nano /etc/rc.local

iptables -t nat -A PREROUTING -i lo -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.180:3128

iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128

iptables -t nat -A PREROUTING -i lo -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.180:3128

iptables -t nat -A PREROUTING -i eth1 -p tcp -m tcp --dport 8080 -j REDIRECT --to-ports 3128

reboot

IPtables

Приведу скрипт к Iptables

#!/bin/sh

echo "0" > /proc/sys/net/ipv4/ip_forward

echo "1" > /proc/sys/net/ipv4/tcp_syncookies

echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

#необходим для корректной работы FTP-сервера

/sbin/modprobe ip_conntrack_ftp

#Сбрасываем старые данные и правила

/sbin/iptables -F

/sbin/iptables -F -t nat

/sbin/iptables -F -t mangle

/sbin/iptables -X

/sbin/iptables -X -t nat

/sbin/iptables -X -t mangle

echo Old Rules Flushed

#Устанавливаем правила на DROP по-умолчанию. (Set Default-Drop Policy)

/sbin/iptables -P INPUT DROP

/sbin/iptables -P OUTPUT DROP

#Create New Chain Called BAD_PACKETS

/sbin/iptables -N BAD_PACKETS

#Разрешаем работу локального интерфейса, того самого 127.0.0.1 (Allow The Loopback)

/sbin/iptables -A INPUT -i lo -j ACCEPT

#Jump To BAD_PACKETS

/sbin/iptables -A INPUT -j BAD_PACKETS

#Разрешаем поддерживать открытыми уже установленные соединения (Allow Established Connections)

/sbin/iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Разрешаем получать данные от DHCP-сервера. (Allow DHCP)

/sbin/iptables -A INPUT -p UDP --dport 68 --sport 67 -j ACCEPT

#Разрешаем присоединяться к SSH, при условии, что используется стандартный 22 порт (Allow SSH)

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 22 -j ACCEPT

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 22 -j ACCEPT

#Разрешаем сетевую печать на этом компьютере. (Allow net print)

/sbin/iptables -A INPUT -p UDP -i eth0 --dport 631 -j ACCEPT

#Разрешаем webmin на стандартном 10000 порту (Allow webmin)

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 10000 -j ACCEPT

#Allow avahi-daemon

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 5353 -j ACCEPT

#Allow input skype

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 13308 -j ACCEPT

#Allow input torrents-client

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 51413 -j ACCEPT

/sbin/iptables -A INPUT -p UDP -i eth0 --dport 51413 -j ACCEPT

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 6881 -j ACCEPT

/sbin/iptables -A INPUT -p UDP -i eth0 --dport 6881 -j ACCEPT

#Allow Samba From Specified Hosts

/sbin/iptables -A INPUT -p TCP -i eth0 --dport 137:139 -j ACCEPT

/sbin/iptables -A INPUT -p UDP -i eth0 --dport 137:139 -j ACCEPT

/sbin/iptables -A INPUT -p TCP -i eth0 --sport 137:139 -j ACCEPT

/sbin/iptables -A INPUT -p UDP -i eth0 --sport 137:139 -j ACCEPT

#Allow ICMP Replies From Specified Hosts (Ping)

/sbin/iptables -A INPUT -p ICMP -i eth0 --icmp-type 8 -j ACCEPT

/sbin/iptables -A INPUT -p ICMP -i eth0 --icmp-type 8 -j ACCEPT

#Разрешаем подключаться к SMTP на 587 порт, как это настроить указано тут. (Allow input mail on 587 port)

/sbin/iptables -A INPUT -p tcp --dport 587 -j ACCEPT

#Log

/sbin/iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "

#Accept Loopback On OUTPUT

/sbin/iptables -A OUTPUT -o lo -j ACCEPT

#Разрешаем поддерживать открытыми уже установленные соединения. (Allow Established Connections)

/sbin/iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

#Разрешить получать IP по DHCP (Allow DHCP)

/sbin/iptables -A OUTPUT -p UDP --dport 67 --sport 68 -j ACCEPT

#Allow HTTP,FTP,DNS,SSH, SMTP & Port 443 Outbound

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 443 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 80 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 53 -j ACCEPT

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 53 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 25 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 22 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 21 -j ACCEPT

#Allow output skype

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 13308 -j ACCEPT

/sbin/iptables -A OUTPUT -p UDP -o eth0 --sport 13308 -j ACCEPT

#Allow pop, imap

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 110 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 143 -j ACCEPT

#Allow IMAPS

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 993 -j ACCEPT

#Allow output icq

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 5190 -j ACCEPT

#Разрешить выход на IRC. (Allow output IRC)

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 6667 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 6668 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 6669 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 8001 -j ACCEPT

#Allow output Google talk

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 5222 -j ACCEPT

#Allow output CUPS (for printers in net)

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 631 -j ACCEPT

#Allow output avahi-daemon

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 5353 -j ACCEPT

#Allow output teamviewer

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 5938 -j ACCEPT

#Allow output ntp (for ntpdate)

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 123 -j ACCEPT

#Allow output Urban Terror

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 27960 -j ACCEPT

#Allow specify ports

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 2046 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 2050 -j ACCEPT

#Allow Samba From Specified Hosts

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 137:139 -j ACCEPT

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 137:139 -j ACCEPT

/sbin/iptables -A OUTPUT -p TCP -o eth0 --dport 445 -j ACCEPT

/sbin/iptables -A OUTPUT -p UDP -o eth0 --dport 445 -j ACCEPT

#Allow ICMP Replies (Ping)

/sbin/iptables -A OUTPUT -p ICMP -o eth0 --icmp-type 8 -j ACCEPT

#Drop

/sbin/iptables -A OUTPUT -j LOG --log-prefix "OUTPUT DROP: "

/sbin/iptables -A BAD_PACKETS -p TCP ! --syn -m state --state NEW -j DROP

/sbin/iptables -A BAD_PACKETS -p TCP --tcp-flags ALL ALL -j DROP

/sbin/iptables -A BAD_PACKETS -p TCP --tcp-flags ALL NONE -j DROP

/sbin/iptables -A BAD_PACKETS -p TCP --tcp-flags ALL SYN \-m state --state ESTABLISHED -j DROP

/sbin/iptables -A BAD_PACKETS -p ICMP --fragment -j DROP

/sbin/iptables -A BAD_PACKETS -m state --state INVALID -j DROP

/sbin/iptables -A BAD_PACKETS -d 255.255.255.255 -j DROP

/sbin/iptables -A BAD_PACKETS -j RETURN

echo "Rules written."