Using Postfix, Dovecot and MySql as Mailserver under CentOS 7

Here is the original guid: Postfix+Dovecot+MySQL搭建邮件服务器

The reference above was written for Ubuntu, I found some changes must be done to apply the techniques with my CentOS scenario.

Another helpful guid: Email with Postfix, Dovecot and MariaDB on CentOS 7

The second one uses likely design of database. More important, it has some things the first reference doesn‘t talk about.

My scenario

I planed to build a mail server working with gitlab, for internal development using. The mail server is also the one running gitlab. The idea makes things simple.

1. DNS configuration

For local network, you have to use "/etc/hosts" as the alternative.

Let‘s say the host name of server is: devsrv,

Server File: /etc/hosts

# hosts for devsrv
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# DNS configuration
192.168.1.10 mail.devsrv.lan www.devsrv.lan devsrv.lan devsrv

Client File: /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.1.10 devsrv devsrv.lan www.devsrv.lan mail.devsrv.lan imap.devsrv.lan smtp.devsrv.lan git.devsrv.lan

2. Installation

Under CentOS, the commands cloud be:

sudo yum install -y postfix dovecot dovecot-core mariadb

3. Initializing of database

Following the instruction of the first reference, initialize the database. I also wrote some procedures to help managing account:

Create Database

create database if not exists mailserver;

create user [email protected]'localhost' identified by 'mailserver123';

grant all on mailserver.* to [email protected]' identified by 'mailserver123';

Create tables and procedures

use mailserver;

delimiter //

drop procedure if exists proc_log;

create procedure proc_log(msg varchar(1024))
begin
	select ifnull(msg, '') as DEBUG;
end //

-- Procedure: proc_show_error
-- Show error message with error code
drop procedure if exists proc_log_error;

create procedure proc_log_error(err_code int, msg varchar(255))
begin
  call proc_log(concat('ERROR(', err_code, '): ', msg));
end //

-- Procedure proc_add_mail_account
-- Create a new mail account
drop procedure if exists proc_add_mail_account;

create procedure proc_add_mail_account
(uname varchar(64),
pwd varchar(64))
begin
  declare def_domain varchar(100) default 'devsrv.lan';
  declare err int default 0;
  declare num int;

  declare uname_len int default 0;
  declare at_pos int default null;
 
  declare domain varchar(100);
  declare domain_id int;
 
  declare pwd_len int;
 
  -- initialize
  set uname = lcase(ltrim(rtrim(uname)));
  set uname_len = length(uname);
  set at_pos = ifnull(instr(uname, '@'), 0);

  set pwd = ltrim(rtrim(pwd));
  set pwd_len = length(pwd);

    -- validate username
  if uname is null or uname_len = 0 then
    set err = 1;
    call proc_log_error(err, 'Empty username');
  end if;

  -- check '@'
  if err = 0 and at_pos > 0 then
      -- if username has only '@' character
      set domain = right(uname, uname_len - at_pos);

      if uname_len = 1 or length(domain) = 0 then
        set err = 2;
        call proc_log_error(err, 'Invalid username');
      end if
    end if;
  end if;

  -- validate domain
  if err = 0 then
        if domain is null or length(domain) = 0 then
            set domain = def_domain;
      
      -- use default domain if not specified.
            set uname = concat(uname, '@', domain);
        end if;
  end if;

  -- validate domain existence
  if err = 0 then
    select id into domain_id from virtual_domains where name = domain;

    if domain_id is null then
      set err = 4;
      call proc_log_error(err, 'Invalid domain');
    end if;
  end if;

  -- validate user existence
  if err = 0 then
    select count(*) into num from virtual_users where email=uname;

    if num > 0 then
      set err = 5;
      call proc_log_error(err, 'User exists');
    end if;
  end if;

  -- validate password
  if err = 0 then
    if pwd_len = 0 then
      set err = 6;
      call proc_log_error(err, 'Empty password');
    else
      -- validate security rules
      -- validate length
      if pwd_len < 6 then
        set err = 7;
        call proc_log_error(err, 'Password must be 6 characters long');
      end if;
      -- NOTE: following rules are ignored now.
      -- validate uppercase letters
      -- validate digit
    end if;
  end if;
 
  if err = 0 then
      -- create account
      set pwd = encrypt(pwd, concat('X7X', substring(sha(rand()), -16)));

      insert virtual_users (domain_id, password, email)
          values(domain_id, pwd, uname);

        if last_insert_id() is null then
            set err = 8;
            call proc_log_error(err, 'Failed to create account');
      else
            select 'Account has been created successfully!';
      end if;
  end if;
