понедельник, 29 апреля 2013 г.

Postfix и Dovecot SASL + VirtualHosts в CentOS 6 x86_64






English:










Иногда случается нужда в развёртывании почты, но и вроде пользователей не так много чтобы городить жирные системы с базами данных в MySQL или PostgreSQL. Хотя с другой стороны и виртуальных пользователей хочется, и еще кое какие плюшки. Перед написанием статьи я очень много рыскал в интернетах, но статьи что попадались мне как правило были либо нацелены на слишком крупные системы, либо были сильно устаревшие и использовали уже не существующий синтаксис конфигов, либо, либо, либо...

Вообщем если кратко, то эта статья про то как настроить Postfix+Dovrcot+SASL виртуальными доменами и виртуальными пользователями и базой пользователей в текстовом файлике.

Очень часто бывает, что сервер с CentOS попадается multiarch, что чревато проблемами от простой установки не нужных 32х битных дубликатов всех пакетов до серьёзных конфликтов  в зависимостях. По этой причине считается хорошим тоном отключать возможность инсталляции пакетов 32х битной архитектуры на 64х битной системе, что мы и сделаем при установке.


Готовим базис 


Поставим необходимые нам в настройке пакеты
echo 'exclude=*.i386 *.i686' >> /etc/yum.conf
yum install postfix postfix-perl-scripts dovecot mailx telnet -y

Чтобы убедиться что мы с вами работаем с одинаковыми мажорными ветками, сверим ПО.
Это необходимо, поскольку у разных веток одного софта, может быть разный синтаксис.
rpm -qa | egrep 'postfix|dovecot'
 dovecot-2.0.9-5.el6.x86_64
 postfix-2.6.6-2.2.el6_1.x86_64
 postfix-perl-scripts-2.6.6-2.2.el6_1.x86_64

Убедимся что они запускаются чтобы не было мучительно больно
service postfix start
 Starting postfix:                                          [  OK  ]
service dovecot start
 Starting Dovecot Imap:                                     [  OK  ]

Ну и закрепим их в автозапуске
chkconfig postfix on
chkconfig dovecot on

Можно приступать к конфигурации системы
Пока не забыли добавим пользователя который будет являться владельцем писем всех пользователей.
groupadd -g 5000 vmail
useradd -m -u 5000 -g 5000 -s /bin/bash vmail



Конфигурация Postfix

У Postfix'a есть замечательный набор конфигурационных скриптов, который избавляет нас от необходимости лазить по конфигу в поисках той или иной опции, и делает процесс настройки более наглядным и если у вас правильно настроен .bashrc, то и позволяет использовать .bash_history в качестве документа изменений конфигурации.

ВСЕГДА делайте BackUP  конфигов перед их изменением, а лучше заведите сервер контроля версий типа Git или SVN для конфигов.
cp /etc/postfix/main.cf{,.bak}

Теперь можно менять конфигурацию
# Сделаем базовые настройки
postconf -e 'mail_spool_directory = /var/spool/mail'
postconf -e 'mynetworks = 127.0.0.0/8'
postconf -e 'inet_interfaces = all'
postconf -e 'myhostname = mail.example1.com'
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'
postconf -e 'home_mailbox = Maildir/'
postconf -e 'recipient_delimiter = +'
postconf -e 'mailbox_size_limit = 0'
postconf -e 'alias_maps = hash:/etc/aliases'
postconf -e 'alias_database = hash:/etc/aliases'

# Расскажем Postfix'y где наш SASL свой socket отрастил
postconf -e 'smtpd_sasl_type = dovecot'
postconf -e 'smtpd_sasl_path = private/auth'
postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

# Расскажем Postfix'y где список доменов зарыли, и куда нынче принято письма складывать 
postconf -e 'virtual_mailbox_domains = /etc/postfix/vhosts'
postconf -e 'virtual_mailbox_base = /home/vmail'
postconf -e 'virtual_mailbox_maps = hash:/etc/postfix/vmaps'
postconf -e 'virtual_minimum_uid = 1000'
postconf -e 'virtual_uid_maps = static:5000'
postconf -e 'virtual_gid_maps = static:5000'

Перечислим все обслуживаемые домены в файле /etc/postfix/vhosts

cat >> /etc/postfix/vhosts <<EOF
example1.com
example2.com
EOF

И создадим карту маппинга дабы направлять потоки почты в нужные директории а так же одаривать пользователей новыми именами. Синтаксис не сложный, как видно из текста ниже за адресом почты следует относительный путь, и соотносится он с директорией /home/vmail . 
touch /etc/postfix/vmaps

