虚假账户会给企业带来损失。机器人注册免费试用、滥用推荐计划、用垃圾信息淹没平台。一些企业购买欺诈防护软件来阻止这些行为。另一些企业暂时负担不起,或者想先用免费工具测试问题。

本指南展示了一条免费、开源(open-source)的机器人防护和虚假账户防护路径。它使用两个工具:CrowdSec 和 ALTCHA。两者都是开源软件,都运行在你自己的服务器上,基础层面都不需要费用。我们在 Ubuntu 26.04 LTS 服务器上构建并测试了此设置。本指南中的每一条命令都来自该测试。

什么是欺诈防护软件?

欺诈防护软件在有害活动造成损害之前检测并阻止它们。对于账户创建,这意味着阻止虚假注册、机器人注册和被盗身份(stolen-identity)账户。

付费欺诈防护平台会实时对每个访客进行评分。它们检查设备指纹、鼠标移动、打字速度和网络声誉等信号。供应商经常更新这些模型,为此它们汇集了多个客户的数据。

免费、开源(open-source)工具可以覆盖部分工作。它们无法与付费平台的完整范围相比。本指南展示了免费工具能做什么,以及它们在哪里止步。

为什么这对电子商务商店很重要

虚假账户会以消耗真金白银的方式打击在线商店。机器人可以创建数十个账户来反复领取首单折扣码。虚假账户可以留下虚假评论,损害买家信任。它们还可以刷推荐奖金,通过虚假推荐链接注册以收集本应属于真实客户的奖励。

在财务损失直接且易于衡量的地方,促销码滥用防护和推荐欺诈防护最为重要。如果你的商店运行注册折扣、推荐计划或评论系统,虚假账户防护不是可选的。

本指南中的设置适用于在线商店的注册或结账账户表单,也适用于任何其他网站。

机器人及虚假账户防护的两层结构

虚假账户防护最好分层进行。没有单一工具能捕获所有内容。本指南构建了两层。

  1. CrowdSec 监控网络流量。它阻止已知的恶意 IP 地址、暴力破解(brute-force)登录尝试和自动化扫描。
  2. ALTCHA 监控注册表单。它使用工作量证明 challenge(proof-of-work challenge)来过滤简单的机器人。

这两层共同阻止了大部分低努力量的机器人流量。它们不会阻止使用真实浏览器和类人行为的攻击者。我们将在本指南后面解释这一差距。

先决条件

本指南在 Ubuntu 26.04 LTS 服务器上构建和测试。本指南中的安装和配置命令都需要以具有 sudo 权限的用户执行。我们将在需要时指导你安装和配置每个工具。

第一部分:设置 CrowdSec

CrowdSec 是一个开源(open-source)入侵防御系统。它读取系统日志,如 SSH 日志和 Web 服务器日志。它在这些日志中寻找攻击模式。当发现攻击模式时,它会创建一个决定来阻止该 IP 地址。一个单独的程序,称为 bouncer,通过服务器的防火墙执行阻止。

CrowdSec 还与其用户社区共享威胁数据。如果另一个 CrowdSec 用户阻止了一个攻击 IP 地址,你的服务器也可以受益于相同的阻止。这需要注册 CrowdSec Console,这是一个免费步骤,下面会介绍。

首先检查你的系统

在安装任何东西之前,确认你的操作系统版本和一些设置:

lsb_release -a
sudo systemctl status ufw
timedatectl

确认三件事:你的操作系统版本、UFW 防火墙是否处于活动状态,以及你的系统时钟是否同步。CrowdSec 需要准确的时间戳才能正常工作。

如果 UFW 处于活动状态,则设置防火墙规则

CrowdSec 和 UFW 做不同的工作。UFW 控制哪些端口是开放的。CrowdSec 的 bouncer 阻止它标记为恶意的特定 IP 地址。一个不能替代另一个。保持 UFW 活动,并让 CrowdSec 的 bouncer 与它一起运行。

如果 UFW 处于活动状态,只打开此设置需要的内容。

在启用 UFW 之前允许 SSH,而不是之后。如果你在没有 SSH 规则的情况下启用 UFW,你会立即将自己锁在远程服务器之外,除了云提供商的控制台之外没有其他方式返回。

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

端口 5000 和 8080 故意保持关闭。Flask 只需要通过 127.0.0.1 在同一台机器上被 Nginx 访问。向公众开放端口 5000 会让访问者完全绕过 Nginx 和 TLS,直接访问 Flask。CrowdSec 的 agent 和 bouncer 也通过 127.0.0.1 相互通信,并且只有在跨多台服务器运行 CrowdSec 时才需要公共端口,本指南不涉及这种情况。

UFW 和 CrowdSec bouncer 创建独立的防火墙规则,在正常使用中不会冲突。

