Centos6.x系统postfix + dovecot 邮箱系统搭建

缘起

    去年年底加了新的蚂蚁宝卡作为日常的流量卡,但老的号码用了快8年,不想轻易完全切换过去。奈何手机又是不支持双卡的渣渣,就把老卡扔就android机里,然后撸了个程序,把来电和短信通过邮件通知到新手机(实测手机端使用网易邮箱大师,邮件的通知速度超快,大约延迟只有30s的样子,足够满足日常使用)

    开始的一段时间用起来很好,直接通过一个139的邮箱,在老android机收到短信、电话后发送邮件到163邮箱,日常使用手机立马就收到邮件提醒了。

    最近这段时间,问题就来了,貌似139邮箱对于使用api进行邮箱外部操作有限制,数量多了之后再也不能发送邮件了。那么解决方法有2个,1、换个邮箱,再用个一段时间,然后又挂了 2、自己搭建一个邮箱系统。

    由于自己有vps,也有域名,也不想后面老是去换邮箱维护咯,那就自己撸一个邮箱系统吧,然后吭哧吭哧整了周末的2天,初步实现了需求。

    有一句槽,我一定要先说为快,现在中文的互联网上,技术资料真的是环境太差了!!搜来搜去,全是几篇原创文章的花式转载,更可恨的是,转载的人根本就没有自己试过,这对后来看的人简直是灾难。。。。坑死了!!!!


过程

    首先说说需求:

        1、要能实现邮件接收以及发送功能,这个是基础,否则根本没法用

        2、用户管理方面可以精简,大不了使用系统的用户系统来做就可以

        3、界面需求,可以不要界面,反正跑在vps上,设置好邮件客户端以及api调用就好


    基础功能安装过程

        通过调研,采用了postfix + dovecot搭建的邮箱服务器以及账户验证

        安装过程如下,基本照着做就好,做完就可以用了,转载自http://lomu.me/post/linux-email-server ,已验证可行

1.安装Postfix

yum -y install postfix

安装完成还需要替换系统自带的sendmail:

rpm -e sendmail
或者
yum remove sendmail

修改MTA(默认邮件传输代理)

alternatives --config mta

然后直接回车即可。

检查一下是不是已经设置成功了。

alternatives --display mta

第一行可以看到mta的状态。 例如:mat - status is manual.

2.安装Dovecot

yum -y install dovecot

3.配置Postfix

编辑/etc/postfix/main.cf,可以下载下来修改,也可以使用vi进行编辑:

vi /etc/postfix/main.cf

修改如下:

# 75行: 取消注释,设置hostname
myhostname = mail.yanke.info
# 83行: 取消注释,设置域名
mydomain = yanke.info
# 99行: 取消注释
myorigin = $mydomain
# 116行: 修改
inet_interfaces = all
# 119行: 推荐ipv4,如果支持ipv6,则可以为all
inet_protocols = ipv4
# 164行: 添加
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# 264行: 取消注释,指定内网和本地的IP地址范围
mynetworks = 127.0.0.0/8, 10.0.0.0/24
# 419行: 取消注释,邮件保存目录
home_mailbox = Maildir/
# 571行: 添加
smtpd_banner = $myhostname ESMTP
# 添加到最后
# 规定邮件最大尺寸为10M
message_size_limit = 10485760
# 规定收件箱最大容量为1G
mailbox_size_limit = 1073741824
# SMTP认证
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
# 限制通过smtp发信,接受者必须是验证过的用户
smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,reject
#防止恶意匿名登录发信
#延时拒绝
smtpd_delay_reject = yes
#发信时必须先登录, 默认不要加,加了别的邮箱不能往这个邮箱投递邮件,因为需要登录。。如果自用只发邮件,则可以设置
#smtpd_client_restrictions = permit_sasl_authenticated, reject
#发信人必须和登录用户匹配
smtpd_sender_restrictions = permit_mynetworks,  permit_sasl_authenticated,  reject_sender_login_mismatch, reject_authenticated_sender_login_mismatch, reject_unauthenticated_sender_login_mismatch
#中转时必须经过验证
smtpd_relay_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
#禁用VFRY
disable_vrfy_command = yes
#
# Requiring this will stop some UCE software. 
# (UCE = Unsolicited Commercial Email = SPAM)
#
smtpd_helo_required = yes

