我们使用 SSO,但最近几天,一些会员报告无法访问其账户,并收到以下错误:
您的账户存在问题。请联系站点管理员
我原以为这可能是由于我之前报告的问题导致的,因此我检查了他们的 IP 地址是否在“被屏蔽的 IP 地址”列表中:其中一位用户的 IP 确实在列表中,但其他用户并不在。
在启用 verbose sso logging(详细 SSO 日志)后,我请其他用户再次尝试,日志显示他们的 IP 地址被阻止:
Verbose SSO log: IP address is blocked xxx.xxx.xxx.xxx
然而,我已双重确认,该 IP 地址并未出现在“被屏蔽的 IP 地址”列表中。我也直接检查了 PostgreSQL 的 screened_ip_addresses 表,未发现该 IP 地址的任何记录。
我已经束手无策了……是否有其他用于阻止 IP 地址的部分需要我们关注?或者 IP 地址被添加到“被屏蔽的 IP 地址”列表中的时间非常短暂,以至于我在收到报告后(几小时内)无法捕捉到它们?
需要明确的是,我们从未手动将任何 IP 地址添加到“被屏蔽的 IP 地址”列表中——它们似乎是在我们通过 API 关闭某用户账户时自动添加的(参见上方链接),而且我们一直无法通过使用文档中说明的 block_ip: false 参数来阻止这一行为。
pfaffman
(Jay Pfaffman)
2
IP 被添加到“屏蔽 IP"列表的问题与我要报告的这个问题是 分开的。我们发现有些成员 并未 被“屏蔽 IP"列表阻止,但却无法通过 SSO 登录其账户,原因据称是"IP 地址已被阻止”。
除了“屏蔽 IP"列表之外,是否还有其他可能阻止 IP 地址的地方需要我进一步排查?
听起来您正在调用“作为垃圾邮件发送者删除”功能,该功能会自动将 IP 和电子邮件地址加入黑名单。我认为您应该重新检查那段代码。根据 UI 设计,您应该使用“普通删除”,而不是“作为垃圾邮件发送者删除”。
这可能确实如此,但我们如何删除用户的问题正在此处进行讨论。
不确定这是否是一个独立的问题,但我注意到“屏蔽 IP"部分中的“匹配数”列在所有条目中都显示为 0。我查看了该表的导出文件,确认所有 IP 的匹配数均为 0。然而,每天我们都能看到用户因 IP 地址被阻止登录(通过 SSO)。
不过,查看“屏蔽邮箱”时,大多数条目都有匹配项!而且那里也有一个 IP 地址列……所以我原以为找到了罪魁祸首,但实际上,被阻止的 IP 地址也没有列在其中。
这是几分钟前来自我们的 /logs 的记录:

以下是“屏蔽 IP"的搜索结果:
我还查看了“屏蔽邮箱”,刚刚被阻止登录的账户的 IP 地址和邮箱地址均未在其中。
有什么建议可以指导我们去哪里进一步排查吗?
我认为我找到了问题所在(最终问题出在我们这边),但还有一些 bug 需要报告。不过,这并不是我熟悉的代码栈,所以希望有人能更仔细地查看。
首先是原因。直接查看 screened_ip_addresses 数据库表,我发现它错误地阻止了两个完整的地址块(176.59.0.0/16 和 109.252.0.0/16)。我真不知道它们是怎么被添加进去的,而且这两个条目从二月起就一直存在。Discourse 管理后台有没有什么按钮可以一次性阻止整个 /16 地址块!?
无论如何,这很可能就是我最初问题的罪魁祸首。不过,Discourse 团队可能还需要关注一些其他问题,因为正是这些问题使得此次排查格外困难:
-
出于某种原因,这些被阻止的地址范围并未显示在“已屏蔽 IP"列表中。我不得不直接查看数据库才能找到它们。不过,使用搜索功能输入 “176.59” 或 “109.252” 却能显示它们。/admin/logs/screened_ip_addresses 接口是否应用了结果数量限制?
-
在导出文件中,它们显示为 176.59.0.0 和 109.252.0.0,即没有显示任何地址块信息。即使是默认范围(127.0.0.0/8、10.0.0.0/8 等)也是如此——导出文件中未显示子网掩码。
-
尽管这些条目一直在阻止用户,但它们的 match_count 值为 0,且 last_match_at 为空(整张表都是如此)。这是预期的行为吗?也许确实不需要统计所有 allow 匹配,但如果阻止操作也不被统计,这些字段似乎就没有被使用或不需要了。或者,是否因为通过 SSO 登录并未触发这些匹配?
我再次想告诉你,我相当确定你是在通过 API 调用“作为垃圾邮件发送者删除”功能。如果来自相关 IP 地址的垃圾邮件发送者删除操作足够多,IP 地址封锁范围会自动扩大。我很有信心,你看到的就是这种情况。
是的,这一点确实如此。也许你的被筛选 IP 列表之所以如此庞大,是因为你长期以来一直在“作为垃圾邮件发送者删除”?你并不希望这样。
你想要的是“仅删除”,而不是“删除并封锁”,但你发布的大部分内容都表明你正在通过 API 调用“删除并封锁”功能。
问题不在于使用的端点,而在于参数,因为 API 期望布尔值以字符串 ‘true’/‘false’ 的形式传递,而我之前并未意识到这一点。
此外,我在上面还遇到了一些其他 bug,不确定是否需要修复。如果不需处理,此问题可以关闭。谢谢。