2

搭建邮箱服务器|安装Postfix与Dovecot|Ubuntu 18.04

Share
Avatar photo
  • 2022 年 4 月 20 日

在网上看了很多教程,在安装的过程中结合起了不下100个搜索结果,花费了一天一夜的时间终于用Postfix和Dovecot搭建起了邮件服务器,并且能够正常收发邮件,不被拦截了。

这篇文章包含以下内容:

  • 安装Postfix
  • 安装Dovecot
  • 配置以上两个软件
  • 配置SPF
  • 配置DKIM
  • 配置DMARC
  • 配置TLS

安装Postfix

很简单的一个流程,直接运行:

apt-get install postfix

安装Dovecot

也是很简单的一个流程,直接运行:

apt-get install dovecot

配置软件

这个环节是最死亡的,一天一夜时间基本都在配置这个软件。因为网上的教程参差不齐,每个人的版本都不一样,配置的过程中少说我查了不下500次log,最终才研究明白。

第一个软件:Postfix,Postfix提供SMTP发件服务,所以在某些程度上来讲,是比较重要的且比较不好配置的一个软件。

首先说明,我个人配置的软件,并未考虑到权限的因素在内,所以与很多教程都不一样,如果您不是个人使用,建议在网上查询相应教程。

我们先来编辑这个文件:

/etc/postfix/main.cf

nano /etc/postfix/main.cf

为了避免麻烦,我直接将整个文件复制上来

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

#default_privs = www-data
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
#SSL证书的配置
smtpd_tls_cert_file= /123/123/pem
smtpd_tls_key_file=/123/123.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_security_level = may
smtp_tls_security_level = may
#smtpd_tls_auth_only = yes

 # Virtual Mailbox Domain Settings 
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_limit = 51200000
#解释一下,我选择了uid为8的mail用户作为了操作用户,方便进行操作,不需要更改太多权限
virtual_minimum_uid = 8
virtual_uid_maps = static:8
virtual_gid_maps = static:8
virtual_mailbox_base = /var/mail
virtual_transport = virtual

 #SASL AS Dovecot to authenticate.
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
smtpd_sasl_authenticated_header = yes
smtpd_recipient_restrictions =permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, permit

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
#这里填写你的域名
myhostname = 123.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
#mydestination = $myhostname, #(这里别忘了改)123.com, localhost
mydestination =
relayhost = 
#mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mynetworks = 127.0.0.0/8
#mynetworks = all
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

#这里是DKIM的配置,如果不需要可以全部注释掉
smtpd_milters= inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
milter_protocol = 2

然后就是另一个文件

nano /etc/postfix/master.cf

这里的配置我发成一个图片吧

Postfix – master.cf配置文件

然后我们需要在/etc/postfix目录下创建三个新文件:

第一个:mysql_virtual_alias_maps.cf

user = MYSQL用户名
password = MYSQL密码
hosts = MYSQL地址
dbname = Postfix的数据库名
table = alias
select_field = goto
where_field = address

第二个:mysql_virtual_mailbox_maps.cf

user = MYSQL用户名
password = MYSQL密码
hosts = MYSQL地址
dbname = Postfix的数据库名
table = mailbox
select_field = maildir
where_field = username

第三个:mysql_virtual_domains_maps.cf

user = MYSQL用户名
password = MYSQL密码
hosts = MYSQL地址
dbname = Postfix的数据库名
table = domain
select_field = domain
where_field = domain

最后我们重启一下Postfix

service postfix restart

然后我们安装Postfix-admin

apt-get install postfix-admin

安装好了我们可以把他软链接到网站目录下

ln -s /usr/share/postfixadmin /你的网站目录

然后访问就可以开始在网站上配置了。


第二个软件:就是Dovecot,同样也不简单

首先在/etc/dovecot/dovecot.conf中加入一行

protocols = imap pop3 lmtp

然后配置/etc/dovecot/dovecot-sql.conf.ext

# This file is commonly accessed via passdb {} or userdb {} section in
# conf.d/auth-sql.conf.ext

