FreeSource: AltLinux/Dokumentacija/PostfixMySQLCourierIMAP

Эта страница была перенесена на altlinux.org. Текст на freesource.info заморожен.

Почтовая система

NB: Любые поправки и дополнения приветствуются!

Что нужно

Нам нужна почта, способная предоставить следующие сервисы:

Делать всё это будем на базе ALT Linux Master 2.4 и почтового демона Postfix. За основу возьмём HOWTO, взятое по ссылке с официального сайта Postfix.

Нам понадобятся:

Установка необходимых пакетов

Подключаем репозитарий backports, т.к. в ALM 2.4 нет необходимого нам postfix с поддержкой TLS.

cat > /etc/apt/sources.list.d/backports.list << EOF

# vim:set ft=conf:

rpm [aris] ftp://ftp.altlinux.com/pub/distributions/ALTLinux/backports/2.4 i586 backports

rpm-src [aris] ftp://ftp.altlinux.com/pub/distributions/ALTLinux/backports/2.4 i586 backports

EOF

cat > /etc/apt/sources.list.d/vendors.list.d/backports.list

simple-key “aris” {

Fingerprint “213520E3EDE04AA556A07FC11ADEDDF9D765EC45”;

Name «Yuri N. Sedunov (aris) ";

}

EOF

И устанавливаем нужные нам пакеты:

apt-get update && apt-get install -y postfix-tls postfix-mysql libsasl2 libsasl2-plugin-sql openssl courier-imap \

courier-authdaemon-mysql fam clamsmtp MySQL-server

Если ставить из Сизифа, то понадобится также:

apt-get update && apt-get install -y postfix-cyrus

Не забудьте сменить пароль в MySQL!

Настройка MySQL

Так как MySQL в ALT Linux Master 2.4 работает в chroot и postfix тоже, нам придётся закомментировать в /var/lib/mysql/my.cnf строку skip-networking.

Заводим БД в MySQL:

mysqladmin create mail;

mysql -p mail

GRANT select on mail.* TO vmailuser@127.0.0.1 IDENTIFIED BY 'password123';

\q

И исполняем следующий скрипт для заведения таблиц:

