兜兜    2017-08-17 23:44:13    2019-07-02 11:10:15   

   postfix postfixadmin dovecot TLS

`特别说明:阿里云、腾讯云等国内云主机和国外的vultr(禁止25端口)无法搭建,本测试使用的是搬瓦工的云主机.` 25端口封了能用465发信吗? https://www.yunrelay.com/news/mailnews/160485233926.html 搬瓦工网站(需翻墙): https://bandwagonhost.com/aff.php?aff=35573 购买优惠码: `BWH26FXH3HIQ` ### **软件版本** **`Centos`** `v6.9` **`postfix`** `v2.6.6` **`dovecot`** `v2.0.9` **`postfixadmin`** `v3.2` **`php`** `v5.5.38` **`mysql`** `v5.6.41-2.el6` **`apache`** `v2.2.15` &emsp; ### **0.检测主机是否可以搭建邮件服务器** `测试自己的服务器是否禁用了25端口` 服务器 ```bash $ telnet mx1.qq.com 25 #测试邮件服务器发送给其他域的邮件使用的端口是否禁封 $ yum install postfix -y #安装postfix $ grep ^inet_interfaces /etc/postfix/main.cf #查看监听地址 ``` ``` inet_interfaces = all ``` ```bash $ /etc/init.d/postfix restart #重启postfix $ netstat -tunlp |grep 25 #查看监听的地址和端口 ``` ``` tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 8470/master ``` 本地电脑 ```bash > telnet 邮件服务器ip 25 #测试其他域的邮件转发到本邮件服务器的端口是否禁封 ``` &emsp; ### **1.准备工作** #### 1.1 配置MX记录 ``` @ MX mail.unotes.co mail A 95.163.201.189 ``` #### 1.2申请Let’s Encrypt HTTPS安全证书(推荐阿里云申请免费证书) `注意:需要在拥有上面解析的公网ip地址的机器上执行该操作` ```bash $ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto $ ./certbot-auto certonly --standalone --email admin@unotes.co -d mail.unotes.co $ cd /etc/letsencrypt/live/mail.unotes.co/ $ ls * cert.pem chain.pem fullchain.pem privkey.pem README ``` chain.pem 为根证书 fullchain.pem 包含根证书的站点证书 privkey.pem 站点私钥 #### 1.3 安装LAMP环境(php>5.3.3,mysql>=5.6) 1.3.1 安装php webtatic仓库 ```bash $ rpm -Uvh http://repo.webtatic.com/yum/el6/latest.rpm ``` 1.3.2 安装mysql社区版仓库 ```bash $ rpm -Uvh http://repo.mysql.com/mysql-community-release-el6.rpm ``` 1.3.3 安装apache ```bash $ yum install httpd ``` 1.3.4 安装php ```bash $ yum --enablerepo=epel install php55w php55w-cli php55w-common php55w-gd php55w-intl php55w-ldap php55w-mbstring php55w-mcrypt php55w-mysql php55w-pdo php55w-pear php55w-pecl-imagick php55w-process php55w-xml php55w-imap openssl mod_ssl -y ``` 1.3.5 安装mysql5.6 ```bash $ yum --enablerepo=epel install mysql-community-server -y ``` 1.3.6 设置开机启动 ```bash $ chkconfig httpd on $ chkconfig mysqld on ``` 1.3.7 测试 ```bash $ vim /var/www/html/index.php ``` ``` <?php phpinfo(); ?> ``` 1.3.8 重启apache ```bash $ /etc/init.d/httpd restart ``` 1.3.9 浏览器访问ip地址 ![](https://files.ynotes.cn/18-8-17/30180853.jpg) &emsp; ### **2.安装postfixadmin** 2.1 下载postfixadmin ```bash $ wget https://sourceforge.net/projects/postfixadmin/files/postfixadmin/postfixadmin-3.2/postfixadmin-3.2.tar.gz/download $ tar xvf download -C /data/app $ mv postfixadmin-3.2 postfixadmin ``` 2.2 创建postfixadmin的数据库和用户 ```bash mysql>create database `postfix` CHARACTER SET utf8 COLLATE utf8_general_ci; mysql> grant all on postfix.* to postfix@'localhost' identified by 'postfix'; mysql> flush privileges; ``` 2.3 修改postfixadmin配置文件 ```bash $ cat /data/app/postfixadmin/config.inc.php ``` ```ini $CONF['configured'] = true; $CONF['database_type'] = 'mysql'; $CONF['database_host'] = 'localhost'; $CONF['database_user'] = 'postfix'; $CONF['database_password'] = 'postfix'; $CONF['database_name'] = 'postfix'; $CONF['admin_email'] = 'postmaster@unotes.co'; $CONF['encrypt'] = 'dovecot:CRAM-MD5'; $CONF['dovecotpw'] = "/usr/bin/doveadm pw"; $CONF['domain_path'] = 'YES'; $CONF['domain_in_mailbox'] = 'NO'; $CONF['smtp_server'] = 'mail.unotes.co'; $CONF['aliases'] = '1000'; $CONF['mailboxes'] = '1000'; $CONF['maxquota'] = '1000'; $CONF['fetchmail'] = 'NO'; $CONF['quota'] = 'YES'; $CONF['used_quotas'] = 'YES'; $CONF['new_quota_table'] = 'YES'; ``` 2.4 建立软链接 ```bash $ ln -s /data/app/postfixadmin/public/ /var/www/html/postfixadmin ``` 2.5 创建配置文件config.local.php和模板目录 ```bash $ touch config.local.php $ mkdir /data/app/postfixadmin/templates_c $ chmod 777 /data/app/postfixadmin/templates_c ``` ```bash $/etc/init.d/httpd restart ``` 2.6 访问postfixadmin http://your_postfixadmin_server_ip/postfixadmin/setup.php ![](https://files.ynotes.cn/18-8-18/86249152.jpg) ![](https://files.ynotes.cn/18-8-18/77916099.jpg) 2.7 修改安装密码 ```bash $ cat config.inc.php |grep setup_password ``` ``` $CONF['setup_password'] = '4dc9c805b408dac8b90261be15665114:58f1d787dxxxxxxxxxxxxxxx'; ``` ![](https://files.ynotes.cn/18-8-18/98191945.jpg) ![](https://files.ynotes.cn/18-8-18/60690959.jpg) 2.8 解决上面提示不能使用dovecotpw加密的问题 ```bash $yum install -y dovecot dovecot-devel dovecot-mysql ``` http://your_postfixadmin_server_ip/postfixadmin/login.php ![](https://files.ynotes.cn/18-8-18/91981830.jpg) &emsp; ### **3.安装和配置Postfix** 3.1 yum安装postfix ```bash $ yum install postfix -y $ chkconfig postfix on ``` 3.2 创建一个vmail用户,用作管理虚拟邮箱的文件夹 ```bash $ useradd -u 2000 -d /var/vmail -m -s /sbin/nologin vmail $ grep vmail/etc/passwd vmail::2000:2000::/var/vmail:/sbin/nologin ``` 3.3 配置Postfix #拷贝SSL证书到postfix对应目录 ```bash $ cp /etc/letsencrypt/live/mail.unotes.co/fullchian.pem /etc/postfix/ssl/mail.unotes.co.crt $ cp /etc/letsencrypt/live/mail.unotes.co/private.key /etc/postfix/ssl/mail.unotes.co.key $ cp /etc/letsencrypt/live/mail.unotes.co/chain.key /etc/postfix/ssl/ca.crt ``` 3.4 配置main.cf ```bash $cd /etc/postfix/ $ cat main.cf ``` ```ini #postfix目录和用户配置 queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/libexec/postfix data_directory = /var/lib/postfix mail_owner = postfix #配置hostname和域名 myhostname = mail.unotes.co mydomain = unotes.co myorigin = $mydomain #监控的接口(all表示所有)和协议 inet_interfaces = all inet_protocols = ipv4 #指定匹配邮件最终目的地的参数列表 mydestination = $myhostname, localhost.$mydomain, localhost #默认配置 unknown_local_recipient_reject_code = 550 alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases home_mailbox = Maildir/ debug_peer_level = 2 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.postfix newaliases_path = /usr/bin/newaliases.postfix mailq_path = /usr/bin/mailq.postfix setgid_group = postdrop html_directory = no manpage_directory = /usr/share/man sample_directory = /usr/share/doc/postfix-2.6.6/samples readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES #开启smtp client连接其他SMTP服务器的SSL/TLS配置 smtp_tls_security_level = may smtp_tls_loglevel = 1 smtp_tls_CAfile = /etc/postfix/ssl/ca.crt smtp_use_tls = yes #配置虚拟邮箱和域名配置 virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf #添加磁盘配置的支持 virtual_create_maildirsize = yes virtual_mailbox_extended = yes virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf virtual_mailbox_limit_override = yes virtual_maildir_limit_message = Sorry, this user has exceeded their disk space quota, please try again later. virtual_overquota_bounce = yes #指定邮件文件夹的所属用户和组 virtual_uid_maps = static:2000 virtual_gid_maps = static:2000 #Specifies which tables proxymap can read: http://www.postfix.org/postconf.5.html#proxy_read_maps proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps #smtp server SSL/TLS配置 smtpd_tls_security_level = may smtpd_tls_auth_only = yes smtpd_tls_cert_file = /etc/postfix/ssl/mail.unotes.co.crt smtpd_tls_key_file = /etc/postfix/ssl/mail.unotes.co.key smtpd_tls_loglevel = 0 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom #SASL认证相关配置 #使用dovecot认证 smtpd_sasl_type = dovecot #Microsoft Outlook 2007之前的版本兼容 broken_sasl_auth_clients = yes #SASL 的UNIX socket路径 smtpd_sasl_path = private/auth #开启SASL认证 smtpd_sasl_auth_enable = yes #禁用匿名登录,关闭open relay smtpd_sasl_security_options = noanonymous #客户端连接后以HELO显示送信方主机名称在此限制 smtpd_delay_reject = yes #smtpd_helo_required = yes #smtpd_helo_restrictions = # permit_mynetworks, # permit_sasl_authenticated, # reject_non_fqdn_helo_hostname, # reject_invalid_helo_hostname, # permit #寄件人名称限制, reject_authenticated_sender_login_mismatch和smtpd_sender_login_maps配合防止登录用户伪造发件人地址 smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unknown_sender_domain, smtpd_sender_login_maps = mysql:/etc/postfix/mysql_sender_login_maps.cf mysql:/etc/postfix/mysql_virtual_alias_maps.cf #收件人名称限制 smtpd_recipient_restrictions = reject_unauth_pipelining, reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_mynetworks, permit_sasl_authenticated, #check_policy_service unix:/var/spool/postfix/postgrey/socket reject_unauth_destination, permit #中继限制 smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination permit smtpd_client_restrictions = permit_sasl_authenticated #限制程序的参数 default_process_limit = 100 smtpd_client_connection_count_limit = 10 smtpd_client_connection_rate_limit = 30 queue_minfree = 20971520 header_size_limit = 51200 message_size_limit = 10485760 smtpd_recipient_limit = 100 #传输映射 virtual_transport = dovecot dovecot_destination_recipient_limit = 1 ``` 3.4 检查配置文件是否有错误 ```bash $ postconf ``` 3.5 创建Mysql脚本 ```bash $ cat /etc/postfix/mysql_virtual_domains_maps.cf ``` ```ini user = postfix password = postfix hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' ``` 3.6 postfix使用的sql配置文件 ```bash $ cat /etc/postfix/mysql_virtual_alias_maps.cf ``` ```ini user = postfix password = postfix hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1' ``` ```bash $ cat /etc/postfix/mysql_virtual_mailbox_maps.cf ``` ```ini user = postfix password = postfix hosts = localhost dbname = postfix query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1' ``` ```bash $ cat /etc/postfix/mysql_virtual_mailbox_limit_maps.cf ``` ```ini user = postfix password = postfix hosts = localhost dbname = postfix query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1' ``` ```bash $ cat /etc/postfix/mysql_sender_login_maps.cf ``` ```ini user = postfix password = postfix hosts = localhost dbname = postfix query = SELECT username FROM mailbox WHERE username='%s' AND active = '1' ``` 3.8 配置master.cf ```bash $ cat /etc/postfix/master.cf ``` ```ini #增加下面的配置 submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_client_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_client_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient} ``` &emsp; ### **4.安装和配置dovecot** 4.0 安装dovecot ```bash $ yum install -y dovecot dovecot-devel dovecot-mysql ``` 4.1 配置dovecot ```bash $ cat /etc/dovecot/dovecot.conf ``` ```ini protocols = imap pop3 listen = * dict { quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext } !include conf.d/*.conf ``` ```bash $ cat /etc/dovecot/conf.d/10-ssl.conf ``` ```ini ssl = yes ssl_cert = </etc/pki/dovecot/certs/mail.unotes.co.crt ssl_key = </etc/pki/dovecot/private/mail.unotes.co.key ``` 4.2 拷贝SSL证书到对应目录 ```bash $cp /etc/letsencrypt/live/mail.unotes.co/fullchian.pem /etc/pki/dovecot/certs/mail.unotes.co.crt $cp /etc/letsencrypt/live/mail.unotes.co/private.key /etc/pki/dovecot//etc/pki/dovecot/certs/mail.unotes.co.key ``` 4.3 配置认证 ```bash $ cat /etc/dovecot/conf.d/10-auth.conf ``` ```ini disable_plaintext_auth = yes auth_mechanisms = plain login cram-md5 !include auth-sql.conf.ext ``` 4.4 配置邮箱目录 ```bash $ cat /etc/dovecot/conf.d/10-mail.conf mail_location = maildir:%hMaildir mbox_write_locks = fcntl ``` 4.5 配置10-master.conf ```bash $ cat /etc/dovecot/conf.d/10-master.conf ``` ```ini service imap-login { inet_listener imap { } inet_listener imaps { } } service pop3-login { inet_listener pop3 { } inet_listener pop3s { } } service lmtp { unix_listener lmtp { } } service imap { } service pop3 { } service auth { unix_listener auth-userdb { mode = 0600 user = vmail group = vmail } unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } } service auth-worker { } service dict { unix_listener dict { mode = 0600 user = vmail group = vmail } } ``` 4.6 配置15-lda.conf ```bash $ cat /etc/dovecot/conf.d/15-lda.conf ``` ```ini protocol lda { mail_plugins = quota postmaster_address = postmaster@unotes.co } ``` 4.7 配置20-imap.conf ```bash $ cat /etc/dovecot/conf.d/20-imap.conf ``` ```ini protocol imap { mail_plugins = quota imap_quota } ``` 4.8 配置20-pop3.conf ```bash $ cat /etc/dovecot/conf.d/20-pop3.conf ``` ```ini protocol pop3 { pop3_uidl_format = %08Xu%08Xv mail_plugins = quota } ``` 4.9 配置90-quota.conf ```bash $ cat /etc/dovecot/conf.d/90-quota.conf ``` ```ini plugin { quota_rule = *:storage=1G } plugin { } plugin { quota = dict:User quota::proxy::quota } plugin { } ``` 4.10 配置dovecot-sql.conf.ext ```bash $ cat /etc/dovecot/dovecot-sql.conf.ext ``` ```ini driver = mysql connect = host=localhost dbname=postfix user=postfix password=postfix default_pass_scheme = CRAM-MD5 user_query = SELECT CONCAT('/var/vmail/', maildir) AS home, 2000 AS uid, 2000 AS gid, CONCAT('*:bytes=', quota) as quota_rule FROM mailbox WHERE username = '%u' AND active='1' password_query = SELECT username AS user, password, CONCAT('/var/vmail/', maildir) AS userdb_home, 2000 AS userdb_uid, 2000 AS userdb_gid, CONCAT('*:bytes=', quota) as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active='1' ``` 4.11 配置dovecot-dict-sql.conf.ext ```bash $ cat /etc/dovecot/dovecot-dict-sql.conf.ext ``` ```ini connect = host=localhost dbname=postfix user=postfix password=postfix map { pattern = priv/quota/storage table = quota2 username_field = username value_field = bytes } map { pattern = priv/quota/messages table = quota2 username_field = username value_field = messages } ``` 4.12 重启postfix ```bash $ /etc/init.d/postfix restart ``` 4.13 重启dovecot ```bash $ /etc/init.d/dovecot restart ``` 4.14 修改dovecot日志权限 ```bash $chmod 777 /var/log/dovecot.log ```    ### **5.Foxmail测试邮箱** ![](https://files.ynotes.cn/18-8-18/39545660.jpg) ![](https://files.ynotes.cn/18-8-18/60236610.jpg) &emsp; ### **6.Postfix日常维护命令** POSTFIX目录介绍 ```bash maildrop:本地邮件放置在maildrop中,同时也被拷贝到incoming中。 incoming:放置正在到达或队列管理进程尚未发现的邮件。 active:放置队列管理进程已经打开了并正准备投递的邮件,该队列有长度的限制。 deferred:放置不能被投递的邮件。 ``` POSTFIX日常维护常用命令 ```bash 启动postfix: postfix start 停止postfix: postfix stop 重新读取postfix配置文件: postfix reload 立即投递队列中所有邮件(慎用): postfix flush 查看队列邮件: postqueue -p mailq postqueue -p |tail ``` 删除队列邮件 ```bash 停用postfix,然后用mailq查id,最后用postsuper -d id号 如果要删除一类队列,如apache@domain.org,则要写一个脚本,举例如下: mailq | tail +2 | awk 'BEGIN { RS = "" } / apache@domain\.org$/ { print $1 }' | tr -d '*!' | postsuper -d - ``` 删除用户邮箱中的邮件 ```bash cd /var/vmail/域名/用户/Maildir/cur/ grep 邮件内容 * #查找需要删除的邮件 rm 邮件文件 ``` &emsp; ### **7.补充:** `问题1:portreserve占用993 110等端口,导致登录不了的问题(如下图)` ![](https://files.ynotes.cn/18-9-28/12073177.jpg) 解决方法: ```bash $ /etc/init.d/portreserve stop $ chkconfig portreserve off ``` `问题2:Recipient address rejected: User unknown in local recipient table` ```bash vim /etc/postfix/main.cf #添加下面的配置 ``` ```ini local_recipient_maps = ``` `问题3:搭建好邮件服务器后,/var/log/maillog报大量的lost connection after AUTH from unknown 分析:通过字面意思就可以知道,是由于客户端认证失败。`[`查询`](https://mxtoolbox.com/SuperTool.aspx)`这些ip基本都是邮件黑名单ip地址。` 解决方法: 1.修改客户端连接的连接比率,值为60s内连接的上限 ```bash $ /etc/postfix/main.cf ``` ```ini smtpd_client_connection_rate_limit = 300 ``` 2.增加恶意客户端检测脚本,并自动添加ip到防火墙(或者使用fail2ban) ```bash $ vim /root/check_blacklist.sh ``` ```bash LOG='/root/blacklist.log' tail -1000 /var/log/maillog|grep "lost connection after AUTH from"|awk '{ print $NF}'|sort|uniq -c|awk '{if($1>10){print $NF}}'|awk -F '[' '{print $2}'|sed s/.$//g|while read line;do /sbin/iptables -L -n |grep $line >/dev/null 2>&1 if [ $? -ne 0 ];then echo -e "`date ` 添加\033[31m ${line}\033[0m 到防火墙黑名单 [\033[32m OK \033[0m]" 2>&1 |tee -a $LOG /sbin/iptables -A INPUT -s $line -j DROP >>$LOG 2>&1 else echo -e "`date` \033[31m${line}\033[0m 已存在防火墙黑名单 [\033[31m Exist \033[0m]" fi done ``` 添加计划任务 ```bash $ crontab -e ``` ```bash * * * * * bash /root/check_blacklist.sh ``` 抓取的黑名单ip列表:https://files.ynotes.cn/ip_blacklist.txt