# This file is opened as root, so it should be owned by root and mode 0600.
#
# http://wiki2.dovecot.org/AuthDatabase/SQL
#
# For the sql passdb module, you'll need a database with a table that
# contains fields for at least the username and password. If you want to
# use the user@domain syntax, you might want to have a separate domain
# field as well.
#
# If your users all have the same uig/gid, and have predictable home
# directories, you can use the static userdb module to generate the home
# dir based on the username and domain. In this case, you won't need fields
# for home, uid, or gid in the database.
#
# If you prefer to use the sql userdb module, you'll want to add fields
# for home, uid, and gid. Here is an example table:
#
# CREATE TABLE users (
#     username VARCHAR(128) NOT NULL,
#     domain VARCHAR(128) NOT NULL,
#     password VARCHAR(64) NOT NULL,
#     home VARCHAR(255) NOT NULL,
#     uid INTEGER NOT NULL,
#     gid INTEGER NOT NULL,
#     active CHAR(1) DEFAULT 'Y' NOT NULL
# );

# Database driver: mysql, pgsql, sqlite
# 这里选择你的数据库类型
driver = mysql

# Database connection string. This is driver-specific setting.
#
# HA / round-robin load-balancing is supported by giving multiple host
# settings, like: host=sql1.host.org host=sql2.host.org
#
# pgsql:
#   For available options, see the PostgreSQL documention for the
#   PQconnectdb function of libpq.
#   Use maxconns=n (default 5) to change how many connections Dovecot can
#   create to pgsql.
#
# mysql:
#   Basic options emulate PostgreSQL option names:
#     host, port, user, password, dbname
#
#   But also adds some new settings:
#     client_flags           - See MySQL manual
#     connect_timeout        - Connect timeout in seconds (default: 5)
#     read_timeout           - Read timeout in seconds (default: 30)
#     write_timeout          - Write timeout in seconds (default: 30)
#     ssl_ca, ssl_ca_path    - Set either one or both to enable SSL
#     ssl_cert, ssl_key      - For sending client-side certificates to server
#     ssl_cipher             - Set minimum allowed cipher security (default: HIGH)
#     ssl_verify_server_cert - Verify that the name in the server SSL certificate
#                              matches the host (default: no)
#     option_file            - Read options from the given file instead of
#                              the default my.cnf location
#     option_group           - Read options from the given group (default: client)
# 
#   You can connect to UNIX sockets by using host: host=/var/run/mysql.sock
#   Note that currently you can't use spaces in parameters.
#
# sqlite:
#   The path to the database file.
#
# Examples:
#   connect = host=192.168.1.1 dbname=users
#   connect = host=sql.example.com dbname=virtual user=virtual password=blarg
#   connect = /etc/dovecot/authdb.sqlite
#
#这条是数据库连接配置信息
connect = host=数据库地址 dbname=数据库名 user=数据库用户名 password=数据库密码

# Default password scheme.
#
# List of supported schemes is in
# http://wiki2.dovecot.org/Authentication/PasswordSchemes
#
default_pass_scheme = MD5-CRYPT

# passdb query to retrieve the password. It can return fields:
#   password - The user's password. This field must be returned.
#   user - user@domain from the database. Needed with case-insensitive lookups.
#   username and domain - An alternative way to represent the "user" field.
#
# The "user" field is often necessary with case-insensitive lookups to avoid
# e.g. "name" and "nAme" logins creating two different mail directories. If
# your user and domain names are in separate fields, you can return "username"
# and "domain" fields instead of "user".
#
# The query can also return other fields which have a special meaning, see
# http://wiki2.dovecot.org/PasswordDatabase/ExtraFields
#
# Commonly used available substitutions (see http://wiki2.dovecot.org/Variables
# for full list):
#   %u = entire user@domain
#   %n = user part of user@domain
#   %d = domain part of user@domain
# 
# Note that these can be used only as input to SQL query. If the query outputs
# any of these substitutions, they're not touched. Otherwise it would be
# difficult to have eg. usernames containing '%' characters.
#
# Example:
#   password_query = SELECT userid AS user, pw AS password \
#     FROM users WHERE userid = '%u' AND active = 'Y'
#
#password_query = \
#  SELECT username, domain, password \
#  FROM mailbox WHERE username = '%n' AND domain = '%d'

