Почтовый сервер в связке Postfix, Dovecot — различия между версиями
Root (обсуждение | вклад) |
Root (обсуждение | вклад) |
||
(не показано 79 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
При установке будем ориентироваться на этот мануал: http://dummyluck.com/page/pochtovyi_server_nastroika_opisanie<br/> | При установке будем ориентироваться на этот мануал: http://dummyluck.com/page/pochtovyi_server_nastroika_opisanie<br/> | ||
− | Настройку будем производить для сервера с одним доменом. Система FreeBSD 10. | + | Настройку будем производить для сервера с одним доменом. Система FreeBSD 10.2 |
− | '''1. Подготовка | + | '''1. Подготовка'''<br/> |
− | + | Прописываем хостнейм <code>/etc/rc.conf</code><br/> | |
− | hostname=" | + | hostname="servmp.megapuper.ru" |
− | + | Делаем изменения в хостах <code>/etc/hosts</code> | |
127.0.0.1 localhost | 127.0.0.1 localhost | ||
109.172.52.114 megapuper.ru | 109.172.52.114 megapuper.ru | ||
Строка 14: | Строка 14: | ||
− | + | Создаём пользователя и добавляем его в группу mail | |
− | + | # pw useradd mail -g mail -s /sbin/nologin -u 1000 | |
− | # pw useradd | + | # pw groupmod mail -m mail |
− | + | Сразу отключаем sendmail<br/> | |
− | + | [etc/rc.conf] | |
+ | |||
sendmail_enable="NO" | sendmail_enable="NO" | ||
sendmail_submit_enable="NO" | sendmail_submit_enable="NO" | ||
sendmail_outbound_enable="NO" | sendmail_outbound_enable="NO" | ||
sendmail_msp_queue_enable="NO" | sendmail_msp_queue_enable="NO" | ||
− | + | ||
− | + | ||
+ | [/etc/periodic.conf] | ||
+ | |||
daily_clean_hoststat_enable="NO" | daily_clean_hoststat_enable="NO" | ||
daily_status_mail_rejects_enable="NO" | daily_status_mail_rejects_enable="NO" | ||
Строка 33: | Строка 36: | ||
− | '''2. | + | '''2. Установка Nginx, MySQL, PHP, PHP-extension. Этот web-сервер будет использоваться для PostfixAdmin ''' |
Здесь коротко, ибо уже тыщу раз ставилось)<br/> | Здесь коротко, ибо уже тыщу раз ставилось)<br/> | ||
Строка 42: | Строка 45: | ||
− | + | Основной конфиг <code>/usr/local/etc/nginx/nginx.conf</code> | |
user www; | user www; | ||
worker_processes 2; | worker_processes 2; | ||
Строка 65: | Строка 68: | ||
types_hash_max_size 2048; | types_hash_max_size 2048; | ||
types_hash_bucket_size 64; | types_hash_bucket_size 64; | ||
− | include /usr/local/etc/nginx/conf/*.conf; | + | include /usr/local/etc/nginx/conf.d/*.conf; |
} | } | ||
− | + | Конфиг виртуального хоста <code>/usr/local/etc/nginx/conf/postfix.conf</code> | |
server { | server { | ||
listen 80; | listen 80; | ||
Строка 96: | Строка 99: | ||
PHP и нужные PHP-extension тоже ставим из пакетов<br/> | PHP и нужные PHP-extension тоже ставим из пакетов<br/> | ||
# pkg install php55 | # pkg install php55 | ||
− | # pkg install php55-* (пригодятся php55-ctype php55-dom php55-gd php55-hash php55-iconv php55-imap php55-json php55-mbstring php55-mcrypt php55-mysql php55-mysqli php55-session php55-xml) | + | # 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> | |
[global] | [global] | ||
error_log = /var/log/php/php-fpm.log | error_log = /var/log/php/php-fpm.log | ||
Строка 107: | Строка 111: | ||
− | + | Конфиг для виртуального хоста <code>/usr/local/etc/php/postfix.conf</code> | |
[postfix] | [postfix] | ||
prefix = /usr/local/www/$pool | prefix = /usr/local/www/$pool | ||
Строка 134: | Строка 138: | ||
− | + | Простенький конфиг <code>/etc/my.cnf</code><br/> | |
[mysqld] | [mysqld] | ||
bind-address=127.0.0.1 | bind-address=127.0.0.1 | ||
− | <font color=red> | + | <font color=red>'''В конфигах, где используется подключение к базе указываем хост 127.0.0.1'''</font> |
− | После этого имеем готовый web-сервер можно переходить к установке | + | После этого имеем готовый web-сервер можно переходить к установке PostfixAdmin |
Строка 147: | Строка 151: | ||
Скачиваем последнюю версию отсюда http://sourceforge.net/projects/postfixadmin/ и заливаем на web-сервер | Скачиваем последнюю версию отсюда http://sourceforge.net/projects/postfixadmin/ и заливаем на web-сервер | ||
− | + | Создаём базу и даём права пользователю | |
− | |||
> 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 ' | + | > grant all on postfix.* to postfix@127.0.0.1 identified by '<font color=blue>ПАРОЛЬ</font>'; |
− | Правим основной конфиг | + | Правим основной конфиг PostfixAdmin <code>config.inc.php</code><br/> |
<spoiler> | <spoiler> | ||
<?php | <?php | ||
Строка 163: | Строка 166: | ||
// To create the hash, visit setup.php in a browser and type a password into the field,<br/> | // To create the hash, visit setup.php in a browser and type a password into the field,<br/> | ||
// on submission it will be echoed out to you as a hashed value.<br/> | // on submission it will be echoed out to you as a hashed value.<br/> | ||
− | $CONF['setup_password'] = ' | + | $CONF['setup_password'] = 'пароль_установки'; |
Строка 183: | Строка 186: | ||
$CONF['database_host'] = '127.0.0.1';<br/> | $CONF['database_host'] = '127.0.0.1';<br/> | ||
$CONF['database_user'] = 'postfix';<br/> | $CONF['database_user'] = 'postfix';<br/> | ||
− | $CONF['database_password'] = ' | + | $CONF['database_password'] = 'ПАРОЛЬ';<br/> |
$CONF['database_name'] = 'postfix';<br/> | $CONF['database_name'] = 'postfix';<br/> | ||
Строка 189: | Строка 192: | ||
// Here, if you need, you can customize table names.<br/> | // Here, if you need, you can customize table names.<br/> | ||
$CONF['database_prefix'] = '';<br/> | $CONF['database_prefix'] = '';<br/> | ||
− | $CONF['database_tables'] = array ( | + | $CONF['database_tables'] = array (<br/> |
− | 'admin' => 'admin' | + | 'admin' => 'admin'<br/> |
− | 'alias' => 'alias', | + | 'alias' => 'alias',<br/> |
− | 'alias_domain' => 'alias_domain', | + | 'alias_domain' => 'alias_domain',<br/> |
− | 'config' => 'config', | + | 'config' => 'config',<br/> |
− | 'domain' => 'domain', | + | 'domain' => 'domain',<br/> |
− | 'domain_admins' => 'domain_admins', | + | 'domain_admins' => 'domain_admins',<br/> |
− | 'fetchmail' => 'fetchmail', | + | 'fetchmail' => 'fetchmail',<br/> |
− | 'log' => 'log', | + | 'log' => 'log',<br/> |
− | 'mailbox' => 'mailbox', | + | 'mailbox' => 'mailbox',<br/> |
− | 'vacation' => 'vacation', | + | 'vacation' => 'vacation',<br/> |
− | 'vacation_notification' => 'vacation_notification', | + | 'vacation_notification' => 'vacation_notification',<br/> |
− | 'quota' => 'quota', | + | 'quota' => 'quota',<br/> |
− | 'quota2' => 'quota2', | + | 'quota2' => 'quota2',<br/> |
); | ); | ||
Строка 226: | Строка 229: | ||
// If a $PALANG text contains a %s, you can add its value after the $PALANG key<br/> | // If a $PALANG text contains a %s, you can add its value after the $PALANG key<br/> | ||
// (separated with a space).<br/> | // (separated with a space).<br/> | ||
− | $CONF['password_validation'] = array( | + | $CONF['password_validation'] = array(<br/> |
− | + | '/.{5}/' => 'password_too_short 5', # minimum length 5 characters<br/> | |
− | + | '/([a-zA-Z].*){3}/' => 'password_no_characters 3', # must contain at least 3 characters<br/> | |
− | + | '/([0-9].*){2}/' => 'password_no_digits 2', # must contain at least 2 digits<br/> | |
− | |||
); | ); | ||
− | // Generate Password<br/> | + | // Generate Password<br/><br/> |
$CONF['generate_password'] = 'NO'; | $CONF['generate_password'] = 'NO'; | ||
− | // Show Password<br/> | + | // Show Password<br/><br/> |
$CONF['show_password'] = 'NO'; | $CONF['show_password'] = 'NO'; | ||
// Page Size<br/> | // Page Size<br/> | ||
− | // Set the number of entries that you would like to see | + | // Set the number of entries that you would like to see in one page.<br/> |
− | |||
$CONF['page_size'] = '50'; | $CONF['page_size'] = '50'; | ||
// Default Aliases<br/> | // Default Aliases<br/> | ||
− | //$CONF['default_aliases'] = array ( | + | //$CONF['default_aliases'] = array (<br/> |
− | + | 'abuse' => 'postmaster',<br/> | |
− | // 'hostmaster' => 'hostmaster@change-this-to-your.domain.tld', | + | // 'hostmaster' => 'hostmaster@change-this-to-your.domain.tld',<br/> |
− | // 'postmaster' => 'postmaster@change-this-to-your.domain.tld', | + | // 'postmaster' => 'postmaster@change-this-to-your.domain.tld',<br/> |
− | // 'webmaster' => 'webmaster@change-this-to-your.domain.tld' | + | // 'webmaster' => 'webmaster@change-this-to-your.domain.tld'<br/> |
− | + | ); | |
Строка 283: | Строка 284: | ||
$CONF['aliases'] = '0';<br/> | $CONF['aliases'] = '0';<br/> | ||
$CONF['mailboxes'] = '0';<br/> | $CONF['mailboxes'] = '0';<br/> | ||
− | $CONF['maxquota'] = ' | + | $CONF['maxquota'] = '0';<br/> |
− | $CONF['domain_quota_default'] = ' | + | $CONF['domain_quota_default'] = '0'; |
Строка 301: | Строка 302: | ||
// Transport options<br/> | // Transport options<br/> | ||
// If you want to define additional transport options put them in array below.<br/> | // If you want to define additional transport options put them in array below.<br/> | ||
− | $CONF['transport_options'] = array ( | + | $CONF['transport_options'] = array (<br/> |
− | + | 'virtual', // for virtual accounts<br/> | |
− | + | 'local', // for system accounts<br/> | |
− | + | 'relay' // for backup mx<br/> | |
− | ); | + | );<br/> |
// Transport default<br/> | // Transport default<br/> | ||
// You should define default transport. It must be in array above.<br/> | // You should define default transport. It must be in array above.<br/> | ||
Строка 340: | Строка 341: | ||
// 0 => only reply to the first mail while on vacation<br/> | // 0 => only reply to the first mail while on vacation<br/> | ||
// 1 => reply on every mail<br/> | // 1 => reply on every mail<br/> | ||
− | $CONF['vacation_choice_of_reply'] = array ( | + | $CONF['vacation_choice_of_reply'] = array (<br/> |
− | + | 0 => 'reply_once', // Sends only Once the message during Out of Office<br/> | |
− | + | 60*60 *24*7 => 'reply_once_per_week' // Reply if last autoreply was at least a week ago<br/> | |
− | + | );<br/> | |
− | |||
− | ); | ||
// End Vacation Stuff. | // End Vacation Stuff. | ||
Строка 394: | Строка 393: | ||
// Send Mail<br/> | // Send Mail<br/> | ||
// If you don't want sendmail tab set this to 'NO';<br/> | // If you don't want sendmail tab set this to 'NO';<br/> | ||
− | $CONF['sendmail'] = 'YES'; | + | //$CONF['sendmail'] = 'YES'; |
Строка 492: | Строка 491: | ||
// Optional:<br/> | // Optional:<br/> | ||
// Script to run after creation of domains.<br/> | // Script to run after creation of domains.<br/> | ||
− | $CONF['domain_postcreation_script'] = ''; | + | $CONF['domain_postcreation_script'] = '/usr/local/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'] = ''; | + | $CONF['domain_postdeletion_script'] = '/usr/local/www/postfix/scripts/domaindel.sh'; |
Строка 549: | Строка 548: | ||
// file (config.local.php) instead of editing this file and override some<br/> | // file (config.local.php) instead of editing this file and override some<br/> | ||
// settings there.<br/> | // settings there.<br/> | ||
− | if (file_exists(dirname(__FILE__) . '/config.local.php')) { | + | if (file_exists(dirname(__FILE__) . '/config.local.php')) {<br/> |
− | + | include(dirname(__FILE__) . '/config.local.php');<br/> | |
− | } | + | }<br/> |
// END OF CONFIG FILE | // END OF CONFIG FILE | ||
</spoiler> | </spoiler> | ||
+ | |||
+ | Выставляем права | ||
+ | # chown -R www:www /usr/local/www/postfix | ||
+ | |||
+ | |||
+ | Теперь заходим на http://postfixadmin/setup.php и видим, что запустилась установка<br/> | ||
+ | Если все условия установки выполнены, то в базе создадутся необходимые таблицы и будет предложено создать суперадмина. | ||
+ | |||
+ | В поле ''Setup password'' вводим пароль из config.inc.php: $CONF['setup_password'] = 'пароль_установки';<br/> | ||
+ | Заполняем остальные поля, и после нажатия кнопки ''Создать'' сгенерится хэш. | ||
+ | |||
+ | Этот хеш надо вставить в config.inc.php вместо пароля установки: $CONF['setup_password'] = 'хеш';<br/> | ||
+ | Повторяем процедуру заведения суперадмина используя пароль_установки | ||
+ | |||
+ | После создания суперадмина временно оставляем PostfixAdmin(так как без postfix и dovecot ящики создаваться не будут) | ||
+ | |||
+ | |||
+ | '''4. Установка Postfix''' | ||
+ | |||
+ | Postfix ставим из портов, т.к. пакет ставится без поддержки mysql<br/> | ||
+ | # 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/> | ||
+ | первый <code>/usr/local/etс/postfix/main.cf</code><br/> | ||
+ | <spoiler> | ||
+ | biff=no<br/> | ||
+ | smtpd_banner = $myhostname ESMTP<br/> | ||
+ | queue_directory = /var/spool/postfix<br/> | ||
+ | command_directory = /usr/local/sbin<br/> | ||
+ | daemon_directory = /usr/local/libexec/postfix<br/> | ||
+ | data_directory = /var/db/postfix<br/> | ||
+ | |||
+ | mail_owner = postfix<br/> | ||
+ | append_dot_mydomain = no<br/> | ||
+ | recipient_delimiter = +<br/> | ||
+ | default_destination_recipient_limit = 1<br/> | ||
+ | mailbox_size_limit = 0<br/> | ||
+ | message_size_limit = 20480000<br/> | ||
+ | |||
+ | inet_protocols = ipv4<br/> | ||
+ | inet_interfaces = all | ||
+ | |||
+ | myhostname = mail.megapuper.ru<br/> | ||
+ | mydomain = megapuper.ru<br/> | ||
+ | myorigin = $mydomain<br/> | ||
+ | mydestination = localhost.$mydomain, localhost<br/> | ||
+ | mynetworks = 127.0.0.0/8, 192.168.0.0/24 | ||
+ | |||
+ | alias_maps = hash:/etc/aliases<br/> | ||
+ | alias_database = hash:/etc/aliases<br/> | ||
+ | smtp_generic_maps = hash:/usr/local/etc/postfix/aliases_smtp_output<br/> | ||
+ | lmtp_generic_maps = hash:/usr/local/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/> | ||
+ | virtual_mailbox_domains = mysql:/usr/local/etc/postfix/maps/mysql_virtual_domains.cf<br/> | ||
+ | virtual_mailbox_maps = mysql:/usr/local/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_transport = lmtp:unix:private/dovecot-lmtp | ||
+ | |||
+ | strict_rfc821_envelopes = yes | ||
+ | |||
+ | mail_spool_directory = /var/spool/mail | ||
+ | |||
+ | smtpd_helo_required = yes | ||
+ | |||
+ | delay_notice_recipient = postmaster@megapuper.ru<br/> | ||
+ | bounce_notice_recipient = postmaster@megapuper.ru<br/> | ||
+ | 2bounce_notice_recipient = postmaster@megapuper.ru<br/> | ||
+ | error_notice_recipient = postmaster@megapuper.ru | ||
+ | |||
+ | debug_peer_level = 2<br/> | ||
+ | debugger_command =<br/> | ||
+ | PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin<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/> | ||
+ | sample_directory = /usr/local/etc/postfix | ||
+ | </spoiler> | ||
+ | |||
+ | |||
+ | второй конфиг<code>/usr/local/etс/postfix/master.cf</code>оставляем дефолтным<br/> | ||
+ | <spoiler> | ||
+ | # ========================================================================== | ||
+ | # service type private unpriv chroot wakeup maxproc command + args | ||
+ | # (yes) (yes) (yes) (never) (100) | ||
+ | # ========================================================================== | ||
+ | smtp inet n - n - - smtpd | ||
+ | #smtp inet n - n - 1 postscreen | ||
+ | #smtpd pass - - n - - smtpd | ||
+ | #dnsblog unix - - n - 0 dnsblog | ||
+ | #tlsproxy unix - - n - 0 tlsproxy | ||
+ | #submission inet n - n - - smtpd | ||
+ | # -o syslog_name=postfix/submission | ||
+ | # -o smtpd_tls_security_level=encrypt | ||
+ | # -o smtpd_sasl_auth_enable=yes | ||
+ | # -o smtpd_reject_unlisted_recipient=no | ||
+ | # -o smtpd_client_restrictions=$mua_client_restrictions | ||
+ | # -o smtpd_helo_restrictions=$mua_helo_restrictions | ||
+ | # -o smtpd_sender_restrictions=$mua_sender_restrictions | ||
+ | # -o smtpd_recipient_restrictions= | ||
+ | # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject | ||
+ | # -o milter_macro_daemon_name=ORIGINATING | ||
+ | #smtps inet n - n - - smtpd | ||
+ | # -o syslog_name=postfix/smtps | ||
+ | # -o smtpd_tls_wrappermode=yes | ||
+ | # -o smtpd_sasl_auth_enable=yes | ||
+ | # -o smtpd_reject_unlisted_recipient=no | ||
+ | # -o smtpd_client_restrictions=$mua_client_restrictions | ||
+ | # -o smtpd_helo_restrictions=$mua_helo_restrictions | ||
+ | # -o smtpd_sender_restrictions=$mua_sender_restrictions | ||
+ | # -o smtpd_recipient_restrictions= | ||
+ | # -o smtpd_relay_restrictions=permit_sasl_authenticated,reject | ||
+ | # -o milter_macro_daemon_name=ORIGINATING | ||
+ | #628 inet n - n - - qmqpd | ||
+ | pickup unix n - n 60 1 pickup | ||
+ | cleanup unix n - n - 0 cleanup | ||
+ | qmgr unix n - n 300 1 qmgr | ||
+ | tlsmgr unix - - n 1000? 1 tlsmgr | ||
+ | rewrite unix - - n - - trivial-rewrite | ||
+ | bounce unix - - n - 0 bounce | ||
+ | defer unix - - n - 0 bounce | ||
+ | trace unix - - n - 0 bounce | ||
+ | verify unix - - n - 1 verify | ||
+ | flush unix n - n 1000? 0 flush | ||
+ | proxymap unix - - n - - proxymap | ||
+ | proxywrite unix - - n - 1 proxymap | ||
+ | smtp unix - - n - - smtp | ||
+ | relay unix - - n - - smtp | ||
+ | # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 | ||
+ | showq unix n - n - - showq | ||
+ | error unix - - n - - error | ||
+ | retry unix - - n - - error | ||
+ | discard unix - - n - - discard | ||
+ | local unix - n n - - local | ||
+ | virtual unix - n n - - virtual | ||
+ | lmtp unix - - n - - lmtp | ||
+ | anvil unix - - n - 1 anvil | ||
+ | scache unix - - n - 1 scache | ||
+ | # ==================================================================== | ||
+ | # Interfaces to non-Postfix software. | ||
+ | # ==================================================================== | ||
+ | #maildrop unix - n n - - pipe | ||
+ | # flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} | ||
+ | # ============================ ======================================= | ||
+ | # Recent Cyrus versions can use the existing "lmtp" master.cf entry. | ||
+ | # | ||
+ | # Specify in cyrus.conf: | ||
+ | # lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 | ||
+ | # | ||
+ | # Specify in main.cf one or more of the following: | ||
+ | # mailbox_transport = lmtp:inet:localhost | ||
+ | # virtual_transport = lmtp:inet:localhost | ||
+ | # | ||
+ | # ==================================================================== | ||
+ | # | ||
+ | # Cyrus 2.1.5 (Amos Gouaux) | ||
+ | # Also specify in main.cf: cyrus_destination_recipient_limit=1 | ||
+ | # | ||
+ | # cyrus unix - n n - - pipe | ||
+ | # user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} | ||
+ | # | ||
+ | # ==================================================================== | ||
+ | # | ||
+ | # Old example of delivery via Cyrus. | ||
+ | # | ||
+ | #old-cyrus unix - n n - - pipe | ||
+ | # flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} | ||
+ | # | ||
+ | # ==================================================================== | ||
+ | # | ||
+ | # See the Postfix UUCP_README file for configuration details. | ||
+ | # | ||
+ | #uucp unix - n n - - pipe | ||
+ | # flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) | ||
+ | # | ||
+ | # ==================================================================== | ||
+ | # | ||
+ | # Other external delivery methods. | ||
+ | # | ||
+ | #ifmail unix - n n - - pipe | ||
+ | # flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) | ||
+ | # | ||
+ | #bsmtp unix - n n - - pipe | ||
+ | # flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient | ||
+ | # | ||
+ | # scalemail-backend unix - n n - 2 pipe | ||
+ | # flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store | ||
+ | # ${nexthop} ${user} ${extension} | ||
+ | # | ||
+ | #mailman unix - n n - - pipe | ||
+ | # flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py | ||
+ | # ${nexthop} ${user} | ||
+ | </spoiler> | ||
+ | |||
+ | Создаём таблицы данных формата "hash" и базы с помощью команды '''postmap'''<br/> | ||
+ | <font color=red>'''Необходимо создать файлы и базы со списками, которые были подключены в конфиге выше, даже если они будут пустыми'''</font> | ||
+ | # touch aliases_lmtp | ||
+ | # touch aliases_smtp_output | ||
+ | # postmap aliases_lmtp | ||
+ | # postmap aliases_smtp_output | ||
+ | |||
+ | |||
+ | Создаём файлы, хранящие SQL-запросы, проверяя имена таблиц и полей (<font color=red>в очередной версии PostfixAdmin они могут измениться</font>) | ||
+ | [/usr/local/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' | ||
+ | |||
+ | [/usr/local/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' | ||
+ | |||
+ | [/usr/local/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' | ||
+ | |||
+ | [/usr/local/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 | ||
+ | |||
+ | |||
+ | Следующие два необязательны, если не будем делать сохранение копий всех писем | ||
+ | [/usr/local/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' | ||
+ | |||
+ | [/usr/local/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 /usr/local/etc/postfix/*.cf | ||
+ | # chgrp postfix /usr/local/etc/postfix/maps/*.cf | ||
+ | # chmod u=rw,g=r,o=r /usr/local/etc/postfix/*.cf | ||
+ | # chmod u=rw,g=r,o=r /usr/local/etc/postfix/maps/*.cf | ||
+ | |||
+ | |||
+ | Рестартим postfix | ||
+ | # /usr/local/etc/rc.d/postfix restart | ||
+ | |||
+ | |||
+ | '''5. Установка Dovecot'''<br/><br/> | ||
+ | Dovecot ставим из портов<br/> | ||
+ | # cd /usr/ports/mail/dovecot2/ | ||
+ | # make install clean | ||
+ | [X] MYSQL | ||
+ | |||
+ | |||
+ | Устанавливаем поддержку языка Sieve в Dovecot(включает в себя настройку скриптов пользователями) | ||
+ | # cd /usr/ports/mail/dovecot2-pigeonhole | ||
+ | # make install clean | ||
+ | |||
+ | |||
+ | Создаём сопутствуюшие папки | ||
+ | # mkdir /var/log/dovecot | ||
+ | # mkdir -p /var/lib/dovecot/sieve/global/ | ||
+ | # mkdir -p /var/lib/dovecot/sieve/private/ | ||
+ | |||
+ | |||
+ | Выставляем права | ||
+ | # chown -R mail:wheel /var/lib/dovecot/sieve/private/ | ||
+ | # chmod -R 700 /var/lib/dovecot/sieve/private/ | ||
+ | |||
+ | |||
+ | Правим конфиги dovecot | ||
+ | [/usr/local/etc/dovecot/dovecot.conf] | ||
+ | |||
+ | # Enable installed protocols | ||
+ | protocols = imap lmtp sieve | ||
+ | dict { | ||
+ | #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext | ||
+ | #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext | ||
+ | } | ||
+ | !include conf.d/*.conf | ||
+ | |||
+ | |||
+ | [/usr/local/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, 1000 AS userdb_uid, 1000 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, 1000 AS uid, 1000 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] | ||
+ | |||
+ | 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' | ||
+ | |||
+ | |||
+ | [/usr/local/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 | ||
+ | |||
+ | |||
+ | [/usr/local/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 | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/local/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: %$ | ||
+ | |||
+ | |||
+ | [/usr/local/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 = 1000 | ||
+ | mail_gid = 1000 | ||
+ | |||
+ | |||
+ | [/usr/local/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 pop3-login { | ||
+ | #inet_listener pop3 { | ||
+ | #port = 110 | ||
+ | #} | ||
+ | #inet_listener pop3s { | ||
+ | #port = 995 | ||
+ | #ssl = yes | ||
+ | #} | ||
+ | #} | ||
+ | |||
+ | service lmtp { | ||
+ | unix_listener lmtp { | ||
+ | path = /var/spool/postfix/private/dovecot-lmtp | ||
+ | group = postfix | ||
+ | mode = 0660 | ||
+ | user = postfix | ||
+ | #mode = 0666 | ||
+ | } | ||
+ | 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 { | ||
+ | unix_listener auth { | ||
+ | path = /var/spool/postfix/private/auth | ||
+ | mode = 0660 | ||
+ | user = postfix | ||
+ | group = postfix | ||
+ | } | ||
+ | user = $default_internal_user | ||
+ | } | ||
+ | |||
+ | service auth-worker { | ||
+ | user = $default_internal_user | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/loca/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 | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/local/etc/dovecot/conf.d/20-imap.conf] | ||
+ | |||
+ | protocol imap { | ||
+ | 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 | ||
+ | mail_max_userip_connections = 100 | ||
+ | # IMAP logout format string: | ||
+ | # %i - total number of bytes read from client | ||
+ | # %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] | ||
+ | |||
+ | protocol lmtp { | ||
+ | mail_plugins = $mail_plugins quota sieve | ||
+ | postmaster_address = postmaster@megapuper.ru | ||
+ | info_log_path = /var/log/dovecot/dovecot-lmtp.log | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/local/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 | ||
+ | #} | ||
+ | |||
+ | |||
+ | [/usr/local/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 | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/local/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 | ||
+ | } | ||
+ | |||
+ | |||
+ | [/usr/local/etc/dovecot/conf.d/auth-sql.conf.ext] | ||
+ | |||
+ | auth_master_user_separator = * | ||
+ | #auth_debug = yes | ||
+ | passdb { | ||
+ | driver = sql | ||
+ | args = /usr/local/etc/dovecot/dovecot-sql-master.conf.ext | ||
+ | master = yes | ||
+ | pass = yes | ||
+ | } | ||
+ | passdb { | ||
+ | driver = sql | ||
+ | args = /usr/local/etc/dovecot/dovecot-sql.conf.ext | ||
+ | #default_fields = userdb_gid=1000 userdb_uid=1000 | ||
+ | } | ||
+ | userdb { | ||
+ | driver = prefetch | ||
+ | } | ||
+ | userdb { | ||
+ | driver = sql | ||
+ | args = /usr/local/etc/dovecot/dovecot-sql.conf.ext | ||
+ | #default_fields = uid=1000 gid=1000 | ||
+ | } | ||
+ | |||
+ | |||
+ | Меняем права и владельца конфигов: | ||
+ | # chgrp mail /usr/local/etc/dovecot/*.conf | ||
+ | # chmod g+r /usr/local/etc/dovecot/*.conf | ||
+ | # chgrp mail /usr/local/etc/dovecot/*.ext | ||
+ | # chmod g+r /usr/local/etc/dovecot/*.ext | ||
+ | # chgrp mail /usr/local/etc/dovecot/conf.d/*.conf | ||
+ | # chmod g+r /usr/local/etc/dovecot/conf.d/*.conf | ||
+ | # chgrp mail /usr/local/etc/dovecot/conf.d/*.ext | ||
+ | # chmod g+r /usr/local/etc/dovecot/conf.d/*.ext | ||
+ | |||
+ | |||
+ | Теперь можно вернуться к PostfixAdmin и приступить к созданию доменов и ящиков | ||
+ | |||
+ | Папка для логов | ||
+ | # mkdir /var/log/postfixadmin | ||
+ | # chown www:www /var/log/postfixadmin | ||
+ | |||
+ | |||
+ | Копируем скрипты в /usr/local/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:www /usr/local/www/postfix/scripts/ | ||
+ | # chmod 744 addmail.sh delmail.sh domainadd.sh domaindel.sh editmail.sh | ||
+ | |||
+ | |||
+ | Создаём папку для почты | ||
+ | # mkdir /var/spool/mail | ||
+ | # chown -R mail:mail /var/spool/mail | ||
+ | |||
+ | |||
+ | Рестартим postfix и dovecot | ||
+ | |||
+ | Создаём в postfixadmin домен и ящики, проверяем хождение почты. | ||
+ | |||
+ | Удаляем setup.php | ||
+ | |||
+ | |||
+ | '''6. Roundcube'''<br/> | ||
+ | |||
+ | [https://roundcube.net/download/ Качаем отсюда нужную версию] и распаковываем её в папку на веб-сервере | ||
+ | |||
+ | |||
+ | Примерный конфиг nginx | ||
+ | server { | ||
+ | listen 80; | ||
+ | server_name webmail.megapuper.ru; | ||
+ | |||
+ | root /usr/local/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:10002; | ||
+ | fastcgi_index index.php; | ||
+ | fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; | ||
+ | fastcgi_intercept_errors on; | ||
+ | include fastcgi_params; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | Конфиг php | ||
+ | [roundcube] | ||
+ | prefix = /usr/local/www/$pool | ||
+ | listen = 127.0.0.1:10002 | ||
+ | listen.allowed_clients = 127.0.0.1 | ||
+ | listen.owner = www | ||
+ | listen.group = www | ||
+ | listen.mode = 0660 | ||
+ | user = www | ||
+ | group = www | ||
+ | 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 '<font color=blue>ПАРОЛЬ</font>'; | ||
+ | |||
+ | |||
+ | Заходим http://webmail.megapuper.ru/installer/ и далее по тексту | ||
+ | |||
+ | |||
+ | '''7. SPF'''<br/> | ||
+ | |||
+ | 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-записи. | ||
+ | |||
+ | |||
+ | Отправляем письмо на какую-нибудь гуглопочту и проверяем<br/> | ||
+ | При просмотре оригинала письма с заголовками у получателя, увидим такие строчки | ||
+ | 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'''<br/> | ||
+ | |||
+ | DKIM - цифровая подпись, которая добавляется к заголовкам письма сервером отправителя, по которой сервер получателя может удостовериться, что отправитель письма соответствует полю From в заголовках письма. | ||
+ | |||
+ | Ставим из пакетов | ||
+ | # pkg install opendkim | ||
+ | |||
+ | |||
+ | Заводим пользователя | ||
+ | # pw useradd -n opendkim -d /home/opendkim -g mail -m -s "/usr/sbin/nologin" -w no | ||
+ | |||
+ | |||
+ | Создаём папку для конфига и прочего | ||
+ | # mkdir /usr/local/etc/opendkim/ | ||
+ | |||
+ | |||
+ | Подготавливаем конфиг <code>/usr/local/etc/opendkim/opendkim.conf</code> | ||
+ | Socket inet:8891@localhost | ||
+ | Syslog yes | ||
+ | SyslogSuccess yes | ||
+ | LogWhy yes | ||
+ | X-Header yes | ||
+ | Canonicalization relaxed/relaxed | ||
+ | # подпись и проверка подписей | ||
+ | #Mode sv | ||
+ | # если только подписываем | ||
+ | Mode s | ||
+ | # список ключей | ||
+ | KeyTable file:/usr/local/etc/opendkim/keytable | ||
+ | |||
+ | # соответствие адресов/доменов и ключей | ||
+ | SigningTable file:/usr/local/etc/opendkim/signingtable | ||
+ | # если вы подписываем и на других серверах | ||
+ | #ExternalIgnoreList file:/usr/local/etc/opendkim/trusted | ||
+ | # список внутренних хостов, почта которых требует подписи | ||
+ | InternalHosts file:/usr/local/etc/opendkim/internal | ||
+ | |||
+ | |||
+ | Генерируем ключ | ||
+ | # opendkim-genkey -D /usr/local/etc/opendkim/ -d megapuper.ru -s megapuper | ||
+ | |||
+ | |||
+ | Прописываем ключ в <code>/usr/local/etc/opendkim/keytable</code> | ||
+ | megapuper._domainkey.megapuper.ru megapuper.ru:megapuper:/usr/local/etc/opendkim/megapuper.private | ||
+ | |||
+ | |||
+ | Соответствие адреса и ключа <code>/usr/local/etc/opendkim/signingtable</code> | ||
+ | megapuper.ru megapuper._domainkey.megapuper.ru | ||
+ | |||
+ | |||
+ | Список хостов, почта которых требует подписи <code>/usr/local/etc/opendkim/internal</code> | ||
+ | 108.195.52.173 | ||
+ | 32.210.209.35 | ||
+ | 192.168.0.7 | ||
+ | 192.168.100.120 | ||
+ | |||
+ | |||
+ | Выставляем права | ||
+ | # chown -R opendkim:mail /usr/local/etc/opendkim/ | ||
+ | |||
+ | |||
+ | Подключаем в postfix <code>/usr/local/etc/postfix/main.cf</code> | ||
+ | milter_default_action = accept | ||
+ | smtpd_milters = inet:localhost:8891 | ||
+ | non_smtpd_milters = inet:localhost:8891 | ||
+ | |||
+ | |||
+ | Добавляем в <code>/etc/rc.conf</code> | ||
+ | milteropendkim_enable="YES" | ||
+ | milteropendkim_uid="opendkim" | ||
+ | |||
+ | |||
+ | Прописываем в 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 /usr/local/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 | ||
+ | |||
+ | |||
+ | Далее стартуем/рестартуем сервисы | ||
+ | # /usr/local/etc/rc.d/milter-opendkim start | ||
+ | # /usr/local/etc/rc.d/postfix start | ||
+ | |||
+ | |||
+ | Потому как путь к конфигу поменяли относительно дефолтного, пришлось поправить скрипт запуска <code>/usr/local/etc/rc.d/milter-opendkim</code> | ||
+ | : ${milteropendkim_cfgfile="/usr/local/etc/opendkim/opendkim.conf"} | ||
+ | |||
+ | |||
+ | Снова отправляем письмо на гуглопочту и проверяем<br/> | ||
+ | В логах увидим, что 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/ | ||
+ | |||
+ | |||
+ | '''Пересылка входящей почты на другой ящик'''<br/> | ||
+ | |||
+ | Требуется пересылать входящую почту с ящика test@megapuper.ru на test@mail.ru | ||
+ | Добавляем в <code>/usr/local/etc/postfix/main.cf</code> | ||
+ | recipient_bcc_maps = hash:/usr/local/etc/postfix/recipient_bcc | ||
+ | В этот файл <code>/usr/local/etc/postfix/recipient_bcc</code> прописываем с какого ящика на какой пересылать | ||
+ | test@megapuper.ru test@mail.ru | ||
+ | Выполняем | ||
+ | postmap /usr/local/etc/postfix/recipient_bcc | ||
+ | postfix reload | ||
− | + | Проверяем | |
− | + | Вуаля. Пока всё. |
Текущая версия на 15:38, 23 октября 2017
При установке будем ориентироваться на этот мануал: http://dummyluck.com/page/pochtovyi_server_nastroika_opisanie
Настройку будем производить для сервера с одним доменом. Система FreeBSD 10.2
1. Подготовка
Прописываем хостнейм /etc/rc.conf
hostname="servmp.megapuper.ru"
Делаем изменения в хостах /etc/hosts
127.0.0.1 localhost 109.172.52.114 megapuper.ru 109.172.52.114 mail.megapuper.ru
Создаём пользователя и добавляем его в группу mail
# pw useradd mail -g mail -s /sbin/nologin -u 1000 # pw groupmod mail -m mail
Сразу отключаем sendmail
[etc/rc.conf] sendmail_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" [/etc/periodic.conf] daily_clean_hoststat_enable="NO" daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO"
2. Установка Nginx, MySQL, PHP, PHP-extension. Этот web-сервер будет использоваться для PostfixAdmin
Здесь коротко, ибо уже тыщу раз ставилось)
Nginx cтавим из пакетов
# pkg install nginx
Основной конфиг /usr/local/etc/nginx/nginx.conf
user www; worker_processes 2; pid /var/run/nginx.pid; events { worker_connections 1024; } http { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; include /usr/local/etc/nginx/mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; client_max_body_size 5m; server_names_hash_bucket_size 64; types_hash_max_size 2048; types_hash_bucket_size 64; include /usr/local/etc/nginx/conf.d/*.conf; }
Конфиг виртуального хоста /usr/local/etc/nginx/conf/postfix.conf
server { listen 80; server_name postfix.megapuper.ru; root /usr/local/www/postfix; index index.php index.html index.htm; 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:10000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; fastcgi_intercept_errors on; include fastcgi_params; } }
PHP и нужные PHP-extension тоже ставим из пакетов
# pkg install php55 # 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 /usr/local/etc/php-fpm.conf
[global] error_log = /var/log/php/php-fpm.log pid = /var/run/php-fpm.pid log_level = notice include=/usr/local/etc/php/*.conf
Конфиг для виртуального хоста /usr/local/etc/php/postfix.conf
[postfix] prefix = /usr/local/www/$pool listen = 127.0.0.1:10000 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0660 user = www group = www 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
MySQL тоже из пакетов
# pkg install mysql56-server
Простенький конфиг /etc/my.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:www /usr/local/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
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
первый /usr/local/etс/postfix/main.cf
Spoiler
второй конфиг/usr/local/etс/postfix/master.cf
оставляем дефолтным
Spoiler
Создаём таблицы данных формата "hash" и базы с помощью команды postmap
Необходимо создать файлы и базы со списками, которые были подключены в конфиге выше, даже если они будут пустыми
# touch aliases_lmtp # touch aliases_smtp_output # postmap aliases_lmtp # postmap aliases_smtp_output
Создаём файлы, хранящие SQL-запросы, проверяя имена таблиц и полей (в очередной версии PostfixAdmin они могут измениться)
[/usr/local/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'
[/usr/local/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'
[/usr/local/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'
[/usr/local/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
Следующие два необязательны, если не будем делать сохранение копий всех писем
[/usr/local/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'
[/usr/local/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 /usr/local/etc/postfix/*.cf # chgrp postfix /usr/local/etc/postfix/maps/*.cf # chmod u=rw,g=r,o=r /usr/local/etc/postfix/*.cf # chmod u=rw,g=r,o=r /usr/local/etc/postfix/maps/*.cf
Рестартим postfix
# /usr/local/etc/rc.d/postfix restart
5. Установка Dovecot
Dovecot ставим из портов
# cd /usr/ports/mail/dovecot2/ # make install clean [X] MYSQL
Устанавливаем поддержку языка Sieve в Dovecot(включает в себя настройку скриптов пользователями)
# cd /usr/ports/mail/dovecot2-pigeonhole # make install clean
Создаём сопутствуюшие папки
# mkdir /var/log/dovecot # mkdir -p /var/lib/dovecot/sieve/global/ # mkdir -p /var/lib/dovecot/sieve/private/
Выставляем права
# chown -R mail:wheel /var/lib/dovecot/sieve/private/ # chmod -R 700 /var/lib/dovecot/sieve/private/
Правим конфиги dovecot
[/usr/local/etc/dovecot/dovecot.conf] # Enable installed protocols protocols = imap lmtp sieve dict { #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext } !include conf.d/*.conf
[/usr/local/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, 1000 AS userdb_uid, 1000 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, 1000 AS uid, 1000 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] 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'
[/usr/local/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
[/usr/local/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 }
[/usr/local/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: %$
[/usr/local/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 = 1000 mail_gid = 1000
[/usr/local/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 pop3-login { #inet_listener pop3 { #port = 110 #} #inet_listener pop3s { #port = 995 #ssl = yes #} #} service lmtp { unix_listener lmtp { path = /var/spool/postfix/private/dovecot-lmtp group = postfix mode = 0660 user = postfix #mode = 0666 } 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 { unix_listener auth { path = /var/spool/postfix/private/auth mode = 0660 user = postfix group = postfix } user = $default_internal_user } service auth-worker { user = $default_internal_user }
[/usr/loca/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 }
[/usr/local/etc/dovecot/conf.d/20-imap.conf] protocol imap { 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 mail_max_userip_connections = 100 # IMAP logout format string: # %i - total number of bytes read from client # %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] protocol lmtp { mail_plugins = $mail_plugins quota sieve postmaster_address = postmaster@megapuper.ru info_log_path = /var/log/dovecot/dovecot-lmtp.log }
[/usr/local/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 #}
[/usr/local/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 }
[/usr/local/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 }
[/usr/local/etc/dovecot/conf.d/auth-sql.conf.ext] auth_master_user_separator = * #auth_debug = yes passdb { driver = sql args = /usr/local/etc/dovecot/dovecot-sql-master.conf.ext master = yes pass = yes } passdb { driver = sql args = /usr/local/etc/dovecot/dovecot-sql.conf.ext #default_fields = userdb_gid=1000 userdb_uid=1000 } userdb { driver = prefetch } userdb { driver = sql args = /usr/local/etc/dovecot/dovecot-sql.conf.ext #default_fields = uid=1000 gid=1000 }
Меняем права и владельца конфигов:
# chgrp mail /usr/local/etc/dovecot/*.conf # chmod g+r /usr/local/etc/dovecot/*.conf # chgrp mail /usr/local/etc/dovecot/*.ext # chmod g+r /usr/local/etc/dovecot/*.ext # chgrp mail /usr/local/etc/dovecot/conf.d/*.conf # chmod g+r /usr/local/etc/dovecot/conf.d/*.conf # chgrp mail /usr/local/etc/dovecot/conf.d/*.ext # chmod g+r /usr/local/etc/dovecot/conf.d/*.ext
Теперь можно вернуться к PostfixAdmin и приступить к созданию доменов и ящиков
Папка для логов
# mkdir /var/log/postfixadmin # chown www:www /var/log/postfixadmin
Копируем скрипты в /usr/local/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:www /usr/local/www/postfix/scripts/ # chmod 744 addmail.sh delmail.sh domainadd.sh domaindel.sh editmail.sh
Создаём папку для почты
# mkdir /var/spool/mail # chown -R mail:mail /var/spool/mail
Рестартим postfix и dovecot
Создаём в postfixadmin домен и ящики, проверяем хождение почты.
Удаляем setup.php
6. Roundcube
Качаем отсюда нужную версию и распаковываем её в папку на веб-сервере
Примерный конфиг nginx
server { listen 80; server_name webmail.megapuper.ru; root /usr/local/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:10002; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; fastcgi_intercept_errors on; include fastcgi_params; } }
Конфиг php
[roundcube] prefix = /usr/local/www/$pool listen = 127.0.0.1:10002 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0660 user = www group = www 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 в заголовках письма.
Ставим из пакетов
# pkg install opendkim
Заводим пользователя
# pw useradd -n opendkim -d /home/opendkim -g mail -m -s "/usr/sbin/nologin" -w no
Создаём папку для конфига и прочего
# mkdir /usr/local/etc/opendkim/
Подготавливаем конфиг /usr/local/etc/opendkim/opendkim.conf
Socket inet:8891@localhost Syslog yes SyslogSuccess yes LogWhy yes X-Header yes Canonicalization relaxed/relaxed # подпись и проверка подписей #Mode sv # если только подписываем Mode s # список ключей KeyTable file:/usr/local/etc/opendkim/keytable # соответствие адресов/доменов и ключей SigningTable file:/usr/local/etc/opendkim/signingtable # если вы подписываем и на других серверах #ExternalIgnoreList file:/usr/local/etc/opendkim/trusted # список внутренних хостов, почта которых требует подписи InternalHosts file:/usr/local/etc/opendkim/internal
Генерируем ключ
# opendkim-genkey -D /usr/local/etc/opendkim/ -d megapuper.ru -s megapuper
Прописываем ключ в /usr/local/etc/opendkim/keytable
megapuper._domainkey.megapuper.ru megapuper.ru:megapuper:/usr/local/etc/opendkim/megapuper.private
Соответствие адреса и ключа /usr/local/etc/opendkim/signingtable
megapuper.ru megapuper._domainkey.megapuper.ru
Список хостов, почта которых требует подписи /usr/local/etc/opendkim/internal
108.195.52.173 32.210.209.35 192.168.0.7 192.168.100.120
Выставляем права
# chown -R opendkim:mail /usr/local/etc/opendkim/
Подключаем в postfix /usr/local/etc/postfix/main.cf
milter_default_action = accept smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
Добавляем в /etc/rc.conf
milteropendkim_enable="YES" milteropendkim_uid="opendkim"
Прописываем в 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 /usr/local/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
Далее стартуем/рестартуем сервисы
# /usr/local/etc/rc.d/milter-opendkim start # /usr/local/etc/rc.d/postfix start
Потому как путь к конфигу поменяли относительно дефолтного, пришлось поправить скрипт запуска /usr/local/etc/rc.d/milter-opendkim
: ${milteropendkim_cfgfile="/usr/local/etc/opendkim/opendkim.conf"}
Снова отправляем письмо на гуглопочту и проверяем
В логах увидим, что 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
Добавляем в /usr/local/etc/postfix/main.cf
recipient_bcc_maps = hash:/usr/local/etc/postfix/recipient_bcc
В этот файл /usr/local/etc/postfix/recipient_bcc
прописываем с какого ящика на какой пересылать
test@megapuper.ru test@mail.ru
Выполняем
postmap /usr/local/etc/postfix/recipient_bcc postfix reload
Проверяем
Вуаля. Пока всё.