Почтовый сервер Postfix, Dovecot — различия между версиями

Материал из megapuper
Перейти к: навигация, поиск
 
(не показано 25 промежуточных версий этого же участника)
Строка 16: Строка 16:
 
Создаём пользователя и группу для виртуальных почтовых ящиков
 
Создаём пользователя и группу для виртуальных почтовых ящиков
 
  # useradd -u 20003 -d /dev/null -s /bin/false vmail
 
  # useradd -u 20003 -d /dev/null -s /bin/false vmail
 +
# usermod -aG vmail vmail
  
  
'''2. Установка Nginx, MySQL, PHP, PHP-extension. Этот web-сервер будет использоваться для PostfixAdmin '''
+
'''2. Установка Nginx, MySQL, PHP. Этот web-сервер будет использоваться с PostfixAdmin '''
  
 
Здесь коротко, ибо уже тыщу раз ставилось)<br/>
 
Здесь коротко, ибо уже тыщу раз ставилось)<br/>
Строка 64: Строка 65:
 
   
 
   
 
         root /srv/www/postfix;
 
         root /srv/www/postfix;
         index index.php index.html index.htm;
+
         index index.php;
 
   
 
   
 
         access_log /var/log/nginx/postfix.access.log;
 
         access_log /var/log/nginx/postfix.access.log;
Строка 83: Строка 84:
  
  
PHP и нужные PHP-extension тоже ставим из пакетов<br/>
+
Ставим PHP<br/>
  # pkg install php55
+
  # apt install php7.1-fpm php7.1-gd php7.1-imap php7.1-intl php7.1-mbstring php7.1-mcrypt php7.1-mysql
# pkg install php55-* (пригодятся php55-ctype php55-dom php55-exif php55-fileinfo php55-filter php55-gd php55-hash php55-iconv php55-imap php55-intl php55-json php55-mbstring php55-mcrypt \
 
  php55-mysql php55-mysqli php55-pdo php5-pdo_mysql php55-session php55-xml)
 
  
  
Конфиг php-fpm <code>/usr/local/etc/php-fpm.conf</code>
+
Конфиг для виртуального хоста <code>/etc/php/7.1/fpm/pool.d/postfix.conf</code>
[global]
 
error_log = /var/log/php/php-fpm.log
 
pid = /var/run/php-fpm.pid
 
log_level = notice
 
