Policr Mini 更新:新部署模型,网格验证,图片重写机制以及 ARM64 架构支持

这是第一篇在博客中发表的更新日志,很高兴在此宣布 Policr Mini 的新内容。你们可能也注意到,前不久 Policr Mini 的域名已更换为 mini.gramlabs.org,它是新的官方域名。

官方的线上版本最后一次具有实质功能变化大约是在半年以前,这期间也不定期的做了一些维护升级工作。这半年来的更新也逐渐在开发分支积累,这些变化将在下面一一介绍。

新的部署模型

在此前版本中机器人只能处于 Polling 工作模式(轮询获取更新),我们将官方实例部署于荷兰(或其它欧洲国家)节点,以尽可能的减少延迟。但这是远远不够的,通信路径决定了它的网络延迟并不会太低。

注释

在最理想的部署环境下,机器人程序应该运行在离自己的数据中心最近的位置,并和同样位于该数据中心附近的 Bot API 服务端通信。它最好通过 Webhook 工作模式获取更新。

得益于对全新的 Telegex 1.0 框架的适配工作结束,我们可以随意改变获取更新的工作模式,自由配置 Bot API 的服务端地址。官方实例当前在 Webhook 下工作,并与本地部署的 Bot API 服务端通信。这几乎把延迟降到了最低,所以能感受到它的响应速度明显更快了

信息

对于自建用户而言,要切到到 Webhook 工作模式并和本地部署的 Bot API 服务端集成,你需要额外配置一些东西。请参考此处

网格验证

此前默认的验证方式是通过识别单张图片,并在数量不超过 5 个的按钮列表中进行选择。严格来说,它存在较大的“碰运气”可能。我们当然也可以简单的提高答案列表的个数,但会导致消息显示占用太长的屏幕空间。

其实很早我们就开始考虑用更复杂的交互来避免这一点,在「多选」和「多阶段」以及「多图片」中犹豫了很久。实际上这些我们都会实现,但当时考虑的是优先实现哪一个。最终我们实现了「多图片」,即网格验证:

Message photo

来自『POLICR · 中文社区』的验证,请确认问题并选择您认为正确的答案。

选出所有「火车」的图片编号

您还剩 198 秒,通过可解除限制。

329
107
548
817
428
106
327
598
129

提示

就像上面的模拟 UI。网格验证会生成单张 9 宫格图片,让被验证用户选择其中的某一类图片。每一张图片都会被“编号”,每一个按钮上都是多个编号的组合。

理论上网格验证的安全性要高得多,因为每一张图片都是随意组合生成的,且答案数量更多,识别难度更大。

我们以上面的截图为例,正常思路的人类会认为答案是 248,但实际生成答案是 428。它是无序的,这也进一步阻碍了识别速度。即使面对批量过验证的“人形机器”,也有够受的。不过我们仍然认为网格验证是用户友好的,所以它成为了新的默认验证模式。

信息

对于自建用户而言,网格验证也有一些定制性。包括图片的统一尺寸,字体,是否对用户开放等。细节请参考此处

图片重写机制

在此前的版本中,机器人始终发送同一批图片(重复利用同一组文件)给验证的用户们。这其实有相当大的弊端,因为图片文件会被 Telegram 计算 Hash 值,当图片的 Hash 值相同时都会具有同一个的 file_id(即引用服务器上的同一个文件)。

如果有人想恶意收集的话,给他足够长的时间和重试次数,他可以将我们所有图片的 file_id 和对应的名称关联起来,从而破解验证。虽然我们可以不断的加入新图片或替换旧图片,甚至用“海量”图片来增加难度,但并不属于“根治”方法。

所谓的“根治”方法也极其简单,我们每一次都修改图片 Hash 不就行了吗?非计算机专业的人可能会这样想,但其实文件的 Hash 值是由文件数据计算而来的,并非一个“属性”而是一个“结果”,它无法直接修改。我们的实现方法是「随机重写一个像素」来生成新图片,这样便可达到相同的目的。

图片重写录屏演示

上面的动画是一个制屏演示,我们用一张 10x10 像素的图片放大后,进行反复随机重写。由于图片被放大很多倍,我们能用肉眼看到一个黑色像素点在任意位置随机产生。这便是图片重写机制的背后原理。

提示

图片重写并不会影响图片的视觉效果,因为它只是操作单个像素(肉眼难以察觉)。在图片体积合理的前提下对性能的影响也极小。

信息

对于自建用户而言,图片重写机制提供了关闭方法。请参考此处

ARM64 架构支持

现在我们同时提供 amd64arm64 架构的镜像,它托管于 gramoss/policr-mini。这意味着我们能够在树莓派等嵌入式 Linux 设备,Oracle Ampere A1 和 AWS Graviton 等 ARM64 架构的云服务器上运行机器人。甚至是你的 OpenWrt 路由器上。