CREATE TABLE postfix_alias (

  id int(11) unsigned NOT NULL auto_increment,

  alias varchar(128NOT NULL default '',

  destination varchar(128NOT NULL default '',

  PRIMARY KEY (id)

) TYPE=MyISAM;

CREATE TABLE postfix_relocated (

  id int(11) unsigned NOT NULL auto_increment,

  email varchar(128NOT NULL default '',

  destination varchar(128NOT NULL default '',

  PRIMARY KEY (id)

) TYPE=MyISAM;

CREATE TABLE postfix_transport (

  id int(11) unsigned NOT NULL auto_increment,

  domain varchar(128NOT NULL default '',

  destination varchar(128NOT NULL default '',

  PRIMARY KEY (id),

  UNIQUE KEY domain (domain)

) TYPE=MyISAM;

CREATE TABLE postfix_virtual_domains (

  id int(11) unsigned NOT NULL auto_increment,

  domain varchar(128NOT NULL default '',

  destination varchar(128NOT NULL default '',

  PRIMARY KEY (id),

  UNIQUE KEY domain (domain)

) TYPE=MyISAM;

CREATE TABLE postfix_users (

  id int(11) unsigned NOT NULL auto_increment,

  email varchar(128NOT NULL default '',

  clear varchar(128NOT NULL default '',

  crypt varchar(128NOT NULL default '',

  name tinytext NOT NULL,

  uid int(11) unsigned NOT NULL default '1001',

  gid int(11) unsigned NOT NULL default '1001',

  homedir varchar(255NOT NULL,

  maildir varchar(255NOT NULL default 'Maildir/',

  quota varchar(255NOT NULL default '20971520',

  access enum('Y','N') NOT NULL default 'Y',

  postfix enum('Y','N') NOT NULL default 'Y',

  pop3 enum('Y','N') NOT NULL default 'Y',

  imap enum('Y','N') NOT NULL default 'Y',

  webmail enum('Y','N') NOT NULL default 'Y',

  sharedgroup varchar(128NOT NULL default '0',

  smtpaccess enum('Y','N') NOT NULL default 'Y',

  PRIMARY KEY (id),

  UNIQUE KEY email (email)

) TYPE=MyISAM;

CREATE TABLE postfix_virtual (

  id int(11) unsigned NOT NULL auto_increment,

  email varchar(128NOT NULL default '',

  destination varchar(128NOT NULL default '',

  PRIMARY KEY (id)

) TYPE=MyISAM;

CREATE TABLE postfix_access (

  id int(10) unsigned NOT NULL auto_increment,

  source varchar(128NOT NULL default '',

  access varchar(128NOT NULL default '',

  type enum('recipient','sender','client') NOT NULL default 'recipient',

  PRIMARY KEY (id)

) TYPE=MyISAM ;

Копируем в MySQL содержимое /etc/postfix/aliases:

INSERT INTO postfix_alias VALUES (1,'MAILER-DAEMON','postmaster');

INSERT INTO postfix_alias VALUES (2,'info','postmaster');

INSERT INTO postfix_alias VALUES (3,'marketing','postmaster');

INSERT INTO postfix_alias VALUES (4,'sales','postmaster');

INSERT INTO postfix_alias VALUES (5,'support','postmaster');

INSERT INTO postfix_alias VALUES (6,'abuse','postmaster');

INSERT INTO postfix_alias VALUES (7,'noc','postmaster');

INSERT INTO postfix_alias VALUES (8,'security','postmaster');

INSERT INTO postfix_alias VALUES (9,'daemon','postmaster');

INSERT INTO postfix_alias VALUES (10,'ftp','postmaster');

INSERT INTO postfix_alias VALUES (11,'hostmaster','postmaster');

INSERT INTO postfix_alias VALUES (12,'lp','postmaster');

INSERT INTO postfix_alias VALUES (13,'mail','postmaster');

INSERT INTO postfix_alias VALUES (14,'news','postmaster');

INSERT INTO postfix_alias VALUES (15,'usenet','news');

INSERT INTO postfix_alias VALUES (16,'uucp','postmaster');

INSERT INTO postfix_alias VALUES (17,'webmaster','postmaster');

INSERT INTO postfix_alias VALUES (18,'www','webmaster');

INSERT INTO postfix_alias VALUES (19,'root','yourmail@yourdomain.ru');

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

groupadd vmail -g 1001

useradd vmail -u 1001 -g 1001 -d /var/mail/virtuals -s /dev/null \

-c 'Virtual Mail User' -M
mkdir /home/vmail/

chown vmail: /home/vmail

Создадим новый домен и в нём пользователя:

INSERT INTO postfix_virtual_domains VALUES (NULL,'test.com','maildrop:') ;

INSERT INTO postfix_users (email,clear,name,homedir) 

        VALUES ('ujo@test.com','mypassword','Artem',' /home/vmail/test.com/ujo/') ;

И не забудем создать ему структуру каталога:

mkdir -p /home/vmail/test.com/ujo/

maildirmake /home/vmail/test.com/ujo/

chown -R vmail:vmail /home/vmail/test.com

Настройка Postfix

Дописываем в файл /etc/postfix/main.cf следующие строки:

myhostname = mail.test.com

mydomain = test.com

mydestination = $myhostname

local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname

home_mailbox = Maildir/

smtpd_sasl_auth_enable = yes

smtpd_sasl2_auth_enable = yes

smtpd_sasl_security_options = noanonymous

smtpd_sasl_local_domain = $myhostname

broken_sasl_auth_clients = yes

smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,

check_recipient_access mysql:/etc/postfix/mysql-recipient.cf,reject_unauth_destination,permit
# The above line must be fitted in one line DONT FORGET

smtpd_sender_restrictions = check_sender_access mysql:/etc/postfix/mysql-sender.cf

smtpd_client_restrictions = check_client_access mysql:/etc/postfix/mysql-client.cf

alias_maps = mysql:/etc/postfix/mysql-aliases.cf

relocated_maps = mysql:/etc/postfix/mysql-relocated.cf

transport_maps = mysql:/etc/postfix/mysql-transport.cf

maildrop_destination_recipient_limit = 1

virtual_transport = maildrop

virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf

virtual_alias_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

# If you want to use TLS add three lines below

smtpd_use_tls = yes

smtpd_tls_cert_file = /etc/postfix/postfix.pem

smtpd_tls_key_file = $smtpd_tls_cert_file

# OPTIONAL PART

smtpd_helo_required = yes

disable_vrfy_command = yes

smtpd_data_restrictions = reject_unauth_pipelining

smtpd_etrn_restrictions = reject

TODO: Генерируем сертификат для SSL

openssl req -x509 -newkey rsa:1024 -keyout postfix.pem -out postfix.pem -nodes -days 365

Создаём в каталоге /etc/postfix файлы со следующим содержимым:

# mysql-aliases.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_alias

select_field = destination

where_field = alias

hosts = 127.0.0.11

# mysql-relocated.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_relocated

select_field = destination

where_field = email

hosts = 127.0.0.1

# mysql-transport.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_transport

select_field = destination

where_field = domain

hosts = 127.0.0.1

# mysql-virtual-domains.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_virtual_domains

select_field = destination

where_field = domain

hosts = 127.0.0.1

# mysql-virtual.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_virtual

select_field = destination

where_field = email

hosts = 127.0.0.1

# mysql-recipient.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_access

select_field = access

where_field = source

additional_conditions = and type = 'recipient'

hosts = 127.0.0.1

# mysql-sender.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_access

select_field = access

where_field = source

additional_conditions = and type = 'sender'

hosts = 127.0.0.1

# mysql-client.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_access

select_field = access

where_field = source

additional_conditions = and type = 'client'

hosts = 127.0.0.1

# mysql-virtual-maps.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_users

select_field = maildir

where_field = email

additional_conditions = and postfix = 'y'

hosts = 127.0.0.1

# mysql-virtual-uid.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_users

select_field = uid

where_field = email

additional_conditions = and postfix = 'y'

hosts = 127.0.0.1

# mysql-virtual-gid.cf

user = vmailuser

password = password123

dbname = mail

table = postfix_users

select_field = gid

where_field = email

additional_conditions = and postfix = 'y'

hosts = 127.0.0.1

Учитывая, что во всех этих файлах записан пароль для доступа к БД, исполняем следующие команды:

chmod 640 mysql-*

chgrp postfix mysql-*

Т.к. в качестве MDA мы будем использовать maildrop, вносим в /etc/postfix/master.cf следующие строки:

maildrop unix – n n – – pipe

flags=Ru user=vmail argv=/usr/bin/maildrop-mysql -d ${recipient}

Настройка SASL

Создаём файл /etc/postfix/sasl/smtpd.conf и записываем в него следующее:

pwcheck_method: auxprop

auxprop_plugin: sql

mech_list: plain login

sql_engine: mysql

sql_hostnames: 127.0.0.1

sql_user: vmailuser

sql_passwd: password123

sql_database: mail

sql_select: select clear from postfix_users where email='%u@%r' and smtpaccess='Y'

Также следим за правами доступа:

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

chmod 640 /etc/postfix/sasl/smtpd.conf

Настройка maildrop

редактируем /etc/courier-imap/maildrop-mysql.conf:

hostname 127.0.0.1

port 3306

database mail

dbuser vmailuser

dbpw password123

dbtable postfix_users

default_uidnumber 1001

default_gidnumber 1001

uid_field email

uidnumber_field uid

gidnumber_field gid

maildir_field maildir

homedirectory_field homedir

quota_field quota

where_clause ""

Проверка

Теперь проверяем, что получилось.

SMTP авторизация

ujo@ujo /RPM/SPECS $ telnet hermesus 25

Trying 192.168.0.10...

Connected to hermesus.

Escape character is '^]'.

220 supermail.domain.ru ESMTP Postfix

EHLO guys

250-supermail.domain.ru

250-PIPELINING

250-SIZE 10240000

250-ETRN

250-STARTTLS

250-AUTH PLAIN LOGIN

250-AUTH=PLAIN LOGIN

250 8BITMIME

AUTH PLAIN dWpvQHRlc3QuY29tAHVqb0B0ZXN0LmNvbQBteXBhc3N3b3Jk2

235 Authentication successful

quit

221 Bye

Connection closed by foreign host.

Работает.

Отправка почты вовне

Отправляем письмо куда-нибудь (echo test|mail -s test root), убеждаемся что связь с MySQL работает.

Локальная доставка

ujo@ujo ~ $ telnet hermesus 25

Trying 192.168.0.10...

Connected to hermesus.

Escape character is '^]'.

220 supermail.domain.ru ESMTP Postfix

EHLO guys

250-supermail.domain.ru

250-PIPELINING

250-SIZE 10240000

250-ETRN

250-STARTTLS

250-AUTH PLAIN LOGIN

250-AUTH=PLAIN LOGIN

250 8BITMIME

MAIL FROM: <ujo@domain.ru>

250 Ok

RCPT TO: <ujo@test.com>

250 Ok

DATA

354 End data with <CR><LF>.<CR><LF>

test

.

250 Ok: queued as 92541152023

quit

221 Bye

Connection closed by foreign host.

Postfix сообщает нам, что 

Nov 28 13:36:47 hermesus postfix/qmgr[15006]: 92541152023: from=<ujo@domain.ru>, size=339, nrcpt=1 (queue active)

Nov 28 13:36:47 hermesus postfix/pipe[15034]: 92541152023: to=<ujo@test.com>, relay=maildrop, delay=20, status=sent (test.com)

Почта пришла и положена на место.

POP3/IMAP4

Здесь всё намного проще: база MySQL у нас уже есть, осталось только настроить Courier-IMAP.

Также вписываем в /etc/courier-imap/authdaemon.conf

authmodulelist="authmysql"

и редактируем /etc/courier-imap/authdaemon-mysql.conf:

MYSQL_SERVER 127.0.0.1

MYSQL_USERNAME vmailuser

MYSQL_PASSWORD password123

MYSQL_PORT 3306

MYSQL_OPT 0

MYSQL_DATABASE mail

MYSQL_USER_TABLE postfix_users

MYSQL_CRYPT_PWFIELD crypt

MYSQL_CLEAR_PWFIELD clear

MYSQL_UID_FIELD uid

MYSQL_GID_FIELD gid

MYSQL_LOGIN_FIELD email

MYSQL_HOME_FIELD homedir

MYSQL_NAME_FIELD name

MYSQL_MAILDIR_FIELD maildir

MYSQL_QUOTA_FIELD quota

И — специфика ALT — висываем в /etc/sysconfig/courier-imap

DEFAULT_AUTHD=mysql

Редактируем файлы pop3d, imapd, pop3d-ssl, imapd-ssl в /etc/courier-imap. Везде вписываем нужный нам ADDRESS и меняем строчки вида POP3DSTART=no на POP3DSTART=yes

запускаем authdaemon и другие:

service courier-authdaemon start

service courier-pop3d start

service courier-pop3d-ssl start

service courier-imapd start

service courier-imapd-ssl start

Проверка:

ujo@ujo ~ $ telnet 192.168.0.13 110

Trying 192.168.0.13...

Connected to 192.168.0.13.

Escape character is '^]'.

+OK Hello there.

user ujo@test.com

+OK Password required.

pass mypassword

+OK logged in.

quit

+OK Bye-bye.

POP3 работает.

ujo@ujo ~ $ telnet 192.168.0.13 143

Trying 192.168.0.13...

Connected to 192.168.0.13.

Escape character is '^]'.

* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998–2004 Double Precision, Inc. See COPYING for distribution information.

0 login ujo@test.com mypassword

0 OK LOGIN Ok.

1 logout

* BYE Courier-IMAP server shutting down

1 OK LOGOUT completed

IMAP тоже.

FAM 

Для полноценной работы Courier-IMAP нужен демон FAM. Редактируем /etc/xinetd.d/sgi_fam, исправляем disable = yes на disable = no, и — это ошибка fam или xinetd — закомментируем строку only_from в /etc/xinetd.conf3

Отстрел проблем


1 Так как MySQL и Postfix у нас оба работает в chroot, то следует писать именно 127.0.0.1, а не localhost. Не забудьте закомментировать строку skip-networking в /var/lib/mysql/my.cnf и прикрыть MySQL от внешнего доступа.

2 Строка для авторизации получается так:

perl -MMIME::Base64 -e 'print encode_base64(«ujo\@test.com\0ujo\@test.com\0mypassword»),"\n";'

3 На самом деле, это снижает безопасность xinetd, ведь с этой строкой все сервисы xinetd по умолчанию слушают только адрес 127.0.0.1, а не все доступные адреса. Однако, из-за досадной ошибки fam не желает работать со строкой only_from.