include=/usr/local/etc/php/*.conf
 
 
 
 
 
Конфиг для виртуального хоста <code>/usr/local/etc/php/postfix.conf</code>
 
 
  [postfix]
 
  [postfix]
prefix = /usr/local/www/$pool
+
  listen = 127.0.0.1:20003
  listen = 127.0.0.1:10000
 
 
  listen.allowed_clients = 127.0.0.1
 
  listen.allowed_clients = 127.0.0.1
  listen.owner = www
+
  listen.owner = www-data
  listen.group = www
+
  listen.group = www-data
 
  listen.mode = 0660
 
  listen.mode = 0660
  user = www
+
  user = www-data
  group = www
+
  group = www-data
 
  pm = dynamic
 
  pm = dynamic
  pm.max_children = 4
+
  pm.max_children = 50
  pm.start_servers = 2
+
  pm.start_servers = 5
  pm.min_spare_servers = 1
+
  pm.min_spare_servers = 4
  pm.max_spare_servers = 3
+
  pm.max_spare_servers = 10
 
  pm.max_requests = 100
 
  pm.max_requests = 100
;pm.status_path = /status/php-fpm/$pool
+
  request_terminate_timeout = 30000s
  request_terminate_timeout = 0
+
  request_slowlog_timeout = 100m
  request_slowlog_timeout = 1m
 
 
  slowlog = /var/log/php/$pool.slow.log
 
  slowlog = /var/log/php/$pool.slow.log
 
  catch_workers_output = yes
 
  catch_workers_output = yes
 +
env[TMP] = /tmp
 +
env[TMPDIR] = /tmp
 +
env[TEMP] = /tmp
 +
php_admin_flag[display_errors] = off
 +
php_admin_value[error_log] = /var/log/php/$pool.error.log
 +
php_admin_flag[log_errors] = on
  
  
MySQL тоже из пакетов
+
Ставим MySQL
  # pkg install mysql56-server
+
  # wget https://repo.percona.com/apt/percona-release_0.1-6.$(lsb_release -sc)_all.deb
 +
# dpkg -i percona-release_0.1-6.$(lsb_release -sc)_all.deb
 +
# apt update
 +
# apt install percona-server-server-5.7
  
  
Простенький конфиг <code>/etc/my.cnf</code><br/>
+
В конфиг <code>/etc/mysql/percona-server.conf.d/mysqld.cnf добавляем</code><br/>
 
  [mysqld]
 
  [mysqld]
 
  bind-address=127.0.0.1
 
  bind-address=127.0.0.1
Строка 140: Строка 138:
 
  > create database postfix character set utf8 collate utf8_general_ci;
 
  > create database postfix character set utf8 collate utf8_general_ci;
 
  > grant all on postfix.* to postfix@127.0.0.1 identified by '<font color=blue>ПАРОЛЬ</font>';
 
  > grant all on postfix.* to postfix@127.0.0.1 identified by '<font color=blue>ПАРОЛЬ</font>';
 
  
 
Правим основной конфиг PostfixAdmin <code>config.inc.php</code><br/>
 
Правим основной конфиг PostfixAdmin <code>config.inc.php</code><br/>
Строка 462: Строка 459:
 
// Optional:<br/>
 
// Optional:<br/>
 
// Script to run after creation of mailboxes.<br/>
 
// Script to run after creation of mailboxes.<br/>
$CONF['mailbox_postcreation_script'] = '/usr/local/www/postfix/scripts/addmail.sh';
+
$CONF['mailbox_postcreation_script'] = '/srv/www/postfix/scripts/addmail.sh';
  
  
 
// Optional:<br/>
 
// Optional:<br/>
 
// Script to run after alteration of mailboxes.<br/>
 
// Script to run after alteration of mailboxes.<br/>
$CONF['mailbox_postedit_script'] = '/usr/local/www/postfix/scripts/editmail.sh';
+
$CONF['mailbox_postedit_script'] = '/srv/www/postfix/scripts/editmail.sh';
  
  
 
// Optional:<br/>
 
// Optional:<br/>
 
// Script to run after deletion of mailboxes.<br/>
 
// Script to run after deletion of mailboxes.<br/>
$CONF['mailbox_postdeletion_script'] = '/usr/local/www/postfix/scripts/delmail.sh';
+
$CONF['mailbox_postdeletion_script'] = '/srv/www/postfix/scripts/delmail.sh';
  
  
 
// Optional:<br/>
 
// Optional:<br/>
 
// Script to run after creation of domains.<br/>
 
// Script to run after creation of domains.<br/>
$CONF['domain_postcreation_script'] = '/usr/local/www/postfix/scripts/domainadd.sh';
+
$CONF['domain_postcreation_script'] = '/srv/www/postfix/scripts/domainadd.sh';
  
  
 
// Optional:<br/>
 
// Optional:<br/>
 
// Script to run after deletion of domains.<br/>
 
// Script to run after deletion of domains.<br/>
$CONF['domain_postdeletion_script'] = '/usr/local/www/postfix/scripts/domaindel.sh';
+
$CONF['domain_postdeletion_script'] = '/srv/www/postfix/scripts/domaindel.sh';
  
  
Строка 543: Строка 540:
  
 
Выставляем права
 
Выставляем права
  # chown -R www:www /usr/local/www/postfix
+
  # chown -R www-data:www-data /srv/www/postfix
  
  
Строка 560: Строка 557:
 
'''4. Установка Postfix'''
 
'''4. Установка Postfix'''
  
Postfix ставим из портов, т.к. пакет ставится без поддержки mysql<br/>
+
  # apt install postfix postfix-mysql
  # cd /usr/ports/mail/postfix
 
# make install clean
 
[X] MYSQL, PCRE, SASL2, TLS
 
CYRUS-SASL [X] MYSQL, CRAM, DIGEST, LOGIN, PLAIN
 
 
 
 
 
По окончании установки активируем postfix
 
Would you like to activate Postfix in /etc/mail/mailer.conf [n]? y
 
  
  
Рихтуем основные конфиги postfix<br/>
+
Правим основные конфиги postfix<br/>
первый <code>/usr/local/etс/postfix/main.cf</code><br/>
+
первый <code>/etс/postfix/main.cf</code><br/>
 
<spoiler>
 
<spoiler>
 
biff=no<br/>
 
biff=no<br/>
 
smtpd_banner = $myhostname ESMTP<br/>
 
smtpd_banner = $myhostname ESMTP<br/>
 
queue_directory = /var/spool/postfix<br/>
 
queue_directory = /var/spool/postfix<br/>
command_directory = /usr/local/sbin<br/>
+
command_directory = /usr/sbin<br/>
daemon_directory = /usr/local/libexec/postfix<br/>
+
daemon_directory = /usr/lib/postfix/sbin<br/>
 
data_directory = /var/db/postfix<br/>
 
data_directory = /var/db/postfix<br/>
  
Строка 599: Строка 588:
 
alias_maps = hash:/etc/aliases<br/>
 
alias_maps = hash:/etc/aliases<br/>
 
alias_database = hash:/etc/aliases<br/>
 
alias_database = hash:/etc/aliases<br/>
smtp_generic_maps = hash:/usr/local/etc/postfix/aliases_smtp_output<br/>
+
smtp_generic_maps = hash:/etc/postfix/aliases_smtp_output<br/>
lmtp_generic_maps = hash:/usr/local/etc/postfix/aliases_lmtp<br/>
+
lmtp_generic_maps = hash:/etc/postfix/aliases_lmtp<br/>
sender_bcc_maps = mysql:/usr/local/etc/postfix/maps/mysql_bcc_mailbox_maps.cf, mysql:/usr/local/etc/postfix/maps/mysql_bcc_domain_maps.cf<br/>
+
sender_bcc_maps = mysql:/etc/postfix/maps/mysql_bcc_mailbox_maps.cf, mysql:/etc/postfix/maps/mysql_bcc_domain_maps.cf<br/>
virtual_mailbox_domains = mysql:/usr/local/etc/postfix/maps/mysql_virtual_domains.cf<br/>
+
virtual_mailbox_domains = mysql:/etc/postfix/maps/mysql_virtual_domains.cf<br/>
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/maps/mysql_virtual_maps.cf<br/>
+
virtual_mailbox_maps = mysql:/etc/postfix/maps/mysql_virtual_maps.cf<br/>
virtual_alias_maps = mysql:/usr/local/etc/postfix/maps/mysql_virtual_alias_domain_maps.cf, mysql:/usr/local/etc/postfix/maps/mysql_virtual_alias_maps.cf
+
virtual_alias_maps = mysql:/etc/postfix/maps/mysql_virtual_alias_domain_maps.cf, mysql:/etc/postfix/maps/mysql_virtual_alias_maps.cf
 
virtual_transport = lmtp:unix:private/dovecot-lmtp
 
virtual_transport = lmtp:unix:private/dovecot-lmtp
  
Строка 620: Строка 609:
 
debug_peer_level = 2<br/>
 
debug_peer_level = 2<br/>
 
debugger_command =<br/>
 
debugger_command =<br/>
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin<br/>
+
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5<br/>
ddd $daemon_directory/$process_name $process_id & sleep 5
 
 
 
sendmail_path = /usr/local/sbin/sendmail<br/>
 
newaliases_path = /usr/local/bin/newaliases<br/>
 
mailq_path = /usr/local/bin/mailq
 
  
setgid_group = maildrop<br/>
+
sendmail_path = /usr/sbin/sendmail<br/>
sample_directory = /usr/local/etc/postfix
+
newaliases_path = /usr/bin/newaliases<br/>
 +
mailq_path = /usr/bin/mailq<br/>
 +
sample_directory = /etc/postfix
 
</spoiler>
 
</spoiler>
  
  
второй конфиг<code>/usr/local/etс/postfix/master.cf</code>оставляем дефолтным<br/>
+
второй конфиг<code>/etс/postfix/master.cf</code><br/>
 
<spoiler>
 
<spoiler>
 
  # ==========================================================================
 
  # ==========================================================================
Строка 755: Строка 741:
  
 
Создаём файлы, хранящие SQL-запросы, проверяя имена таблиц и полей (<font color=red>в очередной версии PostfixAdmin они могут измениться</font>)
 
Создаём файлы, хранящие SQL-запросы, проверяя имена таблиц и полей (<font color=red>в очередной версии PostfixAdmin они могут измениться</font>)
  [/usr/local/etc/postfix/maps/mysql_virtual_maps.cf]
+
  [/etc/postfix/maps/mysql_virtual_maps.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 763: Строка 749:
 
  query = SELECT username FROM mailbox WHERE username='%s' AND active = '1'
 
  query = SELECT username FROM mailbox WHERE username='%s' AND active = '1'
  
  [/usr/local/etc/postfix/maps/mysql_virtual_domains.cf]
+
  [/etc/postfix/maps/mysql_virtual_domains.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 771: Строка 757:
 
  query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
 
  query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
  
  [/usr/local/etc/postfix/maps/mysql_virtual_alias_maps.cf]
+
  [/etc/postfix/maps/mysql_virtual_alias_maps.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 779: Строка 765:
 
  query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
 
  query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
  
  [/usr/local/etc/postfix/maps/mysql_virtual_alias_domain_maps.cf]
+
  [/etc/postfix/maps/mysql_virtual_alias_domain_maps.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 789: Строка 775:
  
 
Следующие два необязательны, если не будем делать сохранение копий всех писем
 
Следующие два необязательны, если не будем делать сохранение копий всех писем
  [/usr/local/etc/postfix/maps/mysql_bcc_domain_maps.cf]
+
  [/etc/postfix/maps/mysql_bcc_domain_maps.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 797: Строка 783:
 
  query = SELECT 'bccsnd+bccflag@megapuper.ru' FROM domain WHERE domain='%d' AND active = '1'
 
  query = SELECT 'bccsnd+bccflag@megapuper.ru' FROM domain WHERE domain='%d' AND active = '1'
  
  [/usr/local/etc/postfix/maps/mysql_bcc_mailbox_maps.cf]
+
  [/etc/postfix/maps/mysql_bcc_mailbox_maps.cf]
 
   
 
   
 
  user = postfix
 
  user = postfix
Строка 807: Строка 793:
  
 
Выставляем права на конфиги
 
Выставляем права на конфиги
  # chgrp postfix /usr/local/etc/postfix/*.cf
+
  # chgrp postfix /etc/postfix/*.cf
  # chgrp postfix /usr/local/etc/postfix/maps/*.cf
+
  # chgrp postfix /etc/postfix/maps/*.cf
  # chmod u=rw,g=r,o=r /usr/local/etc/postfix/*.cf
+
  # chmod u=rw,g=r,o=r /etc/postfix/*.cf
  # chmod u=rw,g=r,o=r /usr/local/etc/postfix/maps/*.cf
+
  # chmod u=rw,g=r,o=r /etc/postfix/maps/*.cf
  
  
 
Рестартим postfix
 
Рестартим postfix
  # /usr/local/etc/rc.d/postfix restart
+
  # service postfix restart
  
  
 
'''5. Установка Dovecot'''<br/><br/>
 
'''5. Установка Dovecot'''<br/><br/>
Dovecot ставим из портов<br/>
 
# cd /usr/ports/mail/dovecot2/
 
# make install clean
 
[X] MYSQL
 
 
  
Устанавливаем поддержку языка Sieve в Dovecot(включает в себя настройку скриптов пользователями)
+
Dovecot и плагины
  # cd /usr/ports/mail/dovecot2-pigeonhole
+
  # apt install dovecot-core dovecot-mysql dovecot-imapd dovecot-lmtpd dovecot-sieve dovecot-managesieved
# make install clean
 
  
  
Строка 836: Строка 816:
  
 
Выставляем права
 
Выставляем права
  # chown -R mail:wheel /var/lib/dovecot/sieve/private/
+
  # chown -R vmail /var/lib/dovecot/sieve/private/
 
  # chmod -R 700 /var/lib/dovecot/sieve/private/
 
  # chmod -R 700 /var/lib/dovecot/sieve/private/
  
  
 
Правим конфиги dovecot
 
Правим конфиги dovecot
  [/usr/local/etc/dovecot/dovecot.conf]
+
  [/etc/dovecot/dovecot.conf]
 
   
 
   
 
  # Enable installed protocols
 
  # Enable installed protocols
 
  protocols = imap lmtp sieve
 
  protocols = imap lmtp sieve
 
  dict {
 
  dict {
  #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
+
  #quota = mysql:/etc/dovecot/dovecot-dict-auth.conf.ext
 
  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
 
  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
 
  }
 
  }
Строка 852: Строка 832:
  
  
  [/usr/local/etc/dovecot/dovecot-sql.conf.ext]
+
  [/etc/dovecot/dovecot-sql.conf.ext]
 
   
 
   
 
  driver = mysql
 
  driver = mysql
Строка 863: Строка 843:
 
   
 
   
 
  #одной строкой без переносов
 
  #одной строкой без переносов
  password_query = SELECT username as user, password, '%u' AS userdb_master_user, CONCAT('/var/spool/mail/', maildir) AS userdb_home, 1000 AS userdb_uid, 1000 AS userdb_gid, CONCAT('*:storage=', quota, 'B')
+
  password_query = SELECT username as user, password, '%u' AS userdb_master_user, CONCAT('/var/spool/mail/', maildir) AS userdb_home, 20003 AS userdb_uid, 20003 AS userdb_gid, CONCAT('*:storage=', quota, 'B')
 
  as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
 
  as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
 
   
 
   
 
  #одной строкой без переносов
 
  #одной строкой без переносов
  user_query = SELECT CONCAT('/var/spool/mail/', maildir) AS home, 1000 AS uid, 1000 AS gid, CONCAT('*:storage=', quota, 'B') as quota_rule FROM mailbox WHERE username = '%u' AND active ='1'
+
  user_query = SELECT CONCAT('/var/spool/mail/', maildir) AS home, 20003 AS uid, 20003 AS gid, CONCAT('*:storage=', quota, 'B') as quota_rule FROM mailbox WHERE username = '%u' AND active ='1'
  
  
  [/usr/local/etc/dovecot/dovecot-sql-master.conf.ext]
+
  [/etc/dovecot/dovecot-sql-master.conf.ext]
 
   
 
   
 
  driver = mysql
 
  driver = mysql
Строка 879: Строка 859:
  
  
  [/usr/local/etc/dovecot/conf.d/10-auth.conf]
+
  [/etc/dovecot/conf.d/10-auth.conf]
 
   
 
   
 
  # Connect only after start SSL/TLS
 
  # Connect only after start SSL/TLS
Строка 893: Строка 873:
  
  
  [/usr/local/etc/dovecot/conf.d/10-director.conf]
+
  [/etc/dovecot/conf.d/10-director.conf]
 
   
 
   
 
  service director {
 
  service director {
Строка 925: Строка 905:
  
  
  [/usr/local/etc/dovecot/conf.d/10-logging.conf]
+
  [/etc/dovecot/conf.d/10-logging.conf]
 
   
 
   
 
  # Log file to use for error messages. "syslog" logs to syslog,
 
  # Log file to use for error messages. "syslog" logs to syslog,
Строка 955: Строка 935:
  
  
  [/usr/local/etc/dovecot/conf.d/10-mail.conf]
+
  [/etc/dovecot/conf.d/10-mail.conf]
 
   
 
   
 
  mail_location = maildir:/var/spool/mail/%d/%n:INBOX=/var/spool/mail/%d/%n
 
  mail_location = maildir:/var/spool/mail/%d/%n:INBOX=/var/spool/mail/%d/%n
Строка 969: Строка 949:
 
  }
 
  }
 
   
 
   
  mail_uid = 1000
+
  mail_uid = 20003
  mail_gid = 1000
+
  mail_gid = 20003
  
  
  [/usr/local/etc/dovecot/conf.d/10-master.conf]
+
  [/etc/dovecot/conf.d/10-master.conf]
 
   
 
   
 
  service imap-login {
 
  service imap-login {
Строка 987: Строка 967:
 
   
 
   
 
  }
 
  }
 
#service pop3-login {
 
  #inet_listener pop3 {
 
  #port = 110
 
  #}
 
  #inet_listener pop3s {
 
  #port = 995
 
  #ssl = yes
 
  #}
 
#}
 
 
   
 
   
 
  service lmtp {
 
  service lmtp {
Строка 1002: Строка 972:
 
   path = /var/spool/postfix/private/dovecot-lmtp
 
   path = /var/spool/postfix/private/dovecot-lmtp
 
   group = postfix
 
   group = postfix
  mode = 0660
 
 
   user = postfix
 
   user = postfix
   #mode = 0666
+
   mode = 0666
 
   }
 
   }
 
   executable = lmtp -L
 
   executable = lmtp -L
 
  }
 
  }
 
service imap {
 
  #vsz_limit = $default_vsz_limit
 
  # Max. number of IMAP processes (connections)
 
  #process_limit = 1024
 
  #executable = imap
 
}
 
 
#service pop3 {
 
  # Max. number of POP3 processes (connections)
 
  #process_limit = 1024
 
#}
 
 
   
 
   
 
  service auth {
 
  service auth {
 
   unix_listener auth {
 
   unix_listener auth {
 
   path = /var/spool/postfix/private/auth
 
   path = /var/spool/postfix/private/auth
  mode = 0660
 
 
   user = postfix
 
   user = postfix
 
   group = postfix
 
   group = postfix
 +
  mode = 0660
 
   }
 
   }
 
   user = $default_internal_user
 
   user = $default_internal_user
Строка 1036: Строка 993:
  
  
  [/usr/loca/etc/dovecot/conf.d/15-lda.conf]
+
  [/etc/dovecot/conf.d/15-lda.conf]
 
   
 
   
 
  postmaster_address = postmaster@megapuper.ru
 
  postmaster_address = postmaster@megapuper.ru
Строка 1051: Строка 1008:
  
  
  [/usr/local/etc/dovecot/conf.d/20-imap.conf]
+
  [/etc/dovecot/conf.d/20-imap.conf]
 
   
 
   
 
  protocol imap {
 
  protocol imap {
 
   mail_plugins = $mail_plugins imap_quota mail_log notify quota
 
   mail_plugins = $mail_plugins imap_quota mail_log notify quota
  #ssl_cert = </usr/local/etc/dovecot/ssl.cert.pem
 
  #ssl_key = </usr/local/etc/dovecot/ssl.key.pem
 
 
   info_log_path = /var/log/dovecot/dovecot-imap.log
 
   info_log_path = /var/log/dovecot/dovecot-imap.log
 
   mail_max_userip_connections = 100
 
   mail_max_userip_connections = 100
   # IMAP logout format string:
+
   #ssl_cert = </etc/dovecot/ssl.cert.pem
  # %i - total number of bytes read from client
+
   #ssl_key = </etc/dovecot/ssl.key.pem
  # %o - total number of bytes sent to client
+
  #imap_logout_format = bytes=%i/%o
 
   #imap_capability =
 
  #imap_idle_notify_interval = 2 mins
 
  #imap_id_send =
 
  #imap_id_log =
 
 
  }
 
  }
  
  
  
  [/usr/local/etc/dovecot/conf.d/20-lmtp.conf]
+
  [/etc/dovecot/conf.d/20-lmtp.conf]
 
   
 
   
 
  protocol lmtp {
 
  protocol lmtp {
Строка 1080: Строка 1030:
  
  
  [/usr/local/etc/dovecot/conf.d/20-managesieve.conf]
+
  [/etc/dovecot/conf.d/20-managesieve.conf]
 
   
 
   
 
  service managesieve-login {
 
  service managesieve-login {
Строка 1106: Строка 1056:
  
  
  [/usr/local/etc/dovecot/conf.d/90-quota.conf]
+
  [/etc/dovecot/conf.d/90-quota.conf]
 
   
 
   
 
  plugin {
 
  plugin {
Строка 1135: Строка 1085:
  
  
  [/usr/local/etc/dovecot/conf.d/90-sieve.conf]
+
  [/etc/dovecot/conf.d/90-sieve.conf]
 
   
 
   
 
  plugin {
 
  plugin {
Строка 1160: Строка 1110:
  
  
  [/usr/local/etc/dovecot/conf.d/auth-sql.conf.ext]
+
  [/etc/dovecot/conf.d/auth-sql.conf.ext]
 
   
 
   
 
  auth_master_user_separator = *
 
  auth_master_user_separator = *
Строка 1166: Строка 1116:
 
  passdb {
 
  passdb {
 
   driver = sql
 
   driver = sql
   args = /usr/local/etc/dovecot/dovecot-sql-master.conf.ext
+
   args = /etc/dovecot/dovecot-sql-master.conf.ext
 
   master = yes
 
   master = yes
 
   pass = yes
 
   pass = yes
Строка 1172: Строка 1122:
 
  passdb {
 
  passdb {
 
   driver = sql
 
   driver = sql
   args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
+
   args = /etc/dovecot/dovecot-sql.conf.ext
   #default_fields = userdb_gid=1000 userdb_uid=1000
+
   #default_fields = userdb_gid=20003 userdb_uid=20003
 
  }
 
  }
 
  userdb {
 
  userdb {
Строка 1180: Строка 1130:
 
  userdb {
 
  userdb {
 
   driver = sql
 
   driver = sql
   args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
+
   args = /etc/dovecot/dovecot-sql.conf.ext
   #default_fields = uid=1000 gid=1000
+
   #default_fields = uid=20003 gid=20003
 
  }
 
  }
  
  
 
Меняем права и владельца конфигов:
 
Меняем права и владельца конфигов:
  # chgrp mail /usr/local/etc/dovecot/*.conf
+
  # chgrp vmail /etc/dovecot/*.conf
  # chmod g+r /usr/local/etc/dovecot/*.conf
+
  # chmod g+r /etc/dovecot/*.conf
  # chgrp mail /usr/local/etc/dovecot/*.ext
+
  # chgrp vmail /etc/dovecot/*.ext
  # chmod g+r /usr/local/etc/dovecot/*.ext
+
  # chmod g+r /etc/dovecot/*.ext
  # chgrp mail /usr/local/etc/dovecot/conf.d/*.conf
+
  # chgrp vmail /etc/dovecot/conf.d/*.conf
  # chmod g+r /usr/local/etc/dovecot/conf.d/*.conf
+
  # chmod g+r /etc/dovecot/conf.d/*.conf
  # chgrp mail /usr/local/etc/dovecot/conf.d/*.ext
+
  # chgrp vmail /etc/dovecot/conf.d/*.ext
  # chmod g+r /usr/local/etc/dovecot/conf.d/*.ext
+
  # chmod g+r /etc/dovecot/conf.d/*.ext
  
  
Строка 1200: Строка 1150:
 
Папка для логов
 
Папка для логов
 
  # mkdir /var/log/postfixadmin
 
  # mkdir /var/log/postfixadmin
  # chown www:www /var/log/postfixadmin
+
  # chown www-data:www-data /var/log/postfixadmin
  
  
Копируем скрипты в /usr/local/www/postfix/scripts/
+
Копируем скрипты в /srv/www/postfix/scripts/
  
 
  [addmail.sh]
 
  [addmail.sh]
Строка 1297: Строка 1247:
  
 
Даём права
 
Даём права
  # chown -R www:www /usr/local/www/postfix/scripts/
+
  # chown -R www-data:www-data /srv/www/postfix/scripts/
 
  # chmod 744 addmail.sh delmail.sh domainadd.sh domaindel.sh editmail.sh
 
  # chmod 744 addmail.sh delmail.sh domainadd.sh domaindel.sh editmail.sh
  
Строка 1303: Строка 1253:
 
Создаём папку для почты
 
Создаём папку для почты
 
  # mkdir /var/spool/mail
 
  # mkdir /var/spool/mail
  # chown -R mail:mail /var/spool/mail
+
  # chown -R vmail:vmail /var/spool/mail
  
  
Строка 1309: Строка 1259:
  
 
Создаём в postfixadmin домен и ящики, проверяем хождение почты.
 
Создаём в postfixadmin домен и ящики, проверяем хождение почты.
 
Удаляем setup.php
 
  
  
Строка 1323: Строка 1271:
 
         server_name webmail.megapuper.ru;
 
         server_name webmail.megapuper.ru;
 
   
 
   
  root /usr/local/www/roundcube;
+
  root /srv/www/roundcube;
 
         index index.php index.html index.htm;
 
         index index.php index.html index.htm;
 
   
 
   
Строка 1334: Строка 1282:
 
   
 
   
 
  location ~ \.php$ {
 
  location ~ \.php$ {
     fastcgi_pass  127.0.0.1:10002;
+
     fastcgi_pass  127.0.0.1:20003;
 
     fastcgi_index  index.php;
 
     fastcgi_index  index.php;
 
     fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
 
     fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
Строка 1345: Строка 1293:
 
Конфиг php
 
Конфиг php
 
  [roundcube]
 
  [roundcube]
prefix = /usr/local/www/$pool
+
  listen = 127.0.0.1:20003
  listen = 127.0.0.1:10002
 
 
  listen.allowed_clients = 127.0.0.1
 
  listen.allowed_clients = 127.0.0.1
  listen.owner = www
+
  listen.owner = www-data
  listen.group = www
+
  listen.group = www-data
 
  listen.mode = 0660
 
  listen.mode = 0660
  user = www
+
  user = $pool
  group = www
+
  group = $pool
 
  pm = dynamic
 
  pm = dynamic
 
  pm.max_children = 4
 
  pm.max_children = 4
Строка 1410: Строка 1357:
 
DKIM - цифровая подпись, которая добавляется к заголовкам письма сервером отправителя, по которой сервер получателя может удостовериться, что отправитель письма соответствует полю From в заголовках письма.
 
DKIM - цифровая подпись, которая добавляется к заголовкам письма сервером отправителя, по которой сервер получателя может удостовериться, что отправитель письма соответствует полю From в заголовках письма.
  
Ставим из пакетов
+
Ставим opendkim и тулзы
  # pkg install opendkim
+
  # apt install opendkim opendkim-tools
  
  
Заводим пользователя
+
Добавляем пользователя в группу
  # pw useradd -n opendkim -d /home/opendkim -g mail -m -s "/usr/sbin/nologin" -w no
+
  # usermod -aG opendkim vmail
  
  
Создаём папку для конфига и прочего
+
Создаём папку для ключей
  # mkdir /usr/local/etc/opendkim/
+
  # mkdir /etc/opendkim/
  
  
Подготавливаем конфиг <code>/usr/local/etc/opendkim/opendkim.conf</code>
+
Подготавливаем конфиг <code>/etc/opendkim.conf</code>
  Socket         inet:8891@localhost
+
  Socket                 inet:8891@localhost
  Syslog         yes
+
PidFile                /var/run/opendkim/opendkim.pid
  SyslogSuccess   yes
+
UserID                  opendkim:opendkim
  LogWhy         yes
+
UMask                  002
  X-Header        yes
+
  Syslog                 yes
  Canonicalization relaxed/relaxed
+
  SyslogSuccess           yes
 +
# на время отладки включим расширенное логирование
 +
  LogWhy                 yes
 +
  SoftwareHeader          yes
 +
  Canonicalization       relaxed/relaxed
 
  # подпись и проверка подписей
 
  # подпись и проверка подписей
  #Mode           sv
+
  #Mode                   sv
 
  # если только подписываем
 
  # если только подписываем
  Mode           s
+
  Mode                   s
 +
 
  # список ключей
 
  # список ключей
  KeyTable file:/usr/local/etc/opendkim/keytable
+
  KeyTable file:/etc/opendkim/keytable
 
 
  # соответствие адресов/доменов и ключей
 
  # соответствие адресов/доменов и ключей
  SigningTable file:/usr/local/etc/opendkim/signingtable
+
  SigningTable file:/etc/opendkim/signingtable
  # если вы подписываем и на других серверах
+
  # если подписываем и на других серверах
  #ExternalIgnoreList file:/usr/local/etc/opendkim/trusted
+
  #ExternalIgnoreList file:/etc/opendkim/trusted
 
  # список внутренних хостов, почта которых требует подписи
 
  # список внутренних хостов, почта которых требует подписи
  InternalHosts file:/usr/local/etc/opendkim/internal
+
  InternalHosts file:/etc/opendkim/internal
  
  
 
Генерируем ключ
 
Генерируем ключ
  # opendkim-genkey -D /usr/local/etc/opendkim/ -d megapuper.ru -s megapuper
+
  # opendkim-genkey -D /etc/opendkim/ -d megapuper.ru -s megapuper
  
  
Прописываем ключ в <code>/usr/local/etc/opendkim/keytable</code>
+
Прописываем ключ в <code>/etc/opendkim/keytable</code>
  megapuper._domainkey.megapuper.ru megapuper.ru:megapuper:/usr/local/etc/opendkim/megapuper.private
+
  megapuper._domainkey.megapuper.ru megapuper.ru:megapuper:/etc/opendkim/megapuper.private
  
  
Соответствие адреса и ключа <code>/usr/local/etc/opendkim/signingtable</code>
+
Соответствие адреса и ключа <code>/etc/opendkim/signingtable</code>
 
  megapuper.ru megapuper._domainkey.megapuper.ru
 
  megapuper.ru megapuper._domainkey.megapuper.ru
  
  
Список хостов, почта которых требует подписи <code>/usr/local/etc/opendkim/internal</code>
+
Список хостов, почта которых требует подписи <code>/etc/opendkim/internal</code>
 
  108.195.52.173
 
  108.195.52.173
 
  32.210.209.35
 
  32.210.209.35
 
  192.168.0.7
 
  192.168.0.7
 
  192.168.100.120
 
  192.168.100.120
 +
127.0.0.1
  
  
 
Выставляем права
 
Выставляем права
  # chown -R opendkim:mail /usr/local/etc/opendkim/
+
  # chown -R opendkim:vmail /etc/opendkim/
  
  
Подключаем в postfix <code>/usr/local/etc/postfix/main.cf</code>
+
Подключаем в postfix <code>/etc/postfix/main.cf</code>
 
  milter_default_action = accept
 
  milter_default_action = accept
 
  smtpd_milters = inet:localhost:8891
 
  smtpd_milters = inet:localhost:8891
 
  non_smtpd_milters = inet:localhost:8891
 
  non_smtpd_milters = inet:localhost:8891
 
 
Добавляем в <code>/etc/rc.conf</code>
 
milteropendkim_enable="YES"
 
milteropendkim_uid="opendkim"
 
  
  
Строка 1483: Строка 1430:
  
 
Проверяем всё ли правильно
 
Проверяем всё ли правильно
  # opendkim-testkey -vvv -d megapuper.ru -s megapuper -k /usr/local/etc/opendkim/megapuper.private
+
  # opendkim-testkey -vvv -d megapuper.ru -s megapuper -k /etc/opendkim/megapuper.private
  
  
Строка 1493: Строка 1440:
  
 
Далее стартуем/рестартуем сервисы
 
Далее стартуем/рестартуем сервисы
  # /usr/local/etc/rc.d/milter-opendkim start
+
  # service opendkim restart
  # /usr/local/etc/rc.d/postfix start
+
  # service postfix restart
 
 
 
 
Потому как путь к конфигу поменяли относительно дефолтного, пришлось поправить скрипт запуска <code>/usr/local/etc/rc.d/milter-opendkim</code>
 
: ${milteropendkim_cfgfile="/usr/local/etc/opendkim/opendkim.conf"}
 
  
  
Строка 1529: Строка 1472:
  
  
Добавляем в <code>/usr/local/etc/postfix/main.cf</code>
+
Добавляем в <code>/etc/postfix/main.cf</code>
  recipient_bcc_maps = hash:/usr/local/etc/postfix/recipient_bcc  
+
  recipient_bcc_maps = hash:/etc/postfix/recipient_bcc  
  
  
В этот файл <code>/usr/local/etc/postfix/recipient_bcc</code> прописываем с какого ящика на какой пересылать
+
В этот файл <code>/etc/postfix/recipient_bcc</code> прописываем с какого ящика на какой пересылать
 
  test@megapuper.ru test@mail.ru
 
  test@megapuper.ru test@mail.ru
  
  
 
Выполняем
 
Выполняем
  postmap /usr/local/etc/postfix/recipient_bcc
+
  postmap /etc/postfix/recipient_bcc
 
  postfix reload
 
  postfix reload
  

Текущая версия на 22:50, 6 марта 2022

При установке будем ориентироваться на этот мануал: http://dummyluck.com/page/pochtovyi_server_nastroika_opisanie
Настройку будем производить для сервера с одним доменом. Система Debian Stretch


1. Подготовка
Прописываем хостнейм /etc/hostname
mail.megapuper.ru


Делаем изменения в хостах /etc/hosts

127.0.0.1         localhost
109.172.52.114	  megapuper.ru
109.172.52.114    mail.megapuper.ru


Создаём пользователя и группу для виртуальных почтовых ящиков

# useradd -u 20003 -d /dev/null -s /bin/false vmail
# usermod -aG vmail vmail


2. Установка Nginx, MySQL, PHP. Этот web-сервер будет использоваться с PostfixAdmin

Здесь коротко, ибо уже тыщу раз ставилось)


Nginx cтавим из пакетов

# apt install nginx


Основной конфиг примерно такой/etc/nginx/nginx.conf

user www-data;
worker_processes 2;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
events {
 worker_connections  4096;
 multi_accept on;
 use epoll;
}
http {
 include       /etc/nginx/mime.types;
 default_type  application/octet-stream;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_requests 100;
 keepalive_timeout  5;
 variables_hash_max_size 1024;
 variables_hash_bucket_size 64;
 server_names_hash_bucket_size 64;
 types_hash_max_size 2048;
 types_hash_bucket_size 64;
 client_body_buffer_size 608M;
 client_max_body_size 608M;
 include /etc/nginx/conf.d/*.conf;
 include /etc/nginx/sites-enabled/*;
}


Конфиг виртуального хоста /etc/nginx/conf/postfix.conf

server {
       listen 80;
       server_name postfix.megapuper.ru;

       root /srv/www/postfix;
       index index.php;

       access_log /var/log/nginx/postfix.access.log;
       error_log  /var/log/nginx/postfix.error.log;

       location / {
           try_files $uri $uri/ /index.php?$uri&$args;
       }

       location ~ \.php$ {
           fastcgi_pass   127.0.0.1:20003;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
           fastcgi_intercept_errors on;
           include fastcgi_params;
       }
}


Ставим PHP

# apt install php7.1-fpm php7.1-gd php7.1-imap php7.1-intl php7.1-mbstring php7.1-mcrypt php7.1-mysql


Конфиг для виртуального хоста /etc/php/7.1/fpm/pool.d/postfix.conf

[postfix]
listen = 127.0.0.1:20003
listen.allowed_clients = 127.0.0.1
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
user = www-data
group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 4
pm.max_spare_servers = 10
pm.max_requests = 100
request_terminate_timeout = 30000s
request_slowlog_timeout = 100m
slowlog = /var/log/php/$pool.slow.log
catch_workers_output = yes
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/$pool.error.log
php_admin_flag[log_errors] = on


Ставим MySQL

# wget https://repo.percona.com/apt/percona-release_0.1-6.$(lsb_release -sc)_all.deb
# dpkg -i percona-release_0.1-6.$(lsb_release -sc)_all.deb
# apt update
# apt install percona-server-server-5.7


В конфиг /etc/mysql/percona-server.conf.d/mysqld.cnf добавляем

[mysqld]
bind-address=127.0.0.1

В конфигах, где используется подключение к базе указываем хост 127.0.0.1

После этого имеем готовый web-сервер можно переходить к установке PostfixAdmin


3. Установка PostfixAdmin

Скачиваем последнюю версию отсюда http://sourceforge.net/projects/postfixadmin/ и заливаем на web-сервер

Создаём базу и даём права пользователю

> create database postfix character set utf8 collate utf8_general_ci;
> grant all on postfix.* to postfix@127.0.0.1 identified by 'ПАРОЛЬ';

Правим основной конфиг PostfixAdmin config.inc.php
Spoiler


Выставляем права

# chown -R www-data:www-data /srv/www/postfix


Теперь заходим на http://postfixadmin/setup.php и видим, что запустилась установка
Если все условия установки выполнены, то в базе создадутся необходимые таблицы и будет предложено создать суперадмина.

В поле Setup password вводим пароль из config.inc.php: $CONF['setup_password'] = 'пароль_установки';
Заполняем остальные поля, и после нажатия кнопки Создать сгенерится хэш.

Этот хеш надо вставить в config.inc.php вместо пароля установки: $CONF['setup_password'] = 'хеш';
Повторяем процедуру заведения суперадмина используя пароль_установки

После создания суперадмина временно оставляем PostfixAdmin(так как без postfix и dovecot ящики создаваться не будут)


4. Установка Postfix

# apt install postfix postfix-mysql


Правим основные конфиги postfix
первый /etс/postfix/main.cf
Spoiler


второй конфиг/etс/postfix/master.cf
Spoiler


Создаём таблицы данных формата "hash" и базы с помощью команды postmap
Необходимо создать файлы и базы со списками, которые были подключены в конфиге выше, даже если они будут пустыми

# touch aliases_lmtp
# touch aliases_smtp_output
# postmap aliases_lmtp
# postmap aliases_smtp_output


Создаём файлы, хранящие SQL-запросы, проверяя имена таблиц и полей (в очередной версии PostfixAdmin они могут измениться)

[/etc/postfix/maps/mysql_virtual_maps.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT username FROM mailbox WHERE username='%s' AND active = '1'
[/etc/postfix/maps/mysql_virtual_domains.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
[/etc/postfix/maps/mysql_virtual_alias_maps.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
[/etc/postfix/maps/mysql_virtual_alias_domain_maps.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT CONCAT('%u', '@', target_domain) FROM alias_domain WHERE alias_domain = '%d' AND active = 1


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

[/etc/postfix/maps/mysql_bcc_domain_maps.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT 'bccsnd+bccflag@megapuper.ru' FROM domain WHERE domain='%d' AND active = '1'
[/etc/postfix/maps/mysql_bcc_mailbox_maps.cf]

user = postfix
password = ПАРОЛЬ
hosts = 127.0.0.1
dbname = postfix
query = SELECT CONCAT('%u', '+bccflag', '@', '%d') FROM mailbox WHERE username='%s' AND active = '1'


Выставляем права на конфиги

# chgrp postfix /etc/postfix/*.cf
# chgrp postfix /etc/postfix/maps/*.cf
# chmod u=rw,g=r,o=r /etc/postfix/*.cf
# chmod u=rw,g=r,o=r /etc/postfix/maps/*.cf


Рестартим postfix

# service postfix restart


5. Установка Dovecot

Dovecot и плагины

# apt install dovecot-core dovecot-mysql dovecot-imapd dovecot-lmtpd dovecot-sieve dovecot-managesieved


Создаём сопутствуюшие папки

# mkdir /var/log/dovecot
# mkdir -p /var/lib/dovecot/sieve/global/
# mkdir -p /var/lib/dovecot/sieve/private/


Выставляем права

# chown -R vmail /var/lib/dovecot/sieve/private/
# chmod -R 700 /var/lib/dovecot/sieve/private/


Правим конфиги dovecot

[/etc/dovecot/dovecot.conf]

# Enable installed protocols
protocols = imap lmtp sieve
dict {
#quota = mysql:/etc/dovecot/dovecot-dict-auth.conf.ext
#expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
}
!include conf.d/*.conf


[/etc/dovecot/dovecot-sql.conf.ext]

driver = mysql
connect = host=127.0.0.1 dbname=postfix user=postfix password=ПАРОЛЬ
default_pass_scheme = PLAIN
#default_pass_scheme = PLAIN-MD5
#   %u = entire user@domain
#   %n = user part of user@domain
#   %d = domain part of user@domain

#одной строкой без переносов
password_query = SELECT username as user, password, '%u' AS userdb_master_user, CONCAT('/var/spool/mail/', maildir) AS userdb_home, 20003 AS userdb_uid, 20003 AS userdb_gid, CONCAT('*:storage=', quota, 'B')
as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1'

#одной строкой без переносов
user_query = SELECT CONCAT('/var/spool/mail/', maildir) AS home, 20003 AS uid, 20003 AS gid, CONCAT('*:storage=', quota, 'B') as quota_rule FROM mailbox WHERE username = '%u' AND active ='1'


[/etc/dovecot/dovecot-sql-master.conf.ext]

driver = mysql
#default_pass_scheme = PLAIN-MD5
default_pass_scheme = PLAIN
connect = host=127.0.0.1 dbname=postfix user=postfix password=ПАРОЛЬ
password_query = SELECT username AS user, password FROM admin WHERE username = '%u' AND active = '1'


[/etc/dovecot/conf.d/10-auth.conf]

# Connect only after start SSL/TLS
# If not local network only !
disable_plaintext_auth = no
auth_cache_size = 1M
auth_cache_negative_ttl = 0
auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
auth_master_user_separator = *
auth_mechanisms = plain

!include auth-sql.conf.ext


[/etc/dovecot/conf.d/10-director.conf]

service director {
  unix_listener login/director {
    #mode = 0666
  }
  fifo_listener login/proxy-notify {
    #mode = 0666
  }
  unix_listener director-userdb {
    #mode = 0600
  }
  inet_listener {
    #port =
  }
}
# Enable director for the wanted login services by telling them to
# connect to director socket instead of the default login socket:
service imap-login {
  #executable = imap-login director
}

#service pop3-login {
  #executable = pop3-login director
#}

# Enable director for LMTP proxying:
protocol lmtp {
  #auth_socket_path = director-userdb
}


[/etc/dovecot/conf.d/10-logging.conf]

# Log file to use for error messages. "syslog" logs to syslog,
# /dev/stderr logs to stderr.
log_path = /var/log/dovecot/dovecot.log
info_log_path = /var/log/dovecot/dovecot-info.log
debug_log_path = /var/log/dovecot/dovecot-debug.log
auth_verbose = yes
auth_verbose_passwords = yes
auth_debug = no
auth_debug_passwords = no
mail_debug = yes
verbose_ssl = no

#plugin {
#}
#log_timestamp = "%b %d %H:%M:%S "
#login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c
#login_log_format = %$: %s
#mail_log_prefix = "%s(%u): "
#  Format to use for logging mail deliveries. You can use variables:
#  %$ - Delivery status message (e.g. "saved to INBOX")
#  %m - Message-ID
#  %s - Subject
#  %f - From address
#  %p - Physical size
#  %w - Virtual size
#deliver_log_format = msgid=%m: %$


[/etc/dovecot/conf.d/10-mail.conf]

mail_location = maildir:/var/spool/mail/%d/%n:INBOX=/var/spool/mail/%d/%n

namespace inbox {
  type = private
  separator = /
  prefix =
  inbox = yes
  hidden = no
  list = yes
  subscriptions = yes
}

mail_uid = 20003
mail_gid = 20003


[/etc/dovecot/conf.d/10-master.conf]

service imap-login {
 inet_listener imap {
  address = *
  port = 143
  #ssl = yes
 }
 inet_listener imaps {
  #port = 993
  #ssl = yes
 }

}

service lmtp {
  unix_listener lmtp {
  path = /var/spool/postfix/private/dovecot-lmtp
  group = postfix
  user = postfix
  mode = 0666
 }
 executable = lmtp -L
}

service auth {
  unix_listener auth {
  path = /var/spool/postfix/private/auth
  user = postfix
  group = postfix
  mode = 0660
 }
 user = $default_internal_user
}

service auth-worker {
  user = $default_internal_user
}


[/etc/dovecot/conf.d/15-lda.conf]

postmaster_address = postmaster@megapuper.ru
hostname = mail.megapuper.ru
#rejection_subject = Rejected: %s
#  %n = CRLF, %r = reason, %s = original subject, %t = recipient
rejection_reason = Your message to <%t> was automatically rejected:%n%r

protocol lda {
  mail_plugins = sieve
  log_path = /var/log/dovecot/mail-dovecot-lda-errors.log
  info_log_path = /var/log/dovecot/mail-dovecot-lda.log
}


[/etc/dovecot/conf.d/20-imap.conf]

protocol imap {
 mail_plugins = $mail_plugins imap_quota mail_log notify quota
 info_log_path = /var/log/dovecot/dovecot-imap.log
 mail_max_userip_connections = 100
 #ssl_cert = </etc/dovecot/ssl.cert.pem
 #ssl_key = </etc/dovecot/ssl.key.pem

}


[/etc/dovecot/conf.d/20-lmtp.conf]

protocol lmtp {
 mail_plugins = $mail_plugins quota sieve
 postmaster_address = postmaster@megapuper.ru
 info_log_path = /var/log/dovecot/dovecot-lmtp.log
}


[/etc/dovecot/conf.d/20-managesieve.conf]

service managesieve-login {
  inet_listener sieve {
  address = 127.0.0.1
  port = 4190
}
 service_count = 1
 vsz_limit = 64M
}
#mail_plugins = virtual
#protocol sieve {
 #managesieve_max_line_length = 65536
 #mail_max_userip_connections = 10
 #mail_plugins = virtual
 # MANAGESIEVE logout format string:
 #  %i - total number of bytes read from client
 #  %o - total number of bytes sent to client
 #managesieve_logout_format = bytes=%i/%o
 #managesieve_implementation_string = Dovecot Pigeonhole
 #managesieve_sieve_capability =
 #managesieve_notify_capability =
 #managesieve_max_compile_errors = 5
#}


[/etc/dovecot/conf.d/90-quota.conf]

plugin {
  quota = dict:user::file:/var/spool/mail/%d/%n/dovecot-quota
  quota_rule = *:storage=1GB
  quota_rule2 = Trash:storage=+10%%
}

# Note that % needs to be escaped as %%, otherwise "% " expands to empty.
plugin {
  #quota_warning = storage=95%% quota-warning 95 %u
  #quota_warning2 = storage=80%% quota-warning 80 %u
}

plugin {
  #quota = dirsize:User quota
  #quota = maildir:User quota
  #quota = dict:User quota::proxy::quota
  #quota = fs:User quota
}

plugin {
  #quota = dict:user::proxy::quota
  #quota2 = dict:domain:%d:proxy::quota_domain
  #quota_rule = *:storage=102400
  #quota2_rule = *:storage=1048576
}


[/etc/dovecot/conf.d/90-sieve.conf]

plugin {
 sieve_user_log = /var/lib/dovecot/sieve/private/%d/%n/.main.peronal.log
 sieve = /var/lib/dovecot/sieve/private/%d/%n/.main.personal.sieve
 #sieve_default = /var/lib/dovecot/sieve/default.sieve
 sieve_dir = /var/lib/dovecot/sieve/private/%d/%n/
 sieve_global_dir = /var/lib/dovecot/sieve/global/
 #sieve_before2 =
 sieve_before = /var/lib/dovecot/sieve/global/incoming_deduplicate.sieve
 #sieve_after =
 #sieve_after2 =
 sieve_extensions = +editheader
 sieve_global_extensions = +vnd.dovecot.duplicate
 sieve_duplicate_period = 1d
 #sieve_plugins =
 recipient_delimiter = +
 #sieve_max_script_size = 1M
 #sieve_max_actions = 32
 #sieve_max_redirects = 4
 #sieve_quota_max_scripts = 0
 #sieve_quota_max_storage = 0
}


[/etc/dovecot/conf.d/auth-sql.conf.ext]

auth_master_user_separator = *
#auth_debug = yes
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql-master.conf.ext
  master = yes
  pass = yes
}
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
  #default_fields = userdb_gid=20003 userdb_uid=20003
}
userdb {
  driver = prefetch
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
  #default_fields = uid=20003 gid=20003
}


Меняем права и владельца конфигов:

# chgrp vmail /etc/dovecot/*.conf
# chmod g+r /etc/dovecot/*.conf
# chgrp vmail /etc/dovecot/*.ext
# chmod g+r /etc/dovecot/*.ext
# chgrp vmail /etc/dovecot/conf.d/*.conf
# chmod g+r /etc/dovecot/conf.d/*.conf
# chgrp vmail /etc/dovecot/conf.d/*.ext
# chmod g+r /etc/dovecot/conf.d/*.ext


Теперь можно вернуться к PostfixAdmin и приступить к созданию доменов и ящиков

Папка для логов

# mkdir /var/log/postfixadmin
# chown www-data:www-data /var/log/postfixadmin


Копируем скрипты в /srv/www/postfix/scripts/

[addmail.sh]

#!/bin/sh
daten=`date -R`
printf "$daten \n CREATE mailbox: $1\n Domain: $2\n MailDir: $3\n Quota: $4 B\n\n" >> /var/log/postfixadmin/addmailbox.log
[delmail.sh]

#!/bin/sh
daten=`date -R`
printf "$daten \n DELETE mailbox: $1\n Domain: $2\n\n" >> /var/log/postfixadmin/delmailbox.log
[domainadd.sh]

#!/bin/sh
daten=`date -R`
printf "$daten \n CREATE Domain: $1\n\n" >> /var/log/postfixadmin/domainadd.log
[domaindel.sh]

#!/bin/sh
daten=`date -R`
printf "$daten \n DELETE Domain: $1\n\n" >> /var/log/postfixadmin/domaindel.log
[editmail.sh]

#!/bin/sh
daten=`date -R`
#del RoundCube user:
host="127.0.0.1"
user="_ROUNDCUBE_SQL_USER_ "
pass="_ROUNDCUBE_SQL_PASSWORD_"
db="_ROUNDCUBE_SQL_BASE_"

sql="SELECT user_id FROM users WHERE username = '$1'"
RES=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`

printf "$daten \n DELETE mailbox: $1\n Domain: $2\n MailDir: $3\n Quota: $4 B\n" >> /var/log/postfixadmin/delmailbox.log
printf " >>> RoundCube SQL-query START \n" >> /var/log/postfixadmin/delmailbox.log

for i in $RES; do
if [ "$i" != "user_id" ]; then
printf " ! FOUND RECORD: USER_ID = $i ! ( $1 )\n" >> /var/log/postfixadmin/delmailbox.log

# Find user_id:
printf " SQL: $sql \n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Cache:
sql="DELETE FROM cache WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from ContactGroupMembers:
sql="DELETE FROM contactgroupmembers WHERE contactgroup_id IN (SELECT contactgroup_id FROM contactgroups WHERE user_id = $i)"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from ContactGroups:
sql="DELETE FROM contactgroups WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Contacts:
sql="DELETE FROM contacts WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Identities:
sql="DELETE FROM identities WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Cache Messages
sql="DELETE FROM cache_messages WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Cache Thread
sql="DELETE FROM cache_thread WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log

# Delete user from Users:
sql="DELETE FROM users WHERE user_id = $i"
RESD=`mysql --host=$host --port=3306 --user=$user --password=$pass --database=$db --execute="$sql"`
printf " SQL: $sql\n" >> /var/log/postfixadmin/delmailbox.log
fi
done
printf " >>> RoundCube SQL-query END \n\n" >> /var/log/postfixadmin/delmailbox.log


Даём права

# chown -R www-data:www-data /srv/www/postfix/scripts/
# chmod 744 addmail.sh delmail.sh domainadd.sh domaindel.sh editmail.sh


Создаём папку для почты

# mkdir /var/spool/mail
# chown -R vmail:vmail /var/spool/mail


Рестартим postfix и dovecot

Создаём в postfixadmin домен и ящики, проверяем хождение почты.


6. Roundcube

Качаем отсюда нужную версию и распаковываем её в папку на веб-сервере


Примерный конфиг nginx

 server {
        listen 80;
        server_name webmail.megapuper.ru;

root /srv/www/roundcube;
        index index.php index.html index.htm;

        access_log /var/log/nginx/roundcube.access.log;
        error_log  /var/log/nginx/roundcube.error.log;

location / {
        try_files $uri $uri/ /index.php?$uri&$args;
        }

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:20003;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
    fastcgi_intercept_errors on;
    include fastcgi_params;
        }
    }


Конфиг php

[roundcube]
listen = 127.0.0.1:20003
listen.allowed_clients = 127.0.0.1
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
user = $pool
group = $pool
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 100
;pm.status_path = /status/php-fpm/$pool
request_terminate_timeout = 0
request_slowlog_timeout = 1m
slowlog = /var/log/php/$pool.slow.log
catch_workers_output = yes


Создаём базу и заводим пользователя

> create database roundcube character set utf8 collate utf8_general_ci;
> grant all privileges on roundcube.* to roundcube@127.0.0.1 identified by 'ПАРОЛЬ';


Заходим http://webmail.megapuper.ru/installer/ и далее по тексту


7. SPF

SPF - это фактически список серверов которым будет разрешено отправлять почту от имени нашего домена


Прописывает в DNS путём добавления TXT-записи

megapuper.ru. 1440 TXT "v=spf1 a mx ip4:109.172.52.114 ~all"


Опции:

"v=spf1" - используемая версия SPF.
"+" - принимать корреспонденцию (Pass). Этот параметр установлен по умолчанию. То есть, если никаких параметров не установлено, то это "Pass";
"-" - Отклонить (Fail);
"~" - "мягкое" отклонение (SoftFail). Письмо будет принято, но будет помечено как СПАМ;
"?" - нейтральное отношение;
"mx" - включает в себя все адреса серверов, указанные в MX-записях домена;
"ip4" - опция позволяет указать конкретный IP-адрес или сеть адресов;
"a" - указываем поведение в случае получения письма от конкретного домена;
"include" - включает в себя хосты, разрешенные SPF-записью указанного домена;
"all" - все остальные сервера, не перечисленные в SPF-записи.


Отправляем письмо на какую-нибудь гуглопочту и проверяем
При просмотре оригинала письма с заголовками у получателя, увидим такие строчки

Received-SPF: pass (google.com: domain of finston@megapuper.ru designates 109.172.52.114 as permitted sender) client-ip=109.172.52.114;
Authentication-Results: mx.google.com;
      spf=pass (google.com: domain of finston@megapuper.ru 


Или здесь http://dkimvalidator.com/


8. DKIM

DKIM - цифровая подпись, которая добавляется к заголовкам письма сервером отправителя, по которой сервер получателя может удостовериться, что отправитель письма соответствует полю From в заголовках письма.

Ставим opendkim и тулзы

# apt install opendkim opendkim-tools


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

# usermod -aG opendkim vmail


Создаём папку для ключей

# mkdir /etc/opendkim/


Подготавливаем конфиг /etc/opendkim.conf

Socket                  inet:8891@localhost
PidFile                 /var/run/opendkim/opendkim.pid
UserID                  opendkim:opendkim
UMask                   002
Syslog                  yes
SyslogSuccess           yes
# на время отладки включим расширенное логирование
LogWhy                  yes
SoftwareHeader          yes
Canonicalization        relaxed/relaxed
# подпись и проверка подписей
#Mode                   sv
# если только подписываем
Mode                    s

# список ключей
KeyTable file:/etc/opendkim/keytable
# соответствие адресов/доменов и ключей
SigningTable file:/etc/opendkim/signingtable
# если подписываем и на других серверах
#ExternalIgnoreList file:/etc/opendkim/trusted
# список внутренних хостов, почта которых требует подписи
InternalHosts file:/etc/opendkim/internal


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

# opendkim-genkey -D /etc/opendkim/ -d megapuper.ru -s megapuper


Прописываем ключ в /etc/opendkim/keytable

megapuper._domainkey.megapuper.ru megapuper.ru:megapuper:/etc/opendkim/megapuper.private


Соответствие адреса и ключа /etc/opendkim/signingtable

megapuper.ru megapuper._domainkey.megapuper.ru


Список хостов, почта которых требует подписи /etc/opendkim/internal

108.195.52.173
32.210.209.35
192.168.0.7
192.168.100.120
127.0.0.1


Выставляем права

# chown -R opendkim:vmail /etc/opendkim/


Подключаем в postfix /etc/postfix/main.cf

milter_default_action = accept
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891


Прописываем в DNS TXT-запись из сгенерённого megapuper.txt

megapuper._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGECRuiaVV2Z8BMwCXp0yoai4IqWQJw/gAa+Qp5BC"


Проверяем всё ли правильно

# opendkim-testkey -vvv -d megapuper.ru -s megapuper -k /etc/opendkim/megapuper.private


Проверка DNS-записи

# dig @8.8.8.8 megapuper._domainkey.megapuper.ru TXT +short
или
# host -t TXT megapuper._domainkey.megapuper.ru 8.8.8.8


Далее стартуем/рестартуем сервисы

# service opendkim restart
# service postfix restart


Снова отправляем письмо на гуглопочту и проверяем
В логах увидим, что opendkim отработал

Oct 19 17:36:51 mail postfix/cleanup[1472]: 4124D4E732: message-id=<op.x6rb05dw73xu59@ws0037>
Oct 19 17:36:51 mail opendkim[1451]: 4124D4E732: DKIM-Signature field added (s=megapuper, d=megapuper.ru)
Oct 19 17:36:51 mail postfix/qmgr[1352]: 4124D4E732: from=<finston@megapuper.ru>, size=702, nrcpt=1 (queue active)


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

Authentication-Results: mx.google.com;
      dkim=pass header.i=@megapuper.ru
DKIM-Filter: OpenDKIM Filter v2.10.3 mail.megapuper.ru 4124D4E732
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=megapuper.ru;

s=megapuper; t=1445265411; bh=rTOBSfI4+dnRHaqML+b7IT3SM2GI+FE6G0AOa/+zdEc=; h=To:Subject:Date:From; b=Ofgjyx6SPMtwF2o7EAIJTXG67RLcJHfNlUeyEDBAB9kesrz9t0gYz22NB54T+v1Wo tQ+P7b60eoI4rgEZtZPwA3iXZgOWwtdUhiGob6MFgkRm0kB2T8L0O+AtNhusQD3LSf 0xGaJDLd2r/BbS/xwe3fMFUVQOJ5nLQctqmCm5HE=


Или здесь http://dkimvalidator.com/


Пересылка входящей почты на другой ящик

Требуется пересылать входящую почту с ящика test@megapuper.ru на test@mail.ru


Добавляем в /etc/postfix/main.cf

recipient_bcc_maps = hash:/etc/postfix/recipient_bcc 


В этот файл /etc/postfix/recipient_bcc прописываем с какого ящика на какой пересылать

test@megapuper.ru test@mail.ru


Выполняем

postmap /etc/postfix/recipient_bcc
postfix reload


Проверяем


Вуаля. Пока всё.