使用 mysql 数据库将外发邮件删除到 exim 中以前不可用的邮箱

使用 mysql 数据库将外发邮件删除到 exim 中以前不可用的邮箱

我们有一个更大的社区门户,多年来规模越来越大,但也有一些死账户。最近,服务器的 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 规则集之后处理,并且所有外发邮件都已发送。

这不是原始问题的完整解决方案,因为我进行了一些简化以找出发生了什么。但在此基础上,应该很容易扩展数据库方案和查询以匹配上面概述的功能。

相关内容