Postfix + Dovecot + Postfixadmin + Roundcube + DKIM

Настройка системы:

# cat /etc/hosts
127.0.0.1 localhost localhost.tst-amo.net.ua localhost4 localhost4.tst-amo.net.ua
::1 localhost localhost.tst-amo.net.ua localhost6 localhost6.tst-amo.net.ua

192.168.1.41 mail mail.tst-amo.net.ua
192.168.1.41 mail.tst-amo.net.ua.
# cat /etc/aliases

# Basic system aliases -- these MUST be present.
mailer-daemon: postmaster
postmaster: root
root: pm@tst-amo.net.ua # учетка на которую будет пересылаться почта root

# General redirections for pseudo accounts.
bin: root
daemon: root
# hostname
tst.tst-amo.net.ua

Очень желателен PTR (прописывается у провайдера по заявке, у моего нельзя)

Например:

# nslookup 222.444.22.63
Server: 192.168.1.41
Address: 192.168.1.41#53

Non-authoritative answer:
222.444.22.63.in-addr.arpa name = mail.domen.ua.

Предполагается, что уже установлены и настроены MySQL, nginx.

1. MySQL

Создаем базу данных:

# mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE postfix;
Query OK, 1 row affected (0.03 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'mypassword';
Query OK, 0 rows affected (0.10 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> quit

2. Postfixadmin

# wget -q -O - "https://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-3.2/postfixadmin-3.2.tar.gz" | tar -xzf - -C /home/www/
# yum install php56w-imap
# chown -R nginx:www-data /home/www/postfixadmin

– где nginx:www-data – пользователь под которым запускается nginx и группа

После обновления сменился владелец /var/lib/php/session и выдало ошибку в браузере

Invalid token

в логах ругань на permission, так как, владельцем стал root:apache:

2018/08/18 08:55:06 [error] 1786#0: *9149 FastCGI sent in stderr: "PHP message: PHP Warning: session_start(): open(/var/lib/php/session/sess_7p6c8kjkosj36d0lehjjr4eeg
6, O_RDWR) failed: Permission denied (13) in /home/www/postfixadmin/common.php on line 26
PHP message: PHP Warning: session_start(): open(/var/lib/php/session/sess_7p6c8kjkosj36d0lehjjr4eeg6, O_RDWR) failed: Permission denied (13) in /home/www/postfixadmin
/public/login.php on line 84" while reading response header from upstream, client: 192.168.1.1, server: tst-amo.net.ua, request: "GET /postfixadmin/public/login.php HT
TP/2.0", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "tst-amo.net.ua"
2018/08/18 08:55:06 [error] 1786#0: *9149 FastCGI sent in stderr: "PHP message: PHP Warning: Unknown: open(/var/lib/php/session/sess_7p6c8kjkosj36d0lehjjr4eeg6, O_RDW
R) failed: Permission denied (13) in Unknown on line 0

Лечим:

# chown -R nginx:www-data /var/lib/php/session

У меня выдавало ошибку на отсутствие директории templates_c:

# mkdir postfixadmin/templates_c
# chown nginx:www-data templates_c

Заходить в сетап:

https://tst-amo.net.ua/postfixadmin/public/setup.php

добавить

$CONF['setup_password'] = '422962da717c2abb5408efe.......b2fa22dd9f7d1bc01835c9e59a';

После настройки заходим и создаем домен, ящики и т.д.

https://tst-amo.net.ua/postfixadmin/public/login.php

3. Postfix – виртуальные пользователи

Создаем сначала групу vmail с идентификатором 1024:

# groupadd -g 1024 vmail

а потом добавляем туда пользователя:

# useradd -d /home/vmail -g 1024 -u 1024 vmail -m

Добавить в /etc/postfix/main.cf

 ........
 virtual_mailbox_base = /home/vmail
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
 virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
 virtual_minimum_uid = 1024
 virtual_uid_maps = static:1024
 virtual_gid_maps = static:1024

# Транспорт
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

…..

