Quod licet Jovi, nоn licet bovi
====== Создание почтовой системы ======
Цель: многодоменная почтовая система с виртуальными пользователями, серым списком, POP и IMAP4-доступом через StartTLS.\\
Средства: postfix, dovecot, maildrop, mysql, sqlgrey, cyrus-sasl, courier-authlib.
Требования: Gentoo GNU/Linux, прямые руки, морщинистый мозг.
Версии необходимого софта:
dev-db/mariadb-5.5.30
net-mail/dovecot-2.1.15
dev-libs/cyrus-sasl-2.1.25-r4
net-libs/courier-authlib-0.65.0-r3
mail-mta/postfix-2.10.0
mail-filter/maildrop-2.6.0
mail-filter/sqlgrey-1.7.6
Ставим его:
USE="-* server community perl ssl mysql pam maildir sasl authlib tools crypt" emerge -av postfix dovecot maildrop mysql sqlgrey cyrus-sasl courier-authlib sqlgrey
Создаём системного пользователя:
groupadd vmail -g 5000
useradd vmail -u 5000 -g 5000
mkdir /home/vmail
chown vmail:vmail /home/vmail
chmod 700 /home/vmail
Логинимся в MySQL под суперпользователем.
Создаём базы и sql-пользователей:
CREATE DATABASE mail;
GRANT ALL PRIVILEGES ON mail.* TO mail@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE `sqlgrey`;
GRANT ALL ON `sqlgrey`.* TO sqlgrey@localhost IDENTIFIED BY '******';
FLUSH PRIVILEGES;
Логинимся в MySQL под новосозданным пользователем.
Создаём таблицы базы данных:
USE mail;
CREATE TABLE postfix_alias (
id int(11) unsigned NOT NULL auto_increment,
alias varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id));
CREATE TABLE postfix_relocated (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id));
CREATE TABLE postfix_transport (
id int(11) unsigned NOT NULL auto_increment,
domain varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY domain (domain));
CREATE TABLE postfix_users (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
clear varchar(128) NOT NULL default '',
crypt varchar(128) NOT NULL default '',
name tinytext NOT NULL,
uid int(11) unsigned NOT NULL default '1004',
gid int(11) unsigned NOT NULL default '1004',
homedir tinytext NOT NULL,
maildir tinytext NOT NULL,
quota tinytext NOT NULL,
access enum('Y','N') NOT NULL default 'Y',
postfix enum('Y','N') NOT NULL default 'Y',
PRIMARY KEY (id),
UNIQUE KEY email (email));
CREATE TABLE postfix_virtual (
id int(11) unsigned NOT NULL auto_increment,
email varchar(128) NOT NULL default '',
destination varchar(128) NOT NULL default '',
PRIMARY KEY (id));
CREATE TABLE postfix_access (
id int(10) unsigned NOT NULL auto_increment,
source varchar(128) NOT NULL default '',
access varchar(128) NOT NULL default '',
type enum('recipient','sender','client') NOT NULL default 'recipient',
PRIMARY KEY (id));
Раскомментируем в /etc/postfix/master.cf:
maildrop unix - n n - - pipe
flags=R user=vmail argv=/usr/bin/maildrop -d ${recipient}
Пишем в /etc/postfix/main.cf:
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
unknown_local_recipient_reject_code = 550
debug_peer_level = 9
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /etc/postfix
readme_directory = no
inet_protocols = ipv4
home_mailbox = .maildir/
myhostname = mail.zveri.me
mydomain = zveri.me
myorigin = $mydomain
mydestination = zveri.me, $transport_maps
local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname
home_mailbox = Maildir/
smtpd_client_restrictions = check_client_access mysql:/etc/postfix/mysql-client.cf
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_helo_restrictions = reject_invalid_hostname, permit
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks, reject_unauth_destination,
permit_mynetworks, permit_sasl_authenticated,
check_recipient_access mysql:/etc/postfix/mysql-recipient.cf,
reject_unauth_destination,
check_policy_service inet:127.0.0.1:2501,
permit
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_path = smtpd
smtpd_sasl_security_options = noanonymous
smtpd_sender_restrictions = check_sender_access mysql:/etc/postfix/mysql-sender.cf
smtpd_tls_auth_only = no
smtpd_tls_cert_file = /etc/ssl/postfix/postfix.crt
smtpd_tls_key_file = /etc/ssl/postfix/postfix.key
smtpd_use_tls = yes
broken_sasl_auth_clients = yes
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
relocated_maps = mysql:/etc/postfix/mysql-relocated.cf
transport_maps = mysql:/etc/postfix/mysql-transport.cf
virtual_maps = mysql:/etc/postfix/mysql-virtual.cf
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_uid_maps = mysql:/etc/postfix/mysql-virtual-uid.cf
virtual_gid_maps = mysql:/etc/postfix/mysql-virtual-gid.cf
message_size_limit = 20480000
maildrop_destination_recipient_limit = 1
Не забываем сменить домен с zveri.me на свой ;)\\
Создаём в /etc/postfix/ следующие файлы с содержимым:
# mysql-aliases.cf
user = mail
password = password
dbname = mail
table = postfix_alias
select_field = destination
where_field = alias
hosts = localhost
# mysql-relocated.cf
user = mail
password = password
dbname = mail
table = postfix_relocated
select_field = destination
where_field = email
hosts = localhost
# mysql-transport.cf
user = mail
password = password
dbname = mail
table = postfix_transport
select_field = destination
where_field = domain
hosts = localhost
# mysql-virtual.cf
user = mail
password = password
dbname = mail
table = postfix_virtual
select_field = destination
where_field = email
hosts = localhost
# mysql-recipient.cf
user = mail
password = password
dbname = mail
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'recipient'
hosts = localhost
# mysql-sender.cf
user = mail
password = password
dbname = mail
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'sender'
hosts = localhost
# mysql-client.cf
user = mail
password = password
dbname = mail
table = postfix_access
select_field = access
where_field = source
additional_conditions = and type = 'client'
hosts = localhost
# mysql-virtual-maps.cf
user = mail
password = password
dbname = mail
table = postfix_users
select_field = maildir
where_field = email
additional_conditions = and postfix = 'y'
hosts = localhost
# mysql-virtual-uid.cf
user = mail
password = password
dbname = mail
table = postfix_users
select_field = uid
where_field = email
additional_conditions = and postfix = 'y'
hosts = localhost
# mysql-virtual-gid.cf
user = mail
password = password
dbname = mail
table = postfix_users
select_field = gid
where_field = email
additional_conditions = and postfix = 'y'
hosts = localhost
Создаём файл /etc/dovecot/dovecot.conf:
protocols = imap pop3
listen = *
shutdown_clients = yes
mail_uid = vmail
mail_gid = vmail
first_valid_uid = 5000
last_valid_uid = 5000
log_path = /var/log/dovecot.log
mail_debug = no
auth_verbose = no
auth_debug = no
auth_debug_passwords = no
ssl = yes
ssl_cert =
Создаём файл /etc/dovecot/dovecot-mysql.conf:
driver = mysql
connect = host=localhost dbname=mail user=mail password=password
default_pass_scheme = PLAIN
password_query = SELECT email AS user, substring_index(substring_index(email,'@',-1),' ',1) AS domain, clear AS password FROM postfix_users WHERE email = '%n@%d' AND access='Y';
user_query = SELECT CONCAT ( substring_index(substring_index(email,'@',1),' ',-1), '@', substring_index(substring_index(email,'@',-1),' ',1) ) AS user, '5000' AS uid, '5000' AS gid FROM postfix_users WHERE substring_index(substring_index(email,'@',1),' ',-1) = '%n' AND substring_index(substring_index(email,'@',-1),' ',1) = '%d' AND access='Y';
Создаём файл /etc/courier/authlib/authdaemonrc:
authmodulelist="authmysql authshadow"
authmodulelistorig="authuserdb authpwd authshadow authmysql authcustom authpipe"
daemons=5
authdaemonvar=/var/lib/courier/authdaemon
DEBUG_LOGIN=0
DEFAULTOPTIONS=""
LOGGEROPTS="-facility=mail"
Создаём файл /etc/courier/authlib/authmysqlrc:
MYSQL_SERVER localhost
MYSQL_USERNAME mail
MYSQL_PASSWORD password
MYSQL_PORT 3306
MYSQL_OPT 0
MYSQL_DATABASE mail
MYSQL_USER_TABLE postfix_users
MYSQL_LOGIN_FIELD email
MYSQL_CRYPT_PWFIELD crypt
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_HOME_FIELD homedir
MYSQL_MAILDIR_FIELD maildir
MYSQL_WHERE_CLAUSE access='Y'
Создаём файл /etc/maildropmysql.config:
hostname localhost
port 3306
database mail
dbuser mail
dbpw password
dbtable postfix_users
default_uidnumber 5000
default_gidnumber 5000
uid_field email
uidnumber_field uid
gidnumber_field gid
maildir_field maildir
homedirectory_field homedir
quota_field quota
# unused for now, but needs to be a valid field.
mailstatus_field postfix
where_clause AND postfix = 'y'
Создаём файл /etc/maildroprc:
`test -d $HOME/$DEFAULT`
if ( $RETURNCODE == 1 )
{
`mkdir -p $HOME/$DEFAULT`
`rm -rf $HOME/$DEFAULT`
`/usr/bin/maildirmake $HOME/$DEFAULT`
`/usr/bin/maildirmake $HOME/$DEFAULT/.Spam/`
`/usr/bin/maildirmake $HOME/$DEFAULT/.Spam/.New`
}
SHELL="/bin/bash"
`/usr/bin/reformail -D 16000 $HOME/$DEFAULT/duplicate.cache`
if ( $RETURNCODE == 0 )
exit
Создаём файл /etc/sasl2/smtpd.conf: ВНИМАНИЕ ! ! ! В первых двух строчках может быть ошибка.
pwcheck_method: saslauthd
pwcheck_method: authdaemond
log_level: 9
mech_list: PLAIN LOGIN
authdaemond_path:/var/lib/courier/authdaemon/socket
Не забываем назначить безопасные права доступа на файлы, содержащие пароли к базе данных (750).
Заходим в sql под пользователем почтовой системы, заходив в базу данных и добавляем домен:
insert into postfix_transport (id, domain, destination) VALUE ("1", "zveri.me", "maildrop: ");
и почтового пользователя:
insert into postfix_users (email, clear, uid, gid, homedir, maildir, access, postfix) values ('testuser@zveri.me', 'userpassword', '5000', '5000', '/home/vmail', 'zveri.me/testuser/Maildir/', 'Y', 'Y');
Правим файл /etc/sqlgrey/sqlgrey.conf:
conf_dir = /etc/sqlgrey
loglevel = 2
user = sqlgrey
group = sqlgrey
inet = 127.0.0.1:2501
pidfile = /var/run/sqlgrey.pid
confdir = /etc/sqlgrey
reconnect_delay = 5
max_connect_age = 24
awl_age = 60
group_domain_level = 100
db_type = mysql
db_name = sqlgrey
db_host = localhost
db_port = default
db_user = sqlgrey
db_pass = ******
db_cleandelay = 32140800
clean_method = sync
prepend = 1
greymethod = smart
optmethod = none
discrimination = off
reject_first_attempt = delay
reject_early_reconnect = delay
admin_mail = ******
Запускаем демоны:
/etc/init.d/saslauthd restart
/etc/init.d/pwcheck start
/etc/init.d/courier-authlib restart
/etc/init.d/dovecot restart
/etc/init.d/sqlgrey restart
/etc/init.d/postfix restart
Не забываем добавить их в автозапуск :)