#
# Reject the request when the client HELO or EHLO parameter has a bad hostname syntax.
# reject_unknown_hostname value not recommended, because it may causes mail losting.
# (for example: after paypal.com registration you don't receive activation mail! I've tried it.)
#
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname

#防止暴力登录
#1min连接数
client_connection_rate_time_unit = 60s
smtpd_client_connection_count_limit = 5
smtpd_client_connection_rate_limit = 5
smtpd_client_message_rate_limit = 5
#当该错误计数器的值还很小时,postfix将暂停指定的时间,然后向客户端报告一个错误。该参数的缺省值为5秒。
smtpd_error_sleep_time = 10s
#当错误计数器的值超过该参数指定的值时,postfix在响应该客户端请求前将沉睡一段时间。缺省值为10。
smtpd_soft_error_limit = 3
#当错误计数器的值超过该参数指定的值时,postfix中断同该客户端的连接。缺省值为100。
smtpd_hard_error_limit = 3

修改好了之后使用/etc/rc.d/init.d/postfix start开启postfix,使用chkconfig postfix on将postfix开机启动。

4.配置Dovecot

修改如下:

vi /etc/dovecot/dovecot.conf
# 26行: 如果不使用IPv6,请修改为*listen = *

vi /etc/dovecot/conf.d/10-auth.conf
# 9行: 取消注释并修改
disable_plaintext_auth = no
# 97行: 添加auth_mechanisms = plain login

vi /etc/dovecot/conf.d/10-mail.conf
# 30行: 取消注释并添加
mail_location = maildir:~/Maildir

vi /etc/dovecot/conf.d/10-master.conf
# 88-90行: 取消注释并添加
# Postfix smtp验证
unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
}

到这里,我们的邮件服务器就已经搭建成功了,/etc/rc.d/init.d/dovecot start开启postfix,使用chkconfig dovecot on将dovecot开机启动

5.域名解析

最后别忘了还需要进行域名解析工作。

添加一个子域名mail,A记录解析到服务器IP。

再添加一个MX记录,主机记录为空,记录值为上面解析的二级域名mail.yanke.info,优先级10。

注意:解析生效可能需要一段时间,大约10分钟。

5.1增加spf记录

由于邮箱协议,诸如smtp原始协议里,是很精简的,对于来源邮箱是可以随意伪造的,所以一般的邮箱系统还会设置下spf记录,用来给其他邮箱系统查证,鉴别发送邮件的ip地址确实和邮箱的域名信息吻合,下面是设置方法

在dns解析里边添加一条txt记录,主机记录填@,类型txt,值填 诸如v=spf1 ip4:45.78.56.33 ~all 的值,其中的ip为你服务器的ip,这样过一会等解析生效就可以了。

spf验证,随便发一个邮件到163的邮箱,然后在收件地址的邮箱里查看源代码,诸如下面就表示spf已经通过

image.png

6.邮箱使用

一切都弄好以后,就可以使用Foxmail等第三方软件来收发邮件了。在这里需要说一下,系统用户就是邮件的用户,例如root,就是一个邮箱用户,邮箱是[email protected],密码就是root的密码,所以需要创建用户,只要使用useradd创建用户,再使用passwd设置密码。

好了,假如我们创建一个admin的用户:

# 创建用户
useradd admin
#设置密码,会要求输入两次密码
passwd admin

接下来登录邮箱客户端,这里使用ThunderBird作为客户端,如图:

image.png

这里需要注意,邮件账号是admin,并不是邮箱,另外我们没有配置SSL,所以也不要勾选。 接下来点击创建,如果一切正常的话,你已经成功了。