А так можно описать алиасы
cat >> /etc/postfix/vmaps <<EOF
info@example1.com  example1.com/info/
hr@example1.com  example1.com/info/
support@example1.com  example1.com/support/
info@example2.com  example2.com/info/
sales@example2.com  example2.com/sales/
EOF

После того как опишите файл скомпилируйте его 
postmap /etc/postfix/vmaps

Ну и перезапустим postfix
/etc/init.d/postfix restart

Настало время первой отправки, скрещиваем все что скрещивается, пробуем
echo test-body | mail -s "test-subject" info@example1.com

У нас должен появиться файл в директории /home/vmail/example1.com/info/new/
А директория должна создаться сама, если этого не произошло смотрим /var/log/maillog и ищем где оступились 
Проверим результат 
ls -la /home/vmail/example1.com/info/new/*
-rw-------. 1 vmail vmail 526 Apr 28 01:39 /home/vmail/example1.com/info/new/1367087988.Vfd00I1fb6dM872595.test-mail
cat /home/vmail/example1.com/info/new/1367087988.Vfd00I1fb6dM872595.test-mail 
Return-Path: <root@mail.example.com>
X-Original-To: info@example1.com
Delivered-To: info@example1.com
Received: by mail.example.com (Postfix, from userid 0)
 id D288977F; Sun, 28 Apr 2013 01:39:48 +0700 (OMST)
Date: Sun, 28 Apr 2013 01:39:48 +0700
To: info@example1.com
Subject: test-subject
User-Agent: Heirloom mailx 12.4 7/29/08
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20130427183948.D288977F@mail.example.com>
From: root@mail.example.com (root)

test-body

Если всё ok то идём дальше


Конфигурация Dovecot

С синтаксисом конфигов на мой взгляд dovecot'y повезло меньше, по этому в этой секции будет несколько "пойди туда, щас скажу куда, сделай то щас скажу что"

Как всегда первым делом бэкапим конфиги. По скольку тут конфигурация раскидана по нескольким файлам, я буду копировать всю директорию.
cp -a /etc/dovecot{,.bak}

Настраиваем многочисленные опции в многочисленных файлах
# Рассказываем Dovecot'y откуда почта берётся. Кстати %d = домен , %n = user@домен
sed -i -e 's/#mail_location.*/mail_location = maildir:\/home\/vmail\/%d\/%n/g'\
 /etc/dovecot/conf.d/10-mail.conf

# настраиваем chroot_dirs
sed -i -e 's/#valid_chroot_dirs.*/valid_chroot_dirs = \/var\/spool\/vmail/g'\
 /etc/dovecot/conf.d/10-mail.conf

# Включим поддержку протоколов которые будем использовать при Аутентификации
sed -i -e 's/^auth_mechanisms.*/auth_mechanisms = plain login cram-md5/g'\
 /etc/dovecot/conf.d/10-auth.conf
# настраиваем base_dir
sed -i -e 's/#base_dir.*/base_dir = \/var\/run\/dovecot\//g'\
 /etc/dovecot/dovecot.conf

# настраиваем протоколы которые собираемся использовать
sed -i -e 's/#protocols.*/protocols = imap pop3/g'\
 /etc/dovecot/dovecot.conf

# настраиваем логирование
sed -i -e 's/#auth_verbose =.*/auth_verbose = yes/g'\
 /etc/dovecot/conf.d/10-logging.conf
sed -i -e 's/#info_log_path.*/info_log_path = \/var\/log\/dovecot.info/g'\
 /etc/dovecot/conf.d/10-logging.conf
sed -i -e 's/#log_path.*/log_path = \/var\/log\/dovecot/g'\
 /etc/dovecot/conf.d/10-logging.conf
sed -i -e 's/#log_timestamp.*/log_timestamp = "%b %d %H:%M:%S "/g'\
 /etc/dovecot/conf.d/10-logging.conf 

В случае если вы не планируете использовать шифрование (НЕ РЕКОМЕНДУЕТСЯ)
# Включаем поддержку не шифрованной Аутентификации
sed -i -e 's/#disable_plaintext_auth.*/disable_plaintext_auth = no/g'\
 /etc/dovecot/conf.d/10-auth.conf
# отрубаем SSL
sed -i -e 's/#ssl =.*/ssl = no/g'\
 /etc/dovecot/conf.d/10-ssl.conf

Ну и вот обещанное пойди в  /etc/dovecot/conf.d/10-master.conf найди и приведи к следующему виду секцию в файле.
Этим жестом мы откроем postfix'y дверцу в мысли dovecot'a через sasl
# Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }

