主要参(chao)照(xi)了以下两篇教程。感谢踩坑的前人!
危险! 这个方案并不可靠!邮箱服务由其他提供商托管更加安全!
需要配置的东西 域名证书 使用 Let’s Encrypt 的免费证书,我使用 acme.sh 来获取。 申请 DNS 服务商的 API 密钥就能实现自动化续签了,还不用 root 权限。
反向 DNS 记录 反向记录所指向的域名应该和你的 MX 记录一致。没有这个记录,你发出的邮件永远进不了 Gmail 邮箱。对于 VPS ,一般在后台进行设置,或者发工单请求。国内运营商就需要向你的 ISP 申请添加,周期长还要收费。
DNS 记录 MX 记录 一般形式:名称为@,内容为另一个域名/子域名/ IP,如mail.example.com 用于告知其他邮件服务器向这一地址投递。
SPF 记录 一般形式:名称为@,内容为v=spf1 a mx ip4:IPv4地址 ip6:IPv6地址 ~all 用于声明会发出邮件的 IP 地址,防止他人伪造。填写v=spf1 +all相当于不填,填写v=spf1 -all则对外声明服务器不会发送任何邮件。
DKIM 记录 名称为密钥名._domainkey(.子域名),例如mail.example.com的 DKIM 记录名可以是default._domainkey.mail。内容之后从 OpenDKIM 生成的 txt 中获得。 截取公钥文件括号中v=DKIM1; h=sha256; k=rsa; s=email; p=超长字符串部分,删去所有引号以及p=部分中间的空格,即为 DKIM 公钥。
DMARC 记录(可选) 一般形式:名称为_dmarc,内容为v=DMARC1;p=quarantine;sp=quarantine;adkim=s;aspf=s 用于声明服务器使用 SPF 和 DKIM 的情况,并给出邮件检验失败的建议处理策略。上例声明了服务器发出的邮件使用 SPF 所示地址,并拥有 DKIM 签名,若检验不通过则建议标记为垃圾邮件。
ADSP 记录(可选) 一般形式:名称为_adsp._domainkey,内容为dkim=all。添加此记录则对外声明所有发出的邮件使用 DKIM 签名。
Postfix 服务端使用的是 Ubuntu ,首先安装需要的软件包。
1 apt-get install postfix postfix-mysql postfix-pcre postfix-policyd-spf-python dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql opendkim opendkim-tools
安装时会弹出 Postfix 的初始设置界面,选择Internet Site选项,然后输入你的邮件服务器(MX记录填写的)域名。 安装完以后把 Postfix 的账户加入到OpenDKIM的组里去。
1 usermod -aG opendkim postfix
编辑/etc/postfix/master.cf 在最底端加入如下内容:
/etc/postfix/master.cf 1 2 policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf
然后向上滚动,找到并取消注释以下内容,不同的编辑一下:
/etc/postfix/master.cf 1 2 3 4 5 6 submission inet n - y - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
编辑/etc/postfix/main.cf 危险! 这里的认证设置不完善,SMTP发信服务将会被滥用!
添加如下内容:
/etc/postfix/main.cf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # TLS 加密策略 smtpd_tls_security_level = may smtp_tls_security_level = may # 支持中文需要 SMTPUTF8 smtputf8_enable = yes smtputf8_autodetect_classes = sendmail, verify #中转规则 smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination policyd-spf_time_limit = 3600 # Milter configuration # OpenDKIM相关 milter_default_action = accept # Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2 milter_protocol = 6 smtpd_milters = local:opendkim/opendkim.sock non_smtpd_milters = local:opendkim/opendkim.sock # 使用Dovecot认证 smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_auth_enable = yes virtual_transport = lmtp:unix:private/dovecot-lmtp # 读取虚拟表 local_recipient_maps = $virtual_mailbox_maps virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf virtual_alias_maps = hash:/etc/postfix/valias
其中找到smtpd_recipient_restrictions条目,编辑为如下形式:
/etc/postfix/main.cf 1 2 3 4 smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policyd-spf
不要添加多个,否则只识别最后一条。其中的内容是顺序执行的,不要调换。
以及找到下面这些条目并编辑为相应值:
/etc/postfix/main.cf 1 2 3 4 5 mydestination = localhost smtpd_tls_cert_file=你的证书目录/fullchain.cer smtpd_tls_key_file=你的证书目录/域名.key smtpd_use_tls=yes smtpd_tls_auth_only = yes
把mydestination改成这样是因为后面设置了virtual_domain,同一个域名设置两次会失效。 参考官方文档
(可选)编辑/etc/postfix/valias 内容如下:
/etc/postfix/valias
然后执行postmap /etc/postfix/valias 。此域名收到的所有邮件都会被转发给[email protected] 。这样就可以给每个网站单独设置邮箱名称,看是谁把你的邮箱信息泄露出去了。 关于virtual_alias的更多用法,请参考上面的官方文档。
OpenDKIM 创建/etc/opendkim.conf 输入以下内容:
/etc/opendkim.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # This is a basic configuration that can easily be adapted to suit a standard # installation. For more advanced options, see opendkim.conf(5) and/or # /usr/share/doc/opendkim/examples/opendkim.conf.sample. # Log to syslog Syslog yes # Required to use local socket with MTAs that access the socket as a non- # privileged user (e.g. Postfix) UMask 007 # OpenDKIM user # Remember to add user postfix to group opendkim UserID opendkim:opendkim # Map domains in From addresses to keys used to sign messages KeyTable /etc/opendkim/key.table SigningTable refile:/etc/opendkim/signing.table # Hosts to ignore when verifying signatures ExternalIgnoreList /etc/opendkim/trusted.hosts InternalHosts /etc/opendkim/trusted.hosts # Commonly-used options; the commented-out versions show the defaults. Canonicalization relaxed/simple Mode sv SubDomains no #ADSPAction continue AutoRestart yes AutoRestartRate 10/1M Background yes DNSTimeout 5 SignatureAlgorithm rsa-sha256 # Always oversign From (sign using actual From and a null From to prevent # malicious signatures header fields (From and/or others) between the signer # and the verifier. From is oversigned by default in the Debian package # because it is often the identity key used by reputation systems and thus # somewhat security sensitive. OversignHeaders From Socket /var/spool/postfix/opendkim/opendkim.sock
创建配置文件目录和 Socket 目录,调整权限:
1 2 3 4 mkdir /etc/opendkim mkdir /etc/opendkim/keys mkdir /var/spool/postfix/opendkim chown opendkim:postfix /var/spool/postfix/opendkim
生成 DKIM 密钥:
1 2 cd /etc/opendkim/keys opendkim-genkey -b 2048 -h rsa-sha256 -r -s 密钥名 -d example.com -v
此时执行
1 cat /etc/opendkim/keys/密钥名.txt
就能获取 DKIM 公钥内容,添加到 DNS 记录里去了。
创建/etc/opendkim/trusted.hosts 内容如下:
/etc/opendkim/trusted.hosts 1 2 3 4 5 127.0.0.1 ::1 localhost mail.example.com example.com
如果直接由根域名提供服务,删掉子域名那行,下面两个文件则去掉中间的 mail 。
创建/etc/opendkim/signing.table 内容如下:
/etc/opendkim/signing.table 1 *@example.com 密钥名._domainkey.mail.example.com
创建/etc/opendkim/key.table 内容如下:
/etc/opendkim/key.table 1 密钥名._domainkey.mail.example.com mail.example.com:密钥名:/etc/opendkim/keys/密钥名.private
设置文件权限 1 2 3 chmod u=rw,go=r /etc/opendkim.conf chown -R opendkim:opendkim /etc/opendkim chmod go-rw /etc/opendkim/keys
Dovecot 完全拷贝注意! 下面的内容除了加密算法有修改以外,完全是拷贝来的。 请考虑 阅读原文 ,打赏原作者
建立一个数据库:
1 2 3 CREATE DATABASE 数据库名;GRANT ALL PRIVILEGES ON 数据库名.* TO '用户名' @'localhost' IDENTIFIED BY '密码' ;FLUSH PRIVILEGES;
建立虚拟域表,接收对应域名的邮件:
1 2 3 4 5 6 7 8 CREATE TABLE 'virtual_domains' ('id' INT NOT NULL AUTO_INCREMENT,'name' VARCHAR (50 ) NOT NULL ,PRIMARY KEY ('id' )) ENGINE= InnoDB DEFAULT CHARSET= utf8; insert into virtual_domains values (1 ,'example.com' )
创建虚拟用户表,用于用户认证:
1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE 'virtual_users' ('id' INT NOT NULL AUTO_INCREMENT,'domain_id' INT NOT NULL ,'password' VARCHAR (106 ) NOT NULL ,'email' VARCHAR (120 ) NOT NULL ,PRIMARY KEY ('id' ),UNIQUE KEY 'email' ('email' ),FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE) ENGINE= InnoDB DEFAULT CHARSET= utf8; insert into virtual_users values (1 ,1 ,SHA2('邮箱密码' ,256 ),'[email protected] ' );
创建/etc/postfix/mysql-virtual-mailbox-domains.cf 内容如下:
/etc/postfix/mysql-virtual-mailbox-domains.cf 1 2 3 4 5 6 user = 用户名 password = 密码 port = 3306 hosts = 127.0.0.1 dbname = 数据库名 query = SELECT 1 FROM virtual_domains WHERE name='%s'
创建/etc/postfix/mysql-virtual-mailbox-maps.cf 内容如下:
/etc/postfix/mysql-virtual-mailbox-maps.cf 1 2 3 4 5 6 user = 用户名 password = 密码 port = 3306 hosts = 127.0.0.1 dbname = 数据库名 query = SELECT 1 FROM virtual_users WHERE email='%s'
编辑/etc/dovecot/dovecot.conf 确保如下内容存在且正确:
/etc/dovecot/dovecot.conf
然后在最后添加:
/etc/dovecot/dovecot.conf 1 protocols = imap lmtp pop3
修改/etc/dovecot/conf.d/10-mail.conf 确保如下内容存在且正确:
/etc/dovecot/conf.d/10-mail.conf 1 2 mail_location = maildir:/var/mail/vhosts/%d/%n mail_privileged_group = mail
然后执行以下命令更改/var/mail的所属:
1 2 3 groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /var/mail chown -R vmail:vmail /var/mail
修改/etc/dovecot/conf.d/10-auth.conf 确保如下内容存在且正确:
/etc/dovecot/conf.d/10-auth.conf 1 2 disable_plaintext_auth = yes auth_mechanisms = plain login
修改/etc/dovecot/conf.d/auth-sql.conf.ext 对应内容改成下面这样:
/etc/dovecot/conf.d/auth-sql.conf.ext 1 2 3 4 5 6 7 8 passdb { driver = sql args = /etc/dovecot/dovecot-sql.conf.ext } userdb { driver = static args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n }
修改/etc/dovecot/dovecot-sql.conf.ext 取消driver行的注释,将值设置为mysql:
/etc/dovecot/dovecot-sql.conf.ext
取消connect行的注释,添加数据库连接信息:
/etc/dovecot/dovecot-sql.conf.ext 1 connect = host=127.0.0.1 port=3306 dbname=数据库名 user=用户名 password=密码
取消default_pass_scheme行的注释,将值设置为SHA256:
/etc/dovecot/dovecot-sql.conf.ext 1 default_pass_scheme = SHA256
取消password_query行的注释,添加查询语句:
/etc/dovecot/dovecot-sql.conf.ext 1 password_query = SELECT email as user , password FROM virtual_users WHERE email= '%u'
修改/etc/dovecot的权限:
1 2 chown -R vmail:dovecot /etc/dovecot chmod -R o-rwx /etc/dovecot
修改/etc/dovecot/conf.d/10-master.conf: 将 imap-login , pop3-login 下第一个的 port 设置为 0,只使用 SSL 加密的 IMAPS 和 POP3S 。最终结果类似如下内容:
/etc/dovecot/conf.d/10-master.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 service imap-login { inet_listener imap { port = 0 #port = 143 } inet_listener imaps { #port = 993 #ssl = yes } } service pop3-login { inet_listener pop3 { port = 0 #port = 110 } inet_listener pop3s { #port = 995 #ssl = yes } }
然后找到service lnmp,对应内容修改为如下所示:
/etc/dovecot/conf.d/10-master.conf 1 2 3 4 5 6 7 service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix } }
然后找到service auth,对应内容修改为如下所示:
/etc/dovecot/conf.d/10-master.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 service auth { unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } unix_listener auth-userdb { mode = 0600 user = vmail #group = } user = dovecot }
最后找到service auth-worker,对应内容修改为如下所示:
/etc/dovecot/conf.d/10-master.conf 1 2 3 service auth-worker { user = vmail }
修改/etc/dovecot/conf.d/10-ssl.conf 将对应内容修改为如下所示:
/etc/dovecot/conf.d/10-ssl.conf 1 2 3 ssl = required ssl_cert = <你的证书目录/fullchain.cer ssl_key = <你的证书目录/域名.key
万里长征的最后一步 启用所有服务
1 2 3 4 5 6 systemctl enable opendkim systemctl enable dovecot systemctl enable postfix systemctl start opendkim systemctl start dovecot systemctl start postfix
用 Ubuntu 自带防火墙 UFW 开启对应端口
1 2 3 4 5 ufw allow 25 ufw allow 587 ufw allow 993 ufw allow 995 ufw reload
现在就可以打开邮件客户端,添加账户,自由地收发邮件了。