7.增加SSL支持

    通过上面的设置,我们已经初步有了一个可以收发邮件的邮箱(虽然可能被163之类的邮箱spm,但是基本可用了),但是呢,基本是无防护的裸奔着(任何人可以匿名telnet到你的服务器然后往你服务器内的邮箱用户发信,客户端发信完全明文不加密等等),各种限制策略没有加上去,根本不可靠。

    关于ssl的设置,只能说是太坑了,各种各样的配置方法,几乎没有一个教程是全面的,摸索了2天也是没有完全搞定的,方法贴在这里吧,算是简单总结

  编辑/etc/postfix/main.cf,在末尾加入开启ssl的代码,如下

#ssl
smtpd_tls_security_level = may
smtpd_tls_received_header = yes
smtpd_tls_auth_only = no
# loglevel 3 or 4 can be used for debugging purposes
smtpd_tls_loglevel = 1
# Path to certificate and key files
smtpd_tls_cert_file = /etc/postfix/myca/mailcert.pem
smtpd_tls_key_file = /etc/postfix/myca/mailkey.pem
smtp_tls_CAfile = /etc/postfix/myca/cacert.pem
smtpd_use_tls = yes
# Should the server announce it allows STARTTLS?
smtpd_tls_note_starttls_offer = yes
smtpd_tls_session_cache_timeout = 3600s
smtp_tls_cert_file = /etc/postfix/myca/mailcert.pem
smtp_tls_key_file = /etc/postfix/myca/mailkey.pem
smtp_tls_CAfile = /etc/postfix/myca/cacert.pem
smtp_use_tls = yes

其中服务器证书链可以通过一定方法生成,建议可以使用startssl或者Let‘s encrypt的签名方法,对你的邮箱域名(这里是mail.yanke.info)进行签名,然后拿到证书链。

通过上面的设置之后呢,我们的服务器相对稳定些了,通过查看日志,外部的服务器发送邮件会通过ssl加密传输。

问题:

    这里ssl设置太过复杂,上面的配置始终没能在我的邮件客户端使用成功,中途出过各种错误,什么签名不对啊,没找到签名啊,各种各样的错误,也有人说开启465加密端口,但是始终没有什么效果。


7.开启465加密smtp协议端口以及587端口

    可以通过编辑/etc/postfix/master.cf,取消注释并修改其中这几行,这样就开启了465安全smtp端口

smtps     inet  n       -       -       -       -       smtpd
    -o smtpd_tls_wrappermode=yes
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=permit_sasl_authenticated,reject

如果你的vps服务器封锁了25端口,那么你可能需要开启备用的587端口,功能和25端口一样,都是smtp端口,也是修改master.cf文件,取消注释并修改,这样就开了587端口

  smtp      inet  n       -       -       -       -       smtpd
  submission inet n       -       -       -       -       smtpd
    -o smtpd_tls_security_level=encrypt
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=permit_sasl_authenticated,reject

7.开启过滤验证功能

    前面也说了,通过上面的基础设置,我们的邮件服务器不设防,任何人可以匿名登录到服务器发信,这是很恐怖的,下面我们通过配置限制下,编辑/etc/postfix/main.cf,在末尾加入下面的配置

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,reject_unauth_destination
smtpd_delay_reject = yes
#发信时必须先登录, 默认不要加,加了别的邮箱不能往这个邮箱投递邮件,因为需要登录。。如果自用只发邮件,则可以设置
#smtpd_client_restrictions = permit_sasl_authenticated, reject
smtpd_sender_restrictions = permit_mynetworks,  permit_sasl_authenticated,  reject_sender_login_mismatch, reject_authenticated_sender_login_mismatch, reject_unauthenticated_sender_login_mismatch
smtpd_relay_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

#禁用VFRY
disable_vrfy_command = yes
#
# Requiring this will stop some UCE software. 
# (UCE = Unsolicited Commercial Email = SPAM)
#
smtpd_helo_required = yes

#
# Reject the request when the client HELO or EHLO parameter has a bad hostname syntax.
# reject_unknown_hostname value not recommended, because it may causes mail losting.
# (for example: after paypal.com registration you don't receive activation mail! I've tried it.)
#
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname

这样,通过设置, 匿名的人仍然可以telnet连接到服务器,但是在没有登录正式用户前,完全没有权限发送邮件,即使发送到服务器本地的用户,这样就比较安全了。