Продолжаем веселиться
# Отрубаем системную аутентификацию
sed -i -e 's/!include auth-system.conf.ext/#!include auth-system.conf.ext/g'\
 /etc/dovecot/conf.d/10-auth.conf

# И подключаем аутентификацию по файлику
sed -i -e 's/#!include auth-passwdfile.conf.ext/!include auth-passwdfile.conf.ext/g'\
 /etc/dovecot/conf.d/10-auth.conf

Немножко подправим схему в фале /etc/dovecot/conf.d/auth-passwdfile.conf.ext
# ПРЕДВАРИТЕЛЬНО его ЗАБЭКАПИВ, да снова, на всякийслучай
cp /etc/dovecot/conf.d/auth-passwdfile.conf.ext{,.bak}

# запишем файл 
cat > /etc/dovecot/conf.d/auth-passwdfile.conf.ext <<EOF

passdb {
  args = scheme=CRYPT /etc/dovecot/passwd
  driver = passwd-file
}

userdb {
  args = /etc/dovecot/users
  driver = passwd-file
}


EOF

Создадим скрипт добавления пользователей
cat > /usr/local/sbin/adddovecotuser <<EOF
#!/bin/bash

maildirmake.dovecot(){
dir="\$1"
owner="\$2"
if [ -z "\$dir" ]; then
  echo "Must supply a directory path"
  exit 1
fi

if [ "\$dir" = "-h" ]; then
  echo "usage: \$0 directory [user]"
  exit 0
fi

umask 077
mkdir -p "\$dir/cur" "\$dir/new" "\$dir/tmp" || exit 1
chmod 0700 "\$dir" "\$dir/cur" "\$dir/new" "\$dir/tmp" || exit 1

if [ -n "\$owner" ]; then
  chown -R "\$owner" "\$dir" || exit 1
fi

}

