通常,WordPress发送邮件需要安装使用SMTP发信插件,比如Easy WP SMTP等。这些插件的使用使得WordPress加载速度变慢,且给WordPress增加了额外的安全风险(参考Easy WP SMTP之前著名的提权及代码执行漏洞)。
一个解决办法是在WordPress的网站服务器上再额外搭建一套邮件服务器。但是,这样的方法显得过于累赘,我们只需要让WordPress发送邮件,收发信的处理应当交由专门的邮件服务器来完成。因此,我们今天介绍使用SMTP邮件中继(SMTP Relay)实现WordPress无插件邮件发送。
本文翻译自LinuxBabe,本文作者为香菇肥牛,本文链接为https://qing.su/article/159.html, 转载需注明原文链接。谢谢!
1, 环境及基础设置
本文的测试环境为Ubuntu 20.04 LTS 64 bit (其他操作系统类似), WordPress域名为example.com, WordPress IP地址为88.88.88.88. WordPress所在服务器的主机名(服务器名)假设为server.example.com. WordPress所在的服务器的25端口可以被屏蔽,不影响发信。
用于发信的邮件服务器的主机名假设为mx.qing.su, 请自行替换为您自己的地址。您可以使用自己搭建的邮件服务器作为中继,也可以使用商业SMTP Relay服务(比如MailChannels, MailJet等等)。
如果您使用的是自己搭建的邮件服务器,请您在邮件服务器上添加好对应的域名example.com以及用户,比如hi@example.com.
您还需要做下列的DNS解析:
- 设置example.com MX记录,记录值任意,但是必须存在。
- 设置example.com SPF记录(TXT). 如果您使用的发信服务器是自己搭建的,您可以设置解析值为“v=spf1 a mx ip4:88.88.88.88 ~all”; 如果您使用的是商业SMTP Relay服务,请参考具体商家的SPF记录设定要求来设置。
- 设置server.exampe.com A记录解析到88.88.88.88.
做好解析之后,请登录您的WordPress服务器,设置好主机名。这里假设短主机名为server, 长主机名为server.example.com. 请注意,主机名不能设置成example.com, 否则邮件没有办法投递到SMTP中继服务器上,只能投递到WordPress服务器本身。另外,如果您WordPress域名和邮件服务器的根域名是同一个域名,则WordPress服务器的长主机名不要设置为和邮件服务器的长主机名相同。比如,我的邮件服务器的主机名为mx.qing.su, 如果我有另外一台WordPress服务器,网站域名也是qing.su, 那么这台WordPress服务器的长主机名就不能设置为mx.qing.su, 而可以设置为web.qing.su或者server.qing.su或者www.qing.su都可以。如果您不知道如何设置主机名,请参考我们的图文视频教程:https://qing.su/how-to-set-hostname
然后,我们就可以开始搭建邮件中继了。
2, 安装与配置Postfix
我们需要安装Postfix来实现SMTP中继。
1 | apt-get install postfix libsasl2-modules |
请注意,如果您的操作系统模板已经默认安装了Postfix, 您同样需要安装libsasl2-modules, 否则无法进行后续的SASL验证。
Postfix安装过程会出现下面几个界面。
在General type of mail configuration这个界面,我们需要选择Internet Site, 如下图。
然后,会出现System mail name的选项框,如果您的主机名设置正确,这里应该会自动填入您的长主机名,我们这里是server.example.com.
安装好之后就可以开始配置Postfix了。我们编辑文件/etc/postfix/main.cf:
找到下面这行:
1 | inet_interfaces = all |
改成:
1 | inet_interfaces = loopback-only |
这样的设置将使得Postfix仅监听本地请求,防止被他人利用。
接着配置中继,找到下面这行:
1 | relayhost = |
我们在后面填上邮件服务器的主机名与端口:
1 | relayhost = mx.qing.su:587 |
请注意,我们这里使用587作为邮件提交端口。在main.cf末尾添加下面几行,配置SASL验证信息:
1 2 3 4 5 | smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = may header_size_limit = 4096000 |
我们指明了SASL验证信息的配置文件位置为/etc/postfix/sasl_passwd. 我们编辑这个文件,按照下面的格式填写发信用户的SMTP用户名与密码。
1 | mx.qing.su:587 hi@example.com:password |
最后,我们hash生成验证信息,并重启Postfix使得更改生效。
1 2 3 | postmap /etc/postfix/sasl_passwd chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db service postfix restart |
如果您是按照我之前的教程搭建的iRedMail一键包,那么您还需要在邮件服务器上做一点更改。
编辑文件/opt/iredapd/settings.py (该文件没有写权限,需要chmod +w提权,编辑完毕后降权),在末尾添加下面一行:
1 | ALLOWED_LOGIN_MISMATCH_SENDERS = ['hi@example.com'] |
然后重启服务生效:
1 | service iredapd restart |
至此,我们已经配置好了SMTP中继。
3, 配置WordPress
配置WordPress之前,我们先简单介绍一下WordPress发邮件的两种方式。第一种是SMTP, 如果您安装了SMTP发信的插件,那么您的WordPress就是采用这种方式发信的。第二种是调用系统默认的sendmail. 由于我们已经配置好了SMTP邮件发送中继,因此,调用系统sendmail就会默认使用SMTP中继来发送邮件;换言之,我们只要卸载掉所有的SMTP发信插件,WordPress就会自动使用SMTP中继发送邮件。
但是,这样发送的邮件是有问题的。我们没有为WordPress指明发件人地址,因此发出来的邮件都是来自username@hostname. 比如,如果你用的是Nginx服务器,那么默认发件人可能是www-data@server.example.com; 如果你用的是Litespeed服务器,那么默认发件人可能是nobody@server.example.com. 我们希望通过根域名发信,比如使用hi@example.com这个地址,而不是hostname发信。我们还希望设置发件人姓名。
实现这一点,我们需要对WordPress的PHP代码做出一点替换。编辑您主题的functions.php文件,加入下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 | function wpb_sender_email( $original_email_address ) { return 'hi@example.com'; } function wpb_sender_name( $original_email_from ) { return '香菇肥牛'; } function fix_my_email_return_path( $phpmailer ) { $phpmailer->Sender = $phpmailer->From; } add_filter( 'wp_mail_from', 'wpb_sender_email' ); add_filter( 'wp_mail_from_name', 'wpb_sender_name' ); add_action( 'phpmailer_init', 'fix_my_email_return_path' ); |
保存后即可生效。使用mail-tester.com测试一下WordPress的SMTP中继邮件发送,评分为满分10分,如下图。
这里为了简便,没有再额外添加DMARC记录,如果需要了解如何添加,请参考上一篇文章https://qing.su/article/158.html.
4, 隐藏WordPress服务器IP
如果你使用的是自己搭建的邮件服务器,那么用SMTP中继发送邮件的时候,会在邮件头中留下WordPress服务器的IP地址,如果您的服务器藏在CDN之后,这样就会暴露源IP. 我们可以修改邮件服务器(不是WordPress服务器)的Postfix配置文件,丢弃掉这个IP地址的邮件头信息。新建文件/etc/postfix/smtp_header_checks, 添加下面的行:
1 | /^Received:/ IGNORE |
然后编辑邮件服务器的Postfix配置文件/etc/postfix/main.cf, 在末尾添加下面的行:
1 | smtp_header_checks = regexp:/etc/postfix/smtp_header_checks |
最后我们让配置生效:
1 2 | postmap /etc/postfix/smtp_header_checks service postfix restart |
至此,我们在WordPress服务器上使用Postfix搭建了SMTP邮件中继服务,这样WordPress就可以不通过插件直接使用SMTP发信,加快了发信和网页加载速度,也提升了安全性。如果您有任何疑问,欢迎在这里留言,我将尽力解答。本文作者为香菇肥牛,本文链接为https://qing.su/article/159.html, 转载需注明原文链接。谢谢!
这个方法配置的确更加专业了,我目前使用的办法是给服务器套一个ipv6地址,让邮件走ipv6出去(smtp有ipv6的情况),邮件头部就会有ipv6地址,且由于国内网络问题,这个ipv6地址很难从外部到达本机服务器,仅是单出不进。
牛逼,套IPv6这是骚操作啊
当时没想到办法,看到he.net的ipv6隧道就起了想法,就是速度慢点
大佬,我把你个转走呗
没问题,欢迎大佬转载
中继我配置完成了,但是最后那段代码咋个不启用呀?
最后那段代码是指WordPress替换的那段代码吗?如果不起用,可能是因为你的插件或者主题在其他地方控制了这几个环境变量
翻译得不错。
感觉大佬此文!虽然是翻译,但确实好用,留个评论支持一下!
感谢支持!