注意:不过一般不是这么简单粗暴的,这里通过设置smtpd_client_restrictions不完善,比较完善的是采用spf验证,递送邮件的服务器没有设置spf或者不正确,则不允许发信


8.开启安全性限制

    邮件服务开启没一个星期,遇到了好多ip不断的尝试auth login的暴力操作,估计是想拿试出服务器用户的密码吧,像下面着个越南猴子的一个ip,不停的在尝试登录,这个也是很危险的,相当于不设防的让人暴力破解密码,尤其是基础的拿服务器linux用户作为用户的postfix系统

lost connection after AUTH from mail.colliers.vn[118.69.244.124]
postfix/smtpd[5909]: disconnect from mail.colliers.vn[118.69.244.124]
postfix/smtpd[5956]: connect from mail.colliers.vn[118.69.244.124]
postfix/smtpd[5956]: warning: mail.colliers.vn[118.69.244.124]: SASL LOGIN authentication failed:

所以我们需要设置下,限制这种暴力的膜法♂登录,查了下,通过下面的设置就可以啦,通过设置连接以及错误次数频率,这种暴力的膜法♂再也没有用处了。设置项如下:

#防止暴力登录
#1min连接数
client_connection_rate_time_unit = 60s
smtpd_client_connection_count_limit = 5
smtpd_client_connection_rate_limit = 5
smtpd_client_message_rate_limit = 5
#当该错误计数器的值还很小时,postfix将暂停指定的时间,然后向客户端报告一个错误。该参数的缺省值为5秒。
smtpd_error_sleep_time = 10s
#当错误计数器的值超过该参数指定的值时,postfix在响应该客户端请求前将沉睡一段时间。缺省值为10。
smtpd_soft_error_limit = 3
#当错误计数器的值超过该参数指定的值时,postfix中断同该客户端的连接。缺省值为100。
smtpd_hard_error_limit = 3

总结

    关于这两个软件本身的配置,其实蛮简单的,尤其是根据下面第一篇文章的配置,已经基本可用。

    难点在于对于细节的完善,而这恰恰是网络上的教程最缺乏的,往往都是无脑转载,copy,paste。。。。

    最后,再一次吐槽网络上copy、paste,一点验证都不做,转来转去,完全是浪费后来人的时间,这点谨记于心

    最后,再一次吐槽网络上copy、paste,一点验证都不做,转来转去,完全是浪费后来人的时间,这点谨记于心

    最后,再一次吐槽网络上copy、paste,一点验证都不做,转来转去,完全是浪费后来人的时间,这点谨记于心


参考文章:

感谢下面的文章的作者,正是有了这些高质量,不是无脑转载的文章,才能为在问题面前苦苦搜寻解决方案的人带来一丝暖意(啊,呸,现在大夏天的,一丝丝凉爽才对。。)

1、http://lomu.me/post/linux-email-server 网上看到的教程里,最实用的一篇基础配置,文章风格也很好,赞?

2、https://blog.tiger-workshop.com/ubuntu-postfix-mail-server-msa-dovecot-smtp-authentication/ 繁文,通俗的讲了邮箱系统的原理以及构成,可以拿来看看补补理论

3、https://gist.github.com/martinmev/8248935 讲如何通用配置smtp,smtps的,其实就是基础配置

4、https://serverfault.com/questions/691795/how-to-force-postfix-smtp-to-use-auth-sasl-and-reject-anonymous-connections  讲如何限制客户端通过telnet登录后随意发信的

5、https://iwader.co.uk/post/postfix-force-smtp-authentication 讲如何设置smtp auth的,其实不全面,最全面的是什么我列的,综合了好多教程的设置

6、http://bbs.chinaunix.net/thread-1664576-1-1.html  讲如何生成邮箱服务器证书的,但是此篇有坑,谨慎再现网服务器使用

7、https://www.madboa.com/geek/openssl/#cs-smtp 讲怎么用OpenSSL连接服务器发信的,可以用来验证ssl设置是否生效

8、http://blog.csdn.net/jiary5201314/article/details/41957753 讲使用telnet发送邮件的,比较有意思,可以拿来玩一玩


发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。