smtpd_recipient_restrictions =
    check_client_access hash:/etc/postfix/blacklist-IP
    permit_mynetworks
    permit_sasl_authenticated
    check_recipient_access hash:/etc/postfix/recipient-list
    reject_non_fqdn_recipient
    reject_unauth_destination
    reject_unknown_recipient_domain
    reject_unverified_recipient
    permit

Здесь правило reject_unauth_destination – должно запрещать открытый релей через ваш сервер

Содержимое служебных файлов:

[root@tst postfix]# cat mysql_virtual_alias_maps.cf
user = postfix
password = mypassword
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
[root@tst postfix]# cat mysql_virtual_domains_maps.cf
user = postfix
password = mypassword
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%u'
[root@tst postfix]# cat mysql_virtual_mailbox_maps.cf
user = postfix
password = mypassword
hosts = localhost
dbname = postfix
query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'
[root@tst postfix]# cat access_sender
tst-amo.net.ua OnlyFromMyUsers
[root@tst postfix]# cat blacklist
#spam@net.ua REJECT
#info@uni.ka REJECT Your e-mail was banned!
#acc@tst1.pp.ua REJECT Your e-mail was banned!
#s@i.ua REJECT SPAM!!!
/.*@tst-amo\.net\.ua/i REJECT You are not imp.kiev.ua, this is my name!!!

advocatov.com REJECT SPAM!!!
bilabonges.eu REJECT SPAM!!!
cloudlite.eu REJECT SPAM!!!
deals@save.spirit-airlines.com REJECT SPAM!!!
domrike.eu REJECT SPAM!!!
saffiano-double.ru REJECT SPAM!!!
whilsacom.eu REJECT SPAM!!!
[root@tst postfix]# cat blacklist-IP
1.52.38.29 REJECT Your IP is spam
2.90.145.125 REJECT Your IP is spam
5.235.7.171 REJECT Your IP is spam
37.104.210.18 REJECT Your IP is spam
37.106.204.58 REJECT Your IP is spam
42.113.159.236 REJECT Your IP is spam
42.116.220.21 REJECT Your IP is spam
43.250.80.131 REJECT Your IP is spam
45.244.118.151 REJECT Your IP is spam
[root@tst postfix]# cat header_checks
# Для спама
/^X-Spam-Level:.*\*{12,}.*/ REDIRECT spam@uni.ka
# Для вложений
/^(.*)name=\"(.*)\.(exe|bat|cmd|mp3)\"$/ REJECT Attachment type not allowed. File "$2" has unacceptable extension: "$3"
[root@tst postfix]# cat hello_access
mail.tst-amo.net.ua REJECT Don't use my server name!!!
[root@tst postfix]# cat recipient-list
# For these users to receive all
/^postmaster\@/ OK
/^hostmaster\@/ OK
/^abuse\@/ OK
/^webmaster\@/ OK
## Users
#/^mfint\@/ OK
#/^metall\@/ OK
[root@tst postfix]# cat whitelist
#--------------- Nuzhno_IMP -----------------
.nas.gov OK
@nas.gov OK
.domen.kiev.ua OK
@domen.kiev.ua OK

#--------------- Cheff other
@mpiyt-shalle.4mpg.de OK
.mpiyt-shalle.4mpg.de OK

 

4. Amavisd-new, ClamAV

This will install amavisd-new and a bunch of dependencies, and clamav + freshclam. It will also install SpamAssassin by default.

# yum install amavisd-new clamav clamav-update freshclam

Edit amavisd.conf.

# vim /etc/amavisd/amavisd.conf

Change the following lines like this…

$mydomain = ‘domain.com’; # a convenient default for other settings
$myhostname = 'mail.domain.com’; # must be a fully-qualified domain name and same as reverse DNS lookup

Make sure everything is set in postfix’s configuration file master.cf

# vim /etc/postfix/master.cf

On top of master.cf, you should have something like…

smtp inet n - n - - smtpd
  -o smtpd_sasl_auth_enable=yes
  -o receive_override_options=no_address_mappings
  -o content_filter=smtp-amavis:127.0.0.1:10024
 …and on bottom, you should have something like…