#这里是用来验证用户密码的,如果你和我的没区别就不需要改
password_query = \
   SELECT username as user, password \
   FROM mailbox WHERE username = '%u'

# userdb query to retrieve the user information. It can return fields:
#   uid - System UID (overrides mail_uid setting)
#   gid - System GID (overrides mail_gid setting)
#   home - Home directory
#   mail - Mail location (overrides mail_location setting)
#
# None of these are strictly required. If you use a single UID and GID, and
# home or mail directory fits to a template string, you could use userdb static
# instead. For a list of all fields that can be returned, see
# http://wiki2.dovecot.org/UserDatabase/ExtraFields
#
# Examples:
#   user_query = SELECT home, uid, gid FROM users WHERE userid = '%u'
#   user_query = SELECT dir AS home, user AS uid, group AS gid FROM users where userid = '%u'
#   user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u'
#
#这里是用来获取用户信息的,尽量不用改
user_query = \
  SELECT ('8') as 'uid',('8') as 'gid'

# If you wish to avoid two SQL lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll
# also have to return userdb fields in password_query prefixed with "userdb_"
# string. For example:
#password_query = \
#  SELECT userid AS user, password, \
#    home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \
#  FROM users WHERE userid = '%u'

# Query to get a list of all usernames.
#iterate_query = SELECT username AS user FROM users

然后更改/etc/dovecot/conf.d/10-auth.conf,只更改这里写到的:

#这里是加上一个
auth_mechanisms = plain login

#这里是删掉这两行前面的注释
!include auth-system.conf.ext
!include auth-sql.conf.ext

如果有ssl配置,更改10-ssl.conf

ssl = yes
ssl_cert = <证书地址
ssl_key = <证书地址

在这里需要注意!!!!你的证书一定要一个完整的证书链才能够使用TLS的加密方式!!!

10-mail.conf

mail_location = maildir:/var/mail/dovecot/%d/%n:INBOX=/var/mail/%d/%n

10-master.conf的话就是整个复制上来了

#default_process_limit = 100
#default_client_limit = 1000

# Default VSZ (virtual memory size) limit for service processes. This is mainly
# intended to catch and kill processes that leak memory before they eat up
# everything.
#default_vsz_limit = 256M

# Login user is internally used by login processes. This is the most untrusted
# user in Dovecot system. It shouldn't have access to anything at all.
#default_login_user = dovenull

# Internal user is used by unprivileged processes. It should be separate from
# login user, so that login processes can't disturb other processes.
#default_internal_user = dovecot

service imap-login {
  inet_listener imap {
    #port = 143
  }
  inet_listener imaps {
    #port = 993
    #ssl = yes
  }

  # Number of connections to handle before starting a new process. Typically
  # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
  # is faster. <doc/wiki/LoginProcess.txt>
  #service_count = 1

  # Number of processes to always keep waiting for more connections.
  #process_min_avail = 0

  # If you set service_count=0, you probably need to grow this.
  #vsz_limit = $default_vsz_limit
}

service pop3-login {
  inet_listener pop3 {
    #port = 110
  }
  inet_listener pop3s {
    #port = 995
    #ssl = yes
  }
}

service lmtp {
  unix_listener lmtp {
    #mode = 0666
  }

  # Create inet listener only if you can't use the above UNIX socket
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port = 
  #}
}

service imap {
  # Most of the memory goes to mmap()ing files. You may need to increase this
  # limit if you have huge mailboxes.
  #vsz_limit = $default_vsz_limit

  # Max. number of IMAP processes (connections)
  #process_limit = 1024
}

service pop3 {
  # Max. number of POP3 processes (connections)
  #process_limit = 1024
}

service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  unix_listener auth-userdb {
    mode = 0666
    #user = 
    #group = 
  }

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    #user = root
  }

  # Auth process is run as this user.
  #user = $default_internal_user
}

service auth-worker {
  # Auth worker process is run as root by default, so that it can access
  # /etc/shadow. If this isn't necessary, the user should be changed to
  # $default_internal_user.
  user = root
}

service dict {
  # If dict proxy is used, mail processes should have access to its socket.
  # For example: mode=0660, group=vmail and global mail_access_groups=vmail
  unix_listener dict {
    #mode = 0600
    #user = 
    #group = 
  }
}

