经过多次搬迁,论坛如风中摇曳的蜡烛一样艰难地存活了,虽然仍有不少错误,但基本能用就已经让我感到欣慰了。
在目前已知的漏洞中,不能发送邮件成运行最大阻碍(注册、找回密码等都靠邮件),考虑到现在绝大多数邮件服务都会主动把莫名的邮件来源当做垃圾邮件,因此我又去弄了个“可靠来源”开SMTP作转发;于是就有了这次长久的折腾orz。
我们论坛用的Discuz 7.2(和X系列基本类似)PHP 5.6,CentOS 7(Vultr),管理中心-“全局”选项卡-“邮件设置”能里看到关于邮件的设置(UCenter类似);
Discuz 邮件发送方式有三种:
- 通过 PHP 函数的 sendmail 发送(推荐,没有其他多余设置)
- 通过 SOCKET 连接 SMTP 服务器发送(支持 ESMTP 验证,需要提供SMTP服务器、端口、(身份验证:用户名、密码)、发件人地址)
- 通过 PHP 函数 SMTP 发送 Email(仅 Windows 主机下有效, 不支持 ESMTP 验证,需要提供SMTP服务器、端口)
由于历史遗留配置里使用的是第二种设置,而经“检测”无法发送邮件,故从第一种开始尝试。(在“工具”选项卡–运行记录–系统记录–系统错误 里没有错误日志,什么鬼)
经查阅资料,PHP的sendmail是调用系统的sendmail指令来发送邮件,因此需要在系统环境上配置起sendmail。
- 先直接试了试敲sendmail之类回车发现有这个命令,但是对常见帮助命令(空参数、–h、–help等)却没有任何提示(什么鬼),稍微问度娘两句发现它连Usage或者manual都没,好吧不管了能用就好。照某个教程开始配置,改php.ini和sendmail.ini,然后发现根本没有sendmail.ini,直接在/etc/新建一个,在命令行测试,无效。回头观察一下,一方面涉及sendmail.ini的似乎都是win下的教程,一方面我的sendmail版本堪忧。
- 用yum装了个sendmail最新版,按另一个linux的教程(本机SMTP非代理)改/etc/mail/sendmail.mc文件(怎么连配置的写法都那么非主流/过时,m4 .mc > .cf;makemap hash),失败
- 找了个使用外部SMTP服务器代发邮件的教程改配置,失败。
偶然间发现命令行出现一条“you have got an new email at …”,查看了一下是vultr邮件中心的退件通知,没在意(flag)
综上第一种方式尝试无果已久后,决定抛弃sendmail尝试第二种方式
- 输入我的SMTP服务器、端口、用户名、密码,检测,失败。看了看Dz的错误日志,总算有东西了,“SMTP:CONNECT – Unable to connect to the SMTP server”emmmm
- 把QQ邮箱的SMTP写进去(用的25端口),检测,失败,log一样
- 查了下帮助,QQ邮箱只开放465和587端口,改端口587重测,失败,查log,“SMTP:AUTH LOGIN – 530 Must issue a STARTTLS command first.”,查帮助要SSL
- 改端口465重测,失败,查log,“SMTP:CONNECT –”(等于没有log,什么鬼),看起来不支持带SSL的SMTP服务,但普通的不带加密的又无法连接,明明服务器ping/wget都不成问题
- 跑去翻Discuz源码(include/sendmail.inc.php),基本操作是fsockopen然后fgets
- 在终端跑php -a,fsockopen连我的SMTP服务器(端口25),等了一会报错连不上
- 在本地用客户端连自己的SMTP服务器,发件测试,成功。
突然想起什么,百度“vultr 25端口”,发现Vultr默认禁用了25端口以防用户滥用(发送大量垃圾邮件),然想起后之前退件时似乎有提到;摔。因为是提供商提供的SMTP服务,不能改端口(不过有一个使用ssl的别的端口)。
- fsockopen连QQ邮箱的服务器(465和587一样),很快就连上了,fgets无返回。
- 百度fsockopen怎么连ssl,说只要给服务器地址加上ssl://就好,fsockopen重连QQ邮箱的SMTP,fgets返回“220 smtp.qq.com Esmtp QQ Mail Server”,成功。
- 正准备直接在php文件里加上ssl协议头,回想控制台虽然“服务器”一栏一般只用输入域名或者ip,不见得会过滤协议头(‘:’和‘/’),尝试写入QQ邮箱SMTP,测试,失败,查log,“SMTP:MAIL FROM – 501 mail from address must be same as authorization user”
- 改“发件人”,测试,成功。(终于)
- 换成自己的SMTP服务器换带加密的端口,测试,失败。#(喷)
- 终端php -a fsockopen连,证书错误(域名不匹配)。跑去提供商找他们服务器域名,换上测试,成功。
看了眼时间,发动态,睡觉。
马后炮地提供一个方便一些的解决方案,可以尝试写一个alias将sendmail指向一个自己写的发送邮件脚本,配置好这个脚本可以成功收发第三方邮件即可。如可利用python的email库。
赞赞