if [ ! \$# = 1 ]
 then
  echo "Usage: \$0 username@domain"
  exit 1
 else
  user=\`echo "\$1" | cut -f1 -d "@"\`
  domain=\`echo "\$1" | cut -s -f2 -d "@"\`
  if [ -x \$domain ]
   then
    echo "No domain given\nUsage: \$0 username@domain"
    exit 2
  fi
  echo "Adding user \$user@\$domain to /etc/dovecot/users"
  echo "\$user@\$domain::5000:5000::/home/vmail/\$domain/\$user/:/bin/false::" >> /etc/dovecot/users

  # Create the needed Maildir directories
  echo "Creating user directory /home/vmail/\$domain/\$user"
  # maildirmake.dovecot does only chown on user directory, we'll create domain directory instead
  if [ ! -x /home/vmail/\$domain ]
   then
    mkdir /home/vmail/\$domain
    chown 5000:5000 /home/vmail/\$domain
    chmod 700 /home/vmail/\$domain
  fi
  maildirmake.dovecot /home/vmail/\$domain/\$user 5000:5000
  # Also make folders for Drafts, Sent, Junk and Trash
  maildirmake.dovecot /home/vmail/\$domain/\$user/.Drafts 5000:5000
  maildirmake.dovecot /home/vmail/\$domain/\$user/.Sent 5000:5000
  maildirmake.dovecot /home/vmail/\$domain/\$user/.Junk 5000:5000
  maildirmake.dovecot /home/vmail/\$domain/\$user/.Trash 5000:5000

  # To add user to Postfix virtual map file and relode Postfix
  echo "Adding user to /etc/postfix/vmaps"
  echo \$1  \$domain/\$user/ >> /etc/postfix/vmaps
  postmap /etc/postfix/vmaps
  postfix reload
fi
echo "\nCreate a password for the new email user"
#SWAP THE FOLLOWING passwd LINES IF USING A UBUNTU VERSION PRIOR TO 12.04
#passwd=\`dovecotpw\`
passwd=\`doveadm pw -u \$user\`
echo "Adding password for \$user@\$domain to /etc/dovecot/passwd"
if [ ! -x /etc/dovecot/passwd ]
 then
  touch /etc/dovecot/passwd
  chmod 640 /etc/dovecot/passwd
fi
echo  "\$user@\$domain:\$passwd" >> /etc/dovecot/passwd

exit 0
EOF

chmod +x /usr/local/sbin/adddovecotuser

И попробуем им воспользоваться
/usr/local/sbin/adddovecotuser user1@example1.com
 Adding user user1@example1.com to /etc/dovecot/users
 Creating user directory /home/vmail/example1.com/user1
 Adding user to /etc/postfix/vmaps
 postfix/postfix-script: refreshing the Postfix mail system
 \nCreate a password for the new email user
 Enter new password: 
 Retype new password: 
 Adding password for user1@example1.com to /etc/dovecot/passwd
Теперь когда файлы users и  passwd лежат на диске, зададим для них корректные права
chgrp dovecot /etc/dovecot/users /etc/dovecot/passwd
chmod 640 /etc/dovecot/users /etc/dovecot/passwd

Для большего понимания ситуации рассмотрим синтаксис файлов users и  passwd
cat /etc/dovecot/users
user1@example1.com::5000:5000::/home/vmail/example1.com/user1/:/bin/false::
^user  ^domain       ^uid ^gid                           ^mail_dir  ^user_shell

cat /etc/dovecot/passwd 
user1@example1.com:{CRAM-MD5}3da65e0449ed4c842c48cf6467351753cf3c1398404e8ae9c54dc3784f0890e7
^user  ^domain       ^password_hash


Создадим скрипт удаления пользователя
cat > /usr/local/sbin/deldovecotuser <<EOF
#!/bin/bash
#
# deldovecotuser - for deleting virtual dovecot users
#
if [ ! \$# = 1 ]
 then
  echo -e "Usage: \$0 username@domain"
  exit 1
 else
  user=\`echo "\$1" | cut -f1 -d "@"\`
  domain=\`echo "\$1" | cut -s -f2 -d "@"\`
  if [ -x \$domain ]
   then
    echo -e "No domain given\nUsage: \$0 username@domain: "
    exit 2
  fi
fi
read -n 1 -p "Delete user \$user@\$domain from dovecot? [Y/N]? "
echo
case \$REPLY in
 y | Y)
  new_users=\`grep -v \$user@\$domain /etc/dovecot/users\`
  new_passwd=\`grep -v \$user@\$domain /etc/dovecot/passwd\`
  new_vmaps=\`grep -v \$user@\$domain /etc/postfix/vmaps\`
  echo "Deleting \$user@\$domain from /etc/dovecot/users"
  echo "\$new_users" > /etc/dovecot/users
  echo "Deleting \$user@\$domain from /etc/dovecot/passwd"
  echo "\$new_passwd" > /etc/dovecot/passwd
  echo "Deleting \$user@\$domain from /etc/postfix/vmaps"
  echo "\$new_vmaps" > /etc/postfix/vmaps
  postmap /etc/postfix/vmaps
  postfix reload
  read -n1 -p "Delete all files in /home/vmail/\$domain/\$user? [Y/N]? " DELETE
  echo
  case \$DELETE in
   y | Y)
    echo "Deleting files in /home/vmail/\$domain/\$user"
    rm -fr /home/vmail/\$domain/\$user
   ;;
   * )
    echo "Not deleting files in /home/vmail/\$domain/\$user"
   ;;
  esac
 ;;
 * )
  echo "Aborting..."
 ;;
esac
EOF

chmod +x /usr/local/sbin/deldovecotuser

И попробуем удалить пользователя( я предварительно создал пользователя bad-user)
/usr/local/sbin/deldovecotuser bad-user@example1.com
 Delete user bad-user@example1.com from dovecot? [Y/N]? y
 Deleting bad-user@example1.com from /etc/dovecot/users
 Deleting bad-user@example1.com from /etc/dovecot/passwd
 Deleting bad-user@example1.com from /etc/postfix/vmaps
 postfix/postfix-script: refreshing the Postfix mail system
 Delete all files in /home/vmail/example1.com/bad-user? [Y/N]? y
 Deleting files in /home/vmail/example1.com/bad-user


Разрешим порты в IPtables
iptables -I INPUT 1 -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
iptables -I INPUT 1 -m state --state NEW -m tcp -p tcp --dport 110 -j ACCEPT
iptables -I INPUT 1 -m state --state NEW -m tcp -p tcp --dport 143 -j ACCEPT
/etc/init.d/iptables save
 iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

Ну и не забудьте всё перезапустить
/etc/init.d/dovecot restart
 Stopping Dovecot Imap:                                     [  OK  ]
 Starting Dovecot Imap:                                     [  OK  ]
/etc/init.d/postfix restart
 Shutting down postfix:                                     [  OK  ]
 Starting postfix:                                          [  OK  ]




Теперь попробуйте подключиться и протестировать как ходят письма

Если у вас есть желание настроить SSL/TLS то читаем дальше



ниже инфа по теме
Enhanced by Zemanta