#
 # spam/virus section
 #
 smtp-amavis unix - - n - 2 smtp
   -o smtp_data_done_timeout=1200
   -o disable_dns_lookups=yes
   -o smtp_send_xforward_command=yes
 127.0.0.1:10025 inet n - y - - smtpd
   -o content_filter=
   -o smtpd_helo_restrictions=
   -o smtpd_sender_restrictions=
   -o smtpd_recipient_restrictions=permit_mynetworks,reject
   -o mynetworks=127.0.0.0/8
   -o smtpd_error_sleep_time=0
   -o smtpd_soft_error_limit=1001
   -o smtpd_hard_error_limit=1000
   -o receive_override_options=no_header_body_checks
   -o smtpd_helo_required=no
   -o smtpd_client_restrictions=
   -o smtpd_restriction_classes=
   -o disable_vrfy_command=no
   -o strict_rfc821_envelopes=yes

Stop the postfix daemon.

# service postfix stop

Start Spamassassin, Amavisd-new and ClamAV daemons.

Проверка синтаксиса Spamassassin

Обновляем правила Spamassassin:

# sa-update --nogpg

Обновляем базы Spamassassin

# service spamassassin start
# service amavisd start 
# service postfix start

5. Postgrey

# yum install postgrey
smtpd_recipient_restrictions =
   check_client_access hash:/etc/postfix/blacklist-IP
   permit_mynetworks
   permit_sasl_authenticated
   check_recipient_access hash:/etc/postfix/recipient-list
   reject_non_fqdn_recipient
   reject_unauth_destination
 ## POSTGREY
   #check_policy_service unix:/var/spool/postfix/postgrey/socket
   check_policy_service inet:127.0.0.1:10023
 ##
   reject_unknown_recipient_domain
   reject_unverified_recipient
   permit

строчка “check_policy_service unix:/var/spool/postfix/postgrey/socket,” или “check_policy_service inet:127.0.0.1:10023” должна быть обязательно прописана после строчки параметра “reject_unauth_destination”, как на примере выше.

По ману запускать нужно так:

# man postgrey
# postgrey --inet=10023 -d

# systemctl reload postfix

6. OpenDKIM

# yum install -y opendkim

Генерируем ключ:

# opendkim-genkey -D /etc/opendkim/ --domain tst-amo.net.ua --selector relay
# cd /etc/opendkim
# chown :opendkim /etc/opendkim/*
# chmod g+r /etc/opendkim/*
# cp opendkim.conf opendkim.conf_orig
# cat opendkim.conf_orig | grep "^[^#]" > opendkim.conf

Правим opendkim.conf до состояния:

[root@tst etc]# cat opendkim.conf
AutoRestart Yes
AutoRestartRate 10/1h
Umask 002
Syslog yes
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:12301@localhost

Создаем служебные файлы:

# touch /etc/opendkim/TrustedHosts
# touch /etc/opendkim/KeyTable
# touch /etc/opendkim/SigningTable

Их содержимое:

# cat /etc/opendkim/KeyTable
 relay._domainkey.tst-amo.net.ua tst-amo.net.ua:relay:/etc/opendkim/relay.private
# cat /etc/opendkim/SigningTable
 *@tst-amo.net.ua relay._domainkey.tst-amo.net.ua
# cat /etc/opendkim/TrustedHosts
 127.0.0.1
 localhost
 *.tst-amo.net.ua
 #host.example.com
 #192.168.1.0/24

Запускаем сервис:

# systemctl start opendkim.service
# systemctl enable opendkim.service
# systemctl status opendkim.service

Добавляем в main.cf для Postfix

# nano /etc/postfix/main.cf
# DKIM
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:12301
non_smtpd_milters = $smtpd_milters

# service postfix reload

для BIND

# nano /var/named/chroot/var/named/tst-amo.net.ua.zone
 relay._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIGfMA0GCSqGSIb3DQEBAQUAA......k02pIg+TwIDAQAB" )
# service named-chroot reload
# service named-chroot status

Проверяем.

7 . Dovecot

# yum install dovecot dovecot-mysql dovecot-pigeonhole

Dovecot quota

