![使用 mysql 数据库将外发邮件删除到 exim 中以前不可用的邮箱](https://linux22.com/image/640647/%E4%BD%BF%E7%94%A8%20mysql%20%E6%95%B0%E6%8D%AE%E5%BA%93%E5%B0%86%E5%A4%96%E5%8F%91%E9%82%AE%E4%BB%B6%E5%88%A0%E9%99%A4%E5%88%B0%20exim%20%E4%B8%AD%E4%BB%A5%E5%89%8D%E4%B8%8D%E5%8F%AF%E7%94%A8%E7%9A%84%E9%82%AE%E7%AE%B1.png)
我们有一个更大的社区门户,多年来规模越来越大,但也有一些死账户。最近,服务器的 IP 被列入黑名单,因为许多用户的邮件地址不再可用(550),而服务器正在向他们发送新闻通讯。
为了避免这种情况,我在发送 php 脚本中过滤掉了已知不可用的邮箱,但我希望 exim 接管这项工作,因为它更通用。
我的计划是使用 mysql 数据库列出不可用的邮箱。我想使用一个简单的脚本,遍历日志文件并将不可用的邮箱电子邮件地址保存到数据库中。
我不确定某些提供商是否普遍会假装邮箱不可用,因为服务器在黑名单上。但是,有一次 40% 的邮件被拒绝,我不敢想象有这么多用户删除了他们的邮件帐户。此外,我必须考虑到已删除的帐户可能会在某个时间(重新)创建。因此,除了地址之外,我还会存储一个时间戳,比如说 4 周后的时间戳。在这段时间内,必须删除发往该地址的所有邮件。如果 4 周后的第一封邮件可以送达,则一切正常。否则,应延长该期限(指数退避等)。
我可以用脚本覆盖所有这些,我甚至已经知道给出被阻止地址列表的 SQL 查询是怎样的:
SELECT blocked FROM maildrop WHERE name=${localpart}@${domain} and timestamp<UNIX_TIMESTAMP()
但问题是,我该如何正确地将其集成到 exim 配置中?起初我以为我可以使用虚拟别名并将邮件重定向到 devnull@localhost 用户,该用户的邮件通过管道传输到 /dev/null。
我使用以下配置进行了测试
mysql_sys_aliases:
debug_print = "R: mysql_sys_aliases for $local_part@$domain"
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT login FROM aliases WHERE alias='${local_part}@${domain}'}}
顺便说一句:我还测试了 mysql_aliases 而不是 mysql_sys_aliases
以及以下数据库条目:别名:[电子邮件保护]| 登录名:devnull@localhost
但没有成功。我仍然在 externaldomain.com 收到了邮件
然后我还找到了这篇使用 acl 的帖子,但我也无法让它工作。此外,我不确定这是否适用于系统直接发送的邮件(而不是通过外部 SMTP) https://serverfault.com/a/577007/239968
您将如何解决这个问题?
答案1
经过一整天的尝试和错误,我终于发现了它的工作原理。现在回想起来,它非常简单。
在 Debian 上,请确保已安装 exim4-daemon-heavy 软件包以获得 mysql 支持。我还假设使用了拆分配置(所有路径都相对于 /etc/exim4/conf.d/)。
然后创建至少有一列包含黑名单邮件地址的数据库。此列应被索引。
创建文件 main/50_exim4-config_failmail 并将 mysql 凭据放入其中:
hide mysql_servers = MYSQL_HOST/MYSQL_DB/MYSQL_USER/MYSQL_PASS
此外创建 router/050_exim4-config_failmail_router 并添加:
failmail:
driver = redirect
data = ${lookup mysql { SELECT '/dev/null' FROM dropmail WHERE email='${local_part}@${domain}'} {$value} }
file_transport = address_file
文件名以 050 开头非常重要,因为它必须在其他路由器之前加载。否则规则将被忽略。我花了几个小时才发现,如果将文件命名为“50_exim4-config...”,效果会大不相同。在这种情况下,其规则在 400 规则集之后处理,并且所有外发邮件都已发送。
这不是原始问题的完整解决方案,因为我进行了一些简化以找出发生了什么。但在此基础上,应该很容易扩展数据库方案和查询以匹配上面概述的功能。