end //
-- end of procedure

drop procedure if exists proc_del_mail_account;

create procedure proc_del_mail_account(uname varchar(64))
begin
    set uname = lcase(ltrim(rtrim(uname)));
 
    delete from virtual_users where email=uname;
 
  if row_count() = 0 then
        call proc_log('User does not exist');
  else
        call proc_log('User account has been removed successfully!');
    end if;

end //

drop procedure if exists proc_add_mail_alias;

create procedure proc_add_mail_alias(src varchar(100), dest varchar(100))
begin
    declare err int default 0;
    declare num int;
 
  declare domain_id int;
 
  declare dest_len int;
    declare dest_at_pos int;
  declare dest_name varchar(100);
  declare dest_domain varchar(100);
 
  declare src_len int;
  declare src_at_pos int;
  declare src_name varchar(100);
  declare src_domain varchar(100);
 
  set dest = lcase(ltrim(rtrim(dest)));
  set dest_len = length(dest);
  set dest_at_pos = ifnull(instr(dest, '@'), 0);
 
  set src = lcase(ltrim(rtrim(src)));
  set src_len = length(src);
  set src_at_pos = ifnull(instr(src, '@'), 0);
 
  -- validate dest length
  if dest_len = 0 then
        set err = 1;
    call proc_log_error(err, 'Empty dest');
    else
        -- check '@'
        if dest_at_pos = 0 then
            set err = 2;
      call proc_log_error(err, 'Invalid dest');
        else
            set dest_name = left(dest, dest_at_pos - 1);
      set dest_domain = right(dest, dest_len - dest_at_pos);
      
      -- re-check dest
      if length(dest_name) = 0 or length(dest_domain) = 0 then
                set err = 3;
        call proc_log_error(err, 'Invalid dest');
            else
                -- check existence
                select count(*) into num from virtual_users where email=dest;
        
        if num = 0 then
                    set err = 4;
          call proc_log_error(err, 'dest does not exist');
        end if;
      end if;
    end if;
  end if;
 
  -- validate
  if err = 0 then
        if src_len = 0 then
            set err = 5;
      call proc_log_error(err, 'Empty alias');
        else
            if src_at_pos = 0 then
                set err = 6;
        call proc_log_error(err, 'Invalid alias');
      else
                set src_name=left(src, src_at_pos - 1);
        set src_domain=right(src, src_len - src_at_pos);
        
        if length(src_name) = 0 or length(src_domain) = 0 then
                    set err = 7;
          call proc_log_error(err, 'Invalid alias');
        end if;
      end if;
    end if;
  end if;
 
  call proc_log(concat('Validate domains', err));
 
  -- validate both domains
  if err = 0 then
        if dest_domain != src_domain then
            set err = 8;
      call proc_log_error(err, 'Domain does not match');
        else
            call proc_log('Check domain id');
      
            select id into domain_id from virtual_domains where name=dest_domain;
            
      call proc_log(concat('Get domain id:', ifnull(domain_id, 'null')));
      
      if domain_id is null then
                set err = 9;
        call proc_log_error(err, 'Domain does not exist');
      else
                select count(*) into num from virtual_aliases where source=src and destination=dest;
        
        call proc_log(concat('num of match:', num));
        
        if num > 0 then
                    set err = 10;
          call proc_log_error(err, 'Alias already exists');
                else
                    call proc_log('Insert into...');
          
                    insert into virtual_aliases(domain_id, source, destination)
                        value(domain_id, src, dest);
                    
          call proc_log('Inserted.');
          
                    if last_insert_id() is null then
                        set err = 11;
                        call proc_log_error(err, 'Failed');
                    else
                        call proc_log('Alias has been added successfully');
          end if;
        end if;
      end if;
        end if;
  end if;
end //

drop procedure if exists proc_del_mail_alias;