# nano /etc/dovecot/conf.d/10-mail.conf
mail_plugins = $mail_plugins quota
# nano /etc/dovecot/conf.d/20-imap.conf
protocol imap {
   mail_plugins = $mail_plugins imap_quota
}
# nano /etc/dovecot/conf.d/10-master.conf
service dict {
    unix_listener dict {
       mode = 0660
       user = vmail
       group = vmail
    }
}
# nano /etc/dovecot/conf.d/90-quota.conf
plugin {
    quota = dict:User quota::proxy::quota
}
# nano /etc/dovecot/dovecot.conf
dict {
    quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
# nano /etc/dovecot/dovecot-dict-sql.conf.ext
connect = host=localhost dbname=postfix user=postfix password=mypassword
map {
    pattern = priv/quota/storage
    table = quota2
    username_field = username
    value_field = bytes
}
map {
    pattern = priv/quota/messages
    table = quota2
    username_field = username
    value_field = messages
}
map {
    pattern = shared/expire/$user/$mailbox
    table = expires
    value_field = expire_stamp
fields {
    username = $user
    mailbox = $mailbox
   }
}
# nano /etc/dovecot/dovecot-sql.conf.ext
# Database driver: mysql, pgsql, sqlite
 driver = mysql
 connect = host=localhost dbname=postfix user=postfix password=mypassword
 default_pass_scheme = MD5-CRYPT

#
 password_query = SELECT `username` as `user`, `password` FROM `mailbox` WHERE `username` = '%n@%d' AND `active`='1'

#
 user_query = SELECT CONCAT('/var/vmail/', `maildir`) AS \
 `home`, 1024 AS `uid`, 1024 AS `gid`, concat('dict:storage=', \
 CAST(ROUND(quota / 1024) AS CHAR), '::proxy::sqlquota') \
 AS quota, CONCAT('*:storage=', CAST(quota AS CHAR), 'B') AS quota_rule \
 FROM `mailbox` WHERE `username` = '%n@%d' AND `active`='1'

# Query to get a list of all usernames.
 iterate_query = SELECT username AS user FROM mailbox
# systemctl restart dovecot

Просмотр квоты пользователя(также можно просмотреть в WEB-интерфейсе PostfixAdmin).

# doveadm quota get -u username@example.com

Включение оповещений при превышении квоты

# nano /etc/dovecot/conf.d/90-quota.conf
plugin {
 # LDA/LMTP allows saving the last mail to bring user from under quota to
 # over quota, if the quota doesn't grow too high. Default is to allow as
 # long as quota will stay under 10% above the limit. Also allowed e.g. 10M.
   quota_rule = *:storage=500M
   quota_rule2 = Trash:storage=+100M
   quota_rule3 = Junk:ignore
   quota_grace = 10%%
}

dict {
   sqlquota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
 }

##
## Quota backends
##

# Multiple backends are supported:
# dirsize: Find and sum all the files found from mail directory.
# Extremely SLOW with Maildir. It'll eat your CPU and disk I/O.
# dict: Keep quota stored in dictionary (eg. SQL)
# maildir: Maildir++ quota
# fs: Read-only support for filesystem quota

plugin {
   #quota = dirsize:User quota
   quota = maildir:User quota::proxy::quota

   #quota = dict:User quota::proxy::quota
   #quota = fs:User quota
}

# Multiple quota roots are also possible, for example this gives each user
# their own 100MB quota and one shared 1GB quota within the domain:
plugin {
   #quota = dict:user::proxy::quota
   #quota2 = dict:domain:%d:proxy::quota_domain
   #quota_rule = *:storage=102400
   #quota2_rule = *:storage=1048576
}
# nano /etc/dovecot/quota-warning.sh
#!/bin/sh
PERCENT=$1
USER=$2
cat << EOF | /usr/libexec/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@tst-amo.net.ua
Subject: quota warning
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
To: $USER

Внимание!
Ваш ящик заполнен на $PERCENT%.

Attention!
Your mailbox is now $PERCENT% full.
EOF

 

Leave a Reply

Your email address will not be published. Required fields are marked *