信息

对于自建用户而言,旧的托管于 telestdbluerain 帐号的镜像已被弃用,请修改配置。

更多新变化

除了以上特别提及的更新,还有一些其它的次要变化。下面会逐个提及。

验证消息发送次数限制

现在用户不能无节制的获取验证消息,也就是反复的从入口按钮获取验证消息的行为被限制。当超过 3 次时机器人会拒绝发送新的验证消息并告知原因。

这是为了避免验证消息被用来攻击机器人,因为网格验证的图片合成比较消耗性能。也可以在一定程度上确保用户难以收集到更多验证资源,同时也加大了验证难度,避免用户刷验证消息获取最容易回答的问题。

Spoiler 实现文字马赛克

在此前的版本中,机器人通过 字符替换文本来实现对部分文字的遮挡(避免显示名称中可能存在的广告)。现在我们多了一种新的选择,使用 Telegram 新增的名为 spoiler 的文字格式来做同样的事情。有关 spoiler 的介绍和效果参阅官方博客的文章目前 spoiler 被默认启用,但不一定是永久性的

信息

对于自建用户而言,你可以自行决定将马赛克方法配置为 classic(经典)或 spoiler。请参考此处

新的镜像基础

我们将基础镜像从 debian:bullseye 改为了 void-linux/void-glibc-busybox:20231202R1。自镜像基础环境从 Debian 转变为 Void Linux 以后,体积大约减少了 45% - 60%。

听起来很吃惊,Void Linux 对于很多人而言是一个听都未听过的 Linux 发行版。但它确有一些独特的优势,我们认为它适合构建容器镜像,在体积和可靠性上都表现不错并能减轻我们的麻烦。此处不再继续介绍,以后有机会也许会提及更多细节。

提示

这里查看镜像的原始文件,也可以通过这些镜像从本地构建 Policr Mini 项目。

Rust 被引入

当前的项目源代码已经包含了一部分 Rust 代码,例如验证资源上传时的解压缩和图片重写的实现。这些 native 代码可以在某些特定功能上提供更强的性能。

当前仓库代码中用 Rust 实现的有两个模块,分别是 ziputilimgkit,位于项目代码的 native/ 路径下。

提示

还有网格验证的图片合成功能被剥离为一个独立的库,名为 img_grider,它的核心代码也是用 Rust 实现的。

已添加英文语言

这里要感谢 @TZrangersprotocol 的贡献,他为项目添加了十分完整的英文翻译。但由于某些原因,我们还不能启用英文支持。在规划好的未来路线中,机器人对消息文本的解析形式会被彻底颠覆和改进,那时候我们会启用英文和其它语言。

增强

  • 基础升级:Elixir 提升到 1.16.0,Erlang 提升到 26.1.2

Bug 修复

  • 修复了 macOS 压缩的验证资源包在服务器上解压出现目录名乱码的问题,现在整个解压缩相关功能已做了兼容性增强。(感谢 @laplace-anon 反馈)
  • 修复了验证资源的 Manifest.yml 和图集不一致时机器人无法启动或功能故障的现象,现在程序会兼容这种错误,并用警告或错误日志提醒。(感谢 @laplace-anon 反馈)
  • 修复了某些少见的情况下,包含附件的验证消息发送失败的错误。
  • 修复了某些时机下退群导致控制台报错的问题。
  • 修复了机器人重启后,遗留的已超时验证发送不出的问题。
  • 修复了强制 Webhook 模式启动的问题(此次更新的上线前夕,感谢 @omg-xtao)。
  • 其它的一些不重要的修复。

下次更新

下面会预告下次更新的主要方向,但不保证 100% 会被实现。这些不是全部的规划内容,只是最近的周期内的被计划好的一部分。

多选验证支持

允许单个问题下添加多个正确答案并要求全部选中才可通过验证,用户需要多次选择答案,并主动提交(或自动触发提交)。多选验证可以明显增加自定义验证的难度,包括破解和收集难度。

新管理后台:控制台

我们会添加一个新的网页后台,名为「控制台」。它会逐步取代当前的后台,一段时间内它们会同时存在,直到旧后台的所有功能被完全替代。

新控制台相比旧后台存在的优势:

  • 将同时适配手机和电脑浏览器,就像本博客和 Policr Mini 的前台那样。
  • 将有更加美观的界面和更强的互操作性。
  • 将提供更加丰富、完整的功能。

提示

每一次更新都会有各种修复和优化,但一般不会被提前列出来。

赞助作者

Policr Mini 的作者对项目充满信心,也有十分具体的未来规划。但它毕竟是免费开发和运营的项目,缺少资金支持导致进展十分缓慢。如果你也看好这个项目的未来,可以考虑赞助项目。亦或联系作者洽谈商业合作。