create procedure proc_del_mail_alias(src varchar(100), dest varchar(100))
begin
    declare err int default 0;
  declare num int;
 
  declare src_len int;
  declare src_at_pos int;
  declare src_domain varchar(100);
  declare src_domain_len int;
 
  declare dest_len int;
  declare dest_at_pos int;
  declare dest_domain varchar(100);
  declare dest_domain_len int;
 
  declare alias_id int default null;
 
  set src = lcase(ltrim(rtrim(src)));
  set src_len = length(src);
  set src_at_pos = ifnull(instr(src, '@'), 0);
  set src_domain = right(src, src_len - src_at_pos);
  set src_domain_len = length(src_domain);
 
  set dest = lcase(ltrim(rtrim(dest)));
  set dest_len = length(dest);
  set dest_at_pos = ifnull(instr(dest, '@'), 0);
  set dest_domain = right(dest, dest_len -dest_at_pos);
  set dest_domain_len = length(dest_domain);
 
  if src_len = 0 or src_at_pos = 0 or src_domain_len = 0 then
        set err = 1;
    call proc_log_error(err, 'Invalid alias');
  end if;
    
  if err = 0 and (dest_len = 0 or dest_at_pos = 0 or dest_domain_len = 0) then
        set err = 2;
        call proc_log_error(err, 'Invalid account');
  end if;
 
  if err = 0 then
        if src_domain != dest_domain then
            set err = 3;
      call proc_log_error(err, 'Different domain');
        end if;
  end if;
 
  if err = 0 then
        select id into alias_id from virtual_aliases where source = src and destination = dest;
    
    if alias_id is null then
            set err = 4;
      call proc_log_error(err, 'Not found');
        else
            delete from virtual_aliases where id = alias_id;
      
      if row_count() = 0 then
                set err = 5;
        call proc_log_error(err, 'Failed to remove record');
            else
                select 'Alias has been removed successfully';
            end if;
      
    end if;
  end if;
end //

NOTE: Change the default domain to your favorite one before run the script.

Copy and run the sql code in query window of MySql Workbench.

Or save the code to a file and run mysql command:

[[email protected]:~]$mysql -u root -u < untitled.sql

Account maintenance

Under mysql command prompt, run statements to maintenance mail account:

$mysql -u mailserver -p

Create user

call proc_add_mail_account('igame', '123456');

Create alias

call proc_add_mail_alias('[email protected]', '[email protected]');

4. Postfix configuration

Following the reference above to configure postfix, but some small differences :

File: /etc/postfix/main.cf

myhostname = mail.devsrv.lan
mydomain = lan

mydestination = $myhostname, localhost.$mydomain, localhost

# restrict in intranet, for internet, should be 0.0.0.0/0
mynetworks = 192.168.1.0/24, 127.0.0.0/8

NOTE: CentOS stores dovecot certs in different path, if you use the default dovecot certs, keep that in mind:

smtpd_tls_cert_file=/etc/pki/dovecot/certs/dovecot.pem
smtpd_tls_key_file=/etc/pki/dovecot/private/dovecot.pem

NOTE: If you have problems when sending mail, try make unset mydestination

mydestination =

The reference above doesn‘t talk about "/etc/postfix/master.cf" which is crucially important, here is how:

File: /etc/postfix/master.cf

# Postfix master process configuration file.  For details on the format
# of the file, see the master(5) manual page (command: "man 5 master").
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# 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=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=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       n       -       -       qmqpd

# NOTE: do not forget dovecot
dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

5. Dovecot configuration

Again, the most occurring error is the path of ssl certs, for default dovecot certs, it should be:

File: /etc/dovecot/dovecot.conf

ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem

Under CentOS 7, there is no *.protocol files for dovecot.conf, so this following line coming from the first reference has no meaning:

 !include_try /usr/share/dovecot/protocols.d/*.protocol 

6. Create Account

In query dialog of "MySql Workbench Community" or mysql command line prompt, run the following sql statement:

use mailserver;

call proc_add_mail_account('test', '123456');

7. Thunderbird Configuration

The Thunderbird is not smart enough if you choose to let it detect the configuration from mail server. The faster way is manually configuring:

Add new account:

Use manual config

NOTE: Remove the "." before server hostname which is a mistake. Configure the port, SSL and authentication like the following picture:

Re-test

Now the Thunderbird shows off how clever it is.

Add Security Exception

Probably Thunderbird warns about security exception, choose "Confirm Security Exception".

Overview of Account Settings

When all done, we can check the settings of account.

Server Settings:

Outgoing Server(SMTP) Settings:

Edit the smtp setting:

Congratulations! All done, now we can send and receive mail. Enjoy!

Good luck!

时间: 2024-10-02 19:42:23

Using Postfix, Dovecot and MySql as Mailserver under CentOS 7的相关文章

Postfix+Dovecot+MySQL搭建邮件服务器

说到邮件服务器,网上有许多不同解决方案.Window操作系统下常见的邮件服务器有hMailServer.MailEnable.EVOMailServer.Apache James(纯Java跨平台)等. 而在Linux/Unix系统中常用的邮件服务器也有不少选择,最经典也是最常见的莫过于Postfix.这篇文章将会讲述如何在Ubuntu系统之下,通过Postfix.Dovecot.MySQL整合实现普通意义上「邮件服务器」的大部分功能. 开始之前 配置邮件服务器并不是一项简单的工作,其过程不仅需

邮件系统服务器搭建记录(五)(Postfix+Cyrus-sasl+Courier-authlib+Dovecot+ExtMail+MySQL)

13.  配置dovecot访问mysql进行验证 dovecot本身是支持mysql认证方式的,其在/etc/dovecot/conf.d/下提供了名为auth-sql.conf.ext的配置文件: [[email protected] ~]# cd /etc/dovecot/conf.d/ [[email protected] conf.d]# ls auth-master.conf.ext  auth-master.conf.ext 但dovecot默认使用的收件认证方式是系统账号口令验证

邮件系统服务器搭建记录(四)(Postfix+Cyrus-sasl+Courier-authlib+Dovecot+ExtMail+MySQL)

8. 安装Apache Http Server: [[email protected] ~]# yum install httpd 9. 下载ExtMail和ExtMan,并使用Extman提供的Mysql脚本初始化extmail数据库 访问Extmail官方网站(http://www.extmail.org/)下载ExtMail和ExtMan程序包,解压: [[email protected] ~]# tar -xf extmail-1.2.tar.gz [[email protected] 

Postfix + Sasl + Courier-Authlib + MySQL + Dovecot + Webmail搭建邮件服务器

实验背景: A.Vmware虚拟机redhat5.8._32位-台作为邮件服务器,设定主机名为mail.willow.com, IP为1.1.1.18,DNS指向本机,提前部署好DNS服务器, 特别要指出的是,一定要将mail邮箱服务器的MX记录,A记录,PTR记录指向 本机1.1.1.18(这里不要解释如何搭建DNS,如需知道,请查看本人前面博客) B.客户机winxp一台,IP为1.1.1.100,用于邮件测试使用 1.邮件系统相关名称解释: MUA:Mail User Agent,邮件用户

Ubuntu之邮件服务器(Postfix, Dovecot, MySql)

前提 系统为 Ubuntu , 版本为14.04, 其他版本问题应该不大 系统 hostname 为 zjc - 详见设置linux主机名 ----- 此步非必须 $ sudo su # echo zjc > /etc/hostname # exit 系统IP地址为10.1.6.49 一些地址映射 要加入/etc/hosts文件或者DNS $ sudo apt-get install vim $ sudo vim /etc/hosts #自然,也可以用其他文本编辑器 #新添加的项 10.1.6.

邮件服务器postfix+dovecot+mysql

1.前期准备 1.1设置hostname CentOS7,可以通过hostnamectl set-hostname hostname命令设置hostname,并且修改hosts文件.这里域名是sijibao.info. hostnamectl set-hostname mail.sijibao.info 为什么要设置hostname呢?因为一般情况下,Postfix在与其他的SMTP服务器进行通信的时候,会使用hostname来表名自己的身份.主机名有两种形式,单名字与FQDN(Fully Qu

邮件服务系列之三实现postfix+dovecot+sasl

MRA :cyrus-imap,dovecot dovecot 依赖MySQL客户端 pop3协议监听tcp110 imap4协议监听tcp143端口 以明文方式工作需结合sasl来实现邮件传输加密 dovecot支持四种协议: pop3 imap4 pop3s imaps 配置文件位于:/etc/dovecot.conf 带有sasl认证能力 支持两种邮箱格式: mbox一个文件存储所有邮件 maildir:一个文件存储一封邮件,所有邮件存储在一个目录中 安装: yum install dov

Centos 下搭建电子邮箱服务器postfix+dovecot

因为同事在做一个电子邮件服务器,准备进行邮件推广什么的,后来遇到些问题,于是我们两个小白一起研究. 网上有很多关于电子邮件服务器搭建的.完整的文档.因此,一些具体的细节和配置,这里就不做详细的说明和解释了.主要讲的是我们两个小白花费大量时间,所查找到的,遇到的问题. 一.背景 postfix是Wietse Venema在IBM的GPL协议之下开发的MTA(邮件传输代理)软件. Dovecot 是一个开源的 IMAP 和 POP3 邮件服务器,支持 Linux/Unix 系统. 经典搭配: pos

Centos6 Postfix+Dovecot+Postfixadmin

本文介绍Centos6 Postfix+Dovecot+Postfixadmin+Roundcube 搭建过程,使用的是阿里云ESC CentOS 6.5 64位,配置hostname[code]#修改network文件vim /etc/sysconfig/networkHOSTNAME=mail.ali.com #添加本地hostsvim /etc/hosts112.74.28.201 mail.ali.com[/code][code]yum update[/code]创建一个vmail用户,