©著作权归作者所有:来自ynotes.cn笔记作者兜兜的原创作品,如需转载,请注明出处:https://ynotes.cn/blog/article_detail/143

文章分类: 服务器     个人分类: 邮件服务器

收藏


4 条评论
按时间正序 按时间倒序

1 2019-02-26 13:52:08

按照这个教程 成功搭建了postfix以及dovecot 非常详细!良心😝😝😝😝😝

       1人回复

作者 兜兜: @shajiashenhua

谢谢你的支持!😄

2019-02-26 13:54:28    回复

2 2019-05-21 10:20:53

我的域名申请了SSL证书,请问我该下载哪一个证书呢?下载APACHE的ssl证书么?

       1人回复

作者 兜兜: @865023784

如果是阿里云,申请nginx的就好了。

2019-05-22 09:45:20    回复

3 2019-05-27 17:33:35

完美的弄好了,谢谢猫哥!

       1人回复

作者 兜兜: @865023784

👍⁣👍⁣👍

2019-05-27 17:45:17    回复

4 2019-07-01 18:05:44

大佬,最后问个问题,用户的邮件该怎么删除啊?后面管理页面和用户后台都没有清理邮件的位置吧!

       2人回复

fred_zheng2: @作者 兜兜

还有一个小问题,用户创建完毕后,部分用户没有已发送邮件的文件夹,有的有那个文件夹,您遇到过么?😁

2019-07-23 14:18:23    回复

作者 兜兜: @865023784

用户的邮件存放在该目录下:/var/vmail/域名/用户/Maildir/cur,⁣删除对应用户的邮件即可

2019-07-02 10:13:12    回复