然后我们就重启这两个软件就好了。

我们这个时候在postfix-admin网站上创建个账户,然后用手机或者电脑的邮件客户端测试一下是否可以正常使用。

log文件在/var/log/mail.log,建议有问题立刻查看,非常有用。

配置SPF

在域名解析记录中添加以下内容:

  • 解析类型:TXT
  • 主机记录:@
  • 记录值:v=spf1 a ip4:服务器的ip地址 ~all

这个记录值有很多种配置方法,如果有ipv6地址的话,就需要改成

v=spf1 a ip4:ipv4地址 ip6:ipv6地址 ~all

有特殊需求的话可以在网上找到SPF记录配置方法,这里就不做赘述了。

配置DKIM(转载)

转载自:https://www.cnblogs.com/jifeng/p/6501376.html

1、Ip反向解析,找isp添加一条IP到mail.domain.com记录

2.为postfix添加dkim认证:(http://blog.eqoe.cn/posts/build-perfect-mail-server.html)  http://www.mail-tester.com/

apt-get install opendkim

安装完毕后,修改opendkim配置文件 

vim /etc/opendkim.conf,将以下内容复制到文件末尾,保存

AutoRestart             Yes
AutoRestartRate         10/1h
LogWhy                  Yes
Syslog                  Yes
SyslogSuccess           Yes
Mode                    sv
Canonicalization        relaxed/simple
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
SignatureAlgorithm      rsa-sha256
Socket                  inet:8891@localhost
PidFile                 /var/run/opendkim/opendkim.pid
UMask                   022
UserID                  opendkim:opendkim
TemporaryDirectory      /var/tmp

将接下来步骤的所有 test.com 替换成你自己的域名

mkdir /etc/opendkim/keys/test.com  新建域名目录
opendkim-genkey -D /etc/opendkim/keys/test.com/ -d test.com -s default  生成随机密钥
chown -R opendkim: /etc/opendkim/keys/test.com  将目录所有者改为opendkim
cp /etc/opendkim/keys/test.com/default.private /etc/opendkim/keys/test.com/default 复制一份,来作为私钥(不改直接用default.private也可以)

chown opendkim default 将复制的default文件的所有者改为opendkim(若不改发送邮件会显示没有权限)

把test.com添加到/etc/opendkim/KeyTable

default._domainkey.test.com test.com:default:/etc/opendkim/keys/test.com/default

修改/etc/opendkim/SigningTable并添加如下记录

*@test.com default._domainkey.test.com

添加信任主机到/etc/opendkim/TrustedHosts:

127.0.0.1
test.com

添加txt记录(基本就是default.txt中的内容)

配置完毕后,可以在http://dkimcore.org/tools/进行检测

配置成功,下面为postfix添加dkim认证:

修改postfix的main.cf文件,vim /etc/postfix/main.cf

smtpd_milters           = inet:127.0.0.1:8891
non_smtpd_milters       = $smtpd_milters
milter_default_action   = accept
milter_protocol         = 2

配置完毕后重启postfix服务,启动opendkim服务

service postfix reload 重启postfix

service opendkim start 启动opendkim服务

dkim配置完毕

通过之前使用的phpmailer继续像gmail邮箱发送邮件,并查看原始邮件

显示dkim:pass,配置完成

3.阿里云直接提交工单进行反向解析

至此全部配置完毕,邮件发送完成。

ps:在完成spf,dkim,反向解析之后,测试邮箱均能正常接收服务器发送的邮件,但是QQ邮箱依旧无法接收被拦截,查看log文件依旧提示550 ip受限,希望解决了这个的人能在下面留言给我点帮助。。

ps:在联系腾讯客服反馈问题后,问题得到解决,现在QQ邮箱能够正常接收邮件。

配置DMARC

在域名解析记录中添加

  • 记录:_dmarc
  • 类型:TXT
  • 记录值:v=DMARC1; p=none; rua=mailto:dmarc-reports@domain.com

把domain.com换成你的域名

配置TLS

在上述配置文件中,已经包含了TLS的配置信息,就不再做过多陈述了。