一个注意事项: 在某些设置中,UFW 自己的规则可能会使 bouncer 的指标计数器不太准确。阻止本身仍然正常工作。只有指标显示受到影响。

安装 CrowdSec Agent

打开终端并运行以下命令,在 Ubuntu 上添加 CrowdSec 仓库并安装 CrowdSec agent:

curl -s https://install.crowdsec.net | sudo sh
sudo apt install -y crowdsec

这将安装核心检测引擎,称为 agent。agent 读取日志。它本身不阻止流量。

检查安装:

sudo systemctl status crowdsec --no-pager
sudo cscli collections list

collection 是一个服务类型的检测规则包。在新服务器上,CrowdSec 默认安装 SSH 和一般 Linux 安全的 collections。

示例输出:

────────────────────────────────────────────────────────────────────────────────────────────────────────────────
COLLECTIONS
────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Name                                 📦 Status   Version  Local Path
────────────────────────────────────────────────────────────────────────────────────────────────────────────────
crowdsecurity/linux                  ✔️  enabled  0.4      /etc/crowdsec/collections/linux.yaml
crowdsecurity/sshd                   ✔️  enabled  0.9      /etc/crowdsec/collections/sshd.yaml
crowdsecurity/whitelist-good-actors  ✔️  enabled  0.4      /etc/crowdsec/collections/whitelist-good-actors.yaml
────────────────────────────────────────────────────────────────────────────────────────────────────────────────

安装 Nginx 并将其连接到 CrowdSec

大多数虚假账户创建是通过网站的注册表单进行的。为了保护该表单,CrowdSec 需要读取你的 Web 服务器日志。

安装 Nginx:

sudo apt install -y nginx

添加 Nginx collection:

sudo cscli collections install crowdsecurity/nginx

请注意,安装 collection 只添加检测规则。它不会告诉 CrowdSec 日志文件在哪里。你必须单独添加:

sudo tee /etc/crowdsec/acquis.d/nginx.yaml > /dev/null <<EOF
filenames:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
labels:
type: nginx
EOF

重启 CrowdSec 服务以使更改生效:

sudo systemctl restart crowdsec

测试 CrowdSec 现在是否读取这些日志:

curl http://localhost/
sudo cscli metrics

在 Acquisition Metrics 表中查找 /var/log/nginx/access.log。读取的行数应大于零。

安装 Bouncer

agent 负责检测。bouncer 负责阻止。我们需要两者。

Ubuntu 26.04 使用 nftables 作为其防火墙后端。这取代了旧的 iptables 系统。安装匹配的 bouncer:

sudo apt install -y crowdsec-firewall-bouncer-nftables
sudo cscli bouncers list

bouncer 列表应显示你的 bouncer 为有效。它还应显示最近的连接时间戳。

示例输出:

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Name                            IP Address  Valid  Last API pull         Type                       Version                                                                  Auth Type
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cs-firewall-bouncer-1786521275  127.0.0.1   ✔️      2026-08-12T07:54:36Z  crowdsec-firewall-bouncer  v0.0.36-debian-pragmatic-amd64-4c315193cd4f19e3937cdee2f15183ec4d602f56  api-key
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

确认完整管道工作

使用手动阻止进行测试。使用一个保留的测试 IP 地址,它永远不会承载真实流量:

sudo cscli decisions add --ip 192.0.2.100 --duration 5m --reason "manual-test-block"
sudo nft list ruleset | grep -A 5 -i crowdsec

检查结果。如果 IP 地址(例如我们的情况中的 192.0.2.100)出现在 nftables 规则集中并带有 drop 规则,则完整链工作:检测、决策和执行。

加入社区威胁情报网络

我们在机器上安装了 CrowdSec agent。接下来我们需要将机器添加到 CrowdSec 网络。

为此,运行:

sudo cscli console enroll --quick

此命令会打印一个链接。

INFO Please visit the following URL to enroll your instance: https://app.crowdsec.net/quick-enroll?token=xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
INFO This link is valid for the next 15m0s.
INFO Please restart crowdsec after accepting the enrollment.
INFO manual set to true
INFO context set to true
INFO Enabled manual : Forward manual decisions to the console
INFO Enabled tainted : Forward alerts from tainted scenarios to the console
INFO Enabled context : Forward context with alerts to the console

在浏览器中打开它。登录免费的 CrowdSec 账户并点击 Enroll engine。请注意,链接仅在 15 分钟内有效,所以请尽快完成此步骤。

此步骤将你的服务器连接到 CrowdSec 的共享阻止列表,该列表由许多用户的数据构建。

CrowdSec 捕获什么,遗漏什么

CrowdSec 在网络级欺诈防护方面很强。它阻止:

  • SSH 暴力破解尝试
  • 已知的恶意 IP 地址
  • 自动化扫描和常见漏洞利用尝试

CrowdSec 不监视注册表单内部发生的事情。如果真实的人和机器人从干净的 IP 地址发送正常请求,它无法区分。这就是为什么虚假账户防护需要第二层。

第二部分:添加 ALTCHA 进行虚假账户防护

ALTCHA 是 CAPTCHA 的开源(open-source)替代品。它不要求用户解决谜题。相反,它要求他们的浏览器解决一个小数学问题,称为工作量证明 challenge(proof-of-work challenge)。真实浏览器在一秒内解决这个问题。简单的机器人跳过此步骤,并被阻止。

ALTCHA 由两部分组成:

  • 开源 widget(open-source widget)。 免费且自托管。这是我们在本指南中使用的。
  • ALTCHA Sentinel。 一个单独的付费产品。它添加了机器学习和行为分析。我们稍后会介绍。

构建测试注册应用

我们使用 Flask,一个小的 Python Web 框架,来构建测试注册表单。这模拟了真实的账户创建页面。它收集电子邮件和用户名,然后在保存账户之前检查有效的 ALTCHA 解决方案。

如果尚未安装 pip,请安装:

sudo apt install -y python3.14-venv python3-pip

设置环境:

mkdir -p ~/testapp && cd ~/testapp
python3 -m venv venv
source venv/bin/activate
pip install flask altcha

完整的应用程序代码可在我们的 GitHub 仓库中作为 GitHub Gist 获得。使用命令下载:

curl -O https://gist.githubusercontent.com/ostechnix/679974866de0cc00f0de57a8b14ccd12/raw/d917c3c79c358f70105801e40d2559235e54f570/altcha-signup-demo.py

该文件包括注册表单、challenge 端点和管理页面。管理页面记录接受和拒绝的注册。关键部分是:

  • 一个 GET /altcha-challenge 路由。它为每次页面加载创建一个新的工作量证明 challenge。
  • 一个 POST /signup 路由。它拒绝任何缺少有效、已解决 ALTCHA 负载的请求。
  • 一个用于拒绝尝试的数据库表。它记录原因和源 IP 地址。此日志为你提供工具捕获内容的真实证据。

重命名并运行它:

mv altcha-signup-demo.py app.py
python app.py &

现在应用程序将在后台运行。

连接 Nginx 作为反向代理

反向代理位于互联网和你的应用程序之间。它将请求转发到 Flask。它还处理加密和日志记录。

sudo tee /etc/nginx/sites-available/testapp > /dev/null <<'EOF'
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate     /etc/nginx/ssl/testapp.crt;
ssl_certificate_key /etc/nginx/ssl/testapp.key;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF

此文件本身什么都不做,直到 Nginx 被告知使用它。启用站点,删除默认站点,并在重新加载前检查配置:

sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/testapp /etc/nginx/sites-enabled/testapp

配置 HTTPS(重要)

这一点让许多第一次(first-time)使用 ALTCHA 的用户感到惊讶。工作量证明 challenge 依赖于称为 Web Crypto API 的浏览器功能。浏览器只允许此功能通过 HTTPS 或 localhost 使用。通过本地网络地址的普通 HTTP 连接将失败。浏览器将报告:“Secure context (HTTPS) required.”

对于测试实验室,自签名(self-signed)证书就足够了:

sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/testapp.key \
-out /etc/nginx/ssl/testapp.crt \
-subj "/CN=192.168.0.30"

对于实时网站,请使用来自受信任机构的证书,例如 Let's Encrypt。将上述命令中的 192.168.0.30 替换为你的服务器 IP 地址。

检查 nginx 配置是否有错误:

sudo nginx -t

你应该看到:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

如果没有错误,请继续重启 nginx 服务:

sudo systemctl reload nginx

nginx -t 只检查语法。如果实际上没有启用任何站点,它不会警告你,所以不要跳过上一节中的 ln -s 步骤。

匹配你的 Widget 版本与库版本

在测试期间,ALTCHA widget 几乎立即失败,显示“Verification failed”。速度是线索:真正的工作量证明检查需要一点时间运行。原因是版本不匹配。服务器上的 Python 库构建一种 challenge 格式。旧版本的 JavaScript widget 期望不同的、更旧的格式。

修复很简单:匹配主要版本。在编写本指南时,当前 widget 是版本 3。它在 HTML 中使用 challenge 属性,并与当前的 Python altcha 库正确配对。在假设你的设置有问题之前,请检查你的版本。

测试结果

首先,找到你服务器的地址并打开注册页面。在服务器上运行此命令以找到其局域网 IP:

ip -4 addr show | grep inet

在主网络接口下查找地址,例如 192.168.0.30。此示例使用该地址;在整个过程中替换为你自己的服务器 IP。

从同一网络上的另一台设备的浏览器,转到 https://192.168.0.30/。

你会首先看到证书警告。这是预期的,因为证书是为此实验室自签名的。点击通过:在 Firefox 中,选择“Advanced”,然后选择“Accept the Risk and Continue”。在 Chrome 中,选择“Advanced”,然后选择“Proceed”。

注册页面应该加载,带有电子邮件字段、用户名字段和下方的 ALTCHA 复选框。

一个有效的设置显示两个结果。

一个真实浏览器,解决 challenge,成功。 点击复选框。widget 解决工作量证明 challenge 并显示绿色复选标记,标记为“Verified”。这需要一点时间。它不是即时的,因为你的浏览器中正在发生真实计算。

填写表单并点击“Sign Up”。页面应显示“Account created.”。在注册表单中使用任何值。它应该工作。

一个机器人脚本,跳过 challenge,失败。

curl -sk -X POST https://localhost/signup -d "[email protected]&username=botuser"

此请求不携带 ALTCHA 负载。服务器拒绝它,并记录原因。跳过真实浏览器代码的脚本无法通过此检查。

127.0.0.1 - - [12/Aug/2026 08:22:14] "POST /signup HTTP/1.0" 400 -
<!DOCTYPE html>
<html>
<head><title>Blocked</title></head>
<body style="font-family: sans-serif; max-width: 400px; margin: 40px auto;">
<h2>Signup rejected</h2>
<p>Reason: Missing verification payload (bot-like request)</p>
<a href="/">Try again</a>
</body>

访问 https://192.168.0.30/admin(使用你自己的服务器地址)以并排查看两个结果:真实注册被接受,机器人尝试被记录为拒绝,并带有原因和源 IP 地址。

恭喜!你刚刚在 Ubuntu 上使用 CrowdSec 和 ALTCHA 为你的网站构建了虚假账户防护设置。如你所见,这是非常基本的设置,但它有效!去探索 ALTCHA 文档以获取更高级的配置。

限制

CrowdSec 和开源(open-source)ALTCHA widget 阻止简单、低努力量的机器人。它们不会阻止每种虚假账户。这是本指南中设置的诚实限制。

更有能力的攻击者可以使用真实的自动化浏览器,由 Playwright 或 Selenium 等工具控制。这种机器人运行实际的 JavaScript。它可以解决 ALTCHA 工作量证明 challenge,就像人类的浏览器一样。针对这种攻击者,本指南中的免费堆栈不提供保护。

这是付费机器人防护和欺诈防护平台旨在弥合的差距。它们添加了超出工作量证明的信号。这些包括鼠标移动、打字节奏和设备指纹。它们还使用在许多客户流量上训练的模型。平台弥合这一差距的效果取决于供应商。它还取决于你自己的流量。做你自己的研究,为你的生产网站找到最佳的商业解决方案。

常见问题(FAQ)

问:CrowdSec 是免费的吗?

答:是的。核心 CrowdSec agent 和 bouncer 是开源的,可以免费自托管。存在面向大型组织的付费控制台层级,但本指南中的设置不需要它。

问:ALTCHA 是免费的吗?

答:ALTCHA widget 是免费且开源的。ALTCHA Sentinel 是一个单独的产品,具有机器学习功能。它是付费的,在 30-day 试用之后。

问:机器人可以绕过 ALTCHA 吗?

答:直接提交表单而不加载页面或运行 JavaScript 的简单脚本无法通过 ALTCHA。使用完整自动化浏览器的机器人可以解决 challenge,因为它表现得像真实浏览器。这是免费、开源(open-source)widget 的主要限制。

问:ALTCHA 工作需要 HTTPS 吗?

答:是的。工作量证明 challenge 依赖于一个浏览器功能,该功能仅通过 HTTPS 或 localhost 工作。普通 HTTP 站点将无法工作,即使在本地网络上也是如此。

问:我什么时候应该为欺诈防护软件付费?

答:一旦虚假账户造成实际经济损失,请考虑付费平台。一旦你有证据表明机器人正在绕过你的免费防御,例如自动化浏览器大规模解决你的工作量证明 challenge,也请考虑。

总结

虚假账户和机器人防护不需要大量预算即可开始。CrowdSec,一个开源(open-source)入侵防御系统,阻止网络级威胁,如暴力破解(brute-force)攻击和已知的恶意 IP 地址。ALTCHA,一个开源(open-source)工作量证明 widget,在注册表单处阻止简单的机器人。

这两个工具一起为你提供了真实、有效、免费的防御。它们阻止了大部分虚假账户创建。它们不会捕获使用真实自动化浏览器的攻击者。对于这种级别的威胁,付费欺诈防护软件添加行为分析以弥合差距。它做得如何因供应商而异。在购买任何商业选项之前,你应该进行自己的评估。

从免费层开始。使用本指南构建的拒绝日志来衡量什么被穿透。一旦你有真实数据显示免费层在哪里不足,再决定付费平台。