跳转到内容
搜索文档

BGP 异常

最后更新 查看 MarkdownAgent 设置

要访问 Cloudflare Radar BGP 异常检测结果,您首先需要创建一个包含 Account:Radar 权限的 API 令牌。以下所有示例均适用于免费层的 Cloudflare 账户。

搜索 BGP 劫持事件

在以下示例中,我们将查询 BGP 劫持事件 API,以获取由 AS64512(示例 ASN)发起或影响该 ASN 的最新 BGP 来源劫持。

curl "https://api.cloudflare.com/client/v4/radar/bgp/hijacks/events?invlovedAsn=64512&format=json&per_page=10" \
--header "Authorization: Bearer <API_TOKEN>"

结果显示了影响 AS64512 的最新 10 个 BGP 劫持事件。

{
  "success": true,
  "errors": [],
  "result": {
    "asn_info": [
      {
        "asn": 64512,
        "org_name": "XXXXX",
        "country_code": "XX"
      },
      ...
    ],
    "events": [
      {
        "duration": 0,
        "event_type": 0,
        "hijack_msgs_count": 1,
        "hijacker_asn": 64512,
        "id": 1234,
        "is_stale": false,
        "max_hijack_ts": "2023-04-27T14:01:55.952",
        "max_msg_ts": "2023-04-27T14:01:55.952",
        "min_hijack_ts": "2023-04-27T14:01:55.952",
        "on_going_count": 1,
        "peer_asns": [
          8455
        ],
        "peer_ip_count": 1,
        "prefixes": [
          "192.0.2.0/24"
        ],
        "tags": [
          {
            "name": "irr_new_origin_invalid",
            "score": 4
          },
          {
            "name": "irr_old_origin_valid",
            "score": 0
          },
          ...
        ],
        "victim_asns": [
          64513
        ],
        "confidence_score": 4
      },
    ],
    "total_monitors": 163
  },
  ...
}

在响应中,我们可以了解每个事件的以下信息:

  • hijack_msg_count:从所有对等方观察到的潜在 BGP 劫持消息数量。
  • peer_asns:观察到劫持消息的路由收集器对等方的 AS 编号。
  • prefixes:受影响的前缀。
  • hijacker_asnvictim_asns:潜在的劫持者 ASN 和受害者 ASN。
  • confidence_score:定量评分,描述系统对该事件为劫持的置信度:
    • 1-3:低置信度。
    • 4-7:中置信度。
    • 8 以上:高置信度。
  • tags:为事件收集的证据。每个 tag 还与一个分数相关,该分数会影响整体置信度评分:
    • 正分数表明该事件_更可能_是劫持。
    • 负分数表明该事件_较不可能_是劫持。

用户可以通过附加 minConfidence=8 参数进一步过滤出低置信度事件,该参数将仅返回 confidence_score8 或更高的事件。

curl "https://api.cloudflare.com/client/v4/radar/bgp/hijacks/events?invlovedAsn=64512&format=json&per_page=10&minConfidence=8" \
--header "Authorization: Bearer <API_TOKEN>"

搜索 BGP 路由泄露事件

BGP 路由泄露是 Cloudflare Radar 检测到的另一种 BGP 异常。目前,我们专注于检测特定于 provider-customer-provider 类型的路由泄露。您可以在我们的博客文章中了解有关我们的设计和方法的更多信息。

在以下示例中,我们将查询 BGP 路由泄露事件 API,以获取影响 AS64512 的最新 BGP 路由泄露事件。

curl "https://api.cloudflare.com/client/v4/radar/bgp/leaks/events?invlovedAsn=64512&format=json&per_page=10" \
--header "Authorization: Bearer <API_TOKEN>"

结果显示了影响 AS64512 的最新 10 个 BGP 路由泄露事件。

{
  "success": true,
  "errors": [],
  "result": {
    "asn_info": [
      {
        "asn": 64512,
        "org_name": "XXXXXXX",
        "country_code": "XX"
      },
      ...
    ],
    "events": [
      {
        "detected_ts": "2023-04-21T23:10:06",
        "finished": false,
        "id": 1234,
        "leak_asn": 64512,
        "leak_count": 14,
        "leak_seg": [
          64514,
          64512,
          64513
        ],
        "leak_type": 1,
        "max_ts": "2023-04-21T23:10:56",
        "min_ts": "2023-04-21T23:09:46",
        "origin_count": 1,
        "peer_count": 13,
        "prefix_count": 1
      },
      ...
    ]
  },
  ...
}

在响应中,我们可以了解每个事件的以下信息:

  • leak_asn:可能导致泄露的 AS。
  • leak_seg:观察到并被认为是泄露的 AS 路径段。
  • min_tsmax_ts:泄露宣告的最早和最新时间戳。
  • leak_count:观察到的 BGP 路由泄露宣告的总数。
  • peer_count:观察到泄露的路由收集器对等方数量。
  • prefix_countorigin_count:受泄露影响的前缀和源 AS 数量。

发送 BGP 劫持警报

在此示例中,我们将向您展示如何构建一个 Cloudflare Workers 应用程序,以使用 webhooks(适用于 Google Hangouts、Discord、Telegram 等)或电子邮件发送与给定 ASN 相关的 BGP 劫持警报。

我们将使用 Cloudflare Workers 作为平台,并使用其 Cron 触发器定期检查新警报。

对于该应用程序,我们希望它能执行以下操作:

  • 使用给定的 API 令牌从 Cloudflare API 获取数据。
  • 检查 Cloudflare KV 以了解哪些事件是新事件。
  • 为新劫持构建消息,并通过 webhook 触发器发送警报。

Worker 应用程序设置

我们将从设置 Cloudflare Worker 应用程序开始。

首先,在本地目录中创建一个新的 Workers 应用程序:

npm create cloudflare@latest -- hijack-alerts

进行设置时,请选择以下选项:

  • 对于 What would you like to start with?,选择 Hello World example
  • 对于 Which template would you like to use?,选择 Worker only
  • 对于 Which language do you want to use?,选择 JavaScript
  • 对于 Do you want to use git for version control?,选择 Yes
  • 对于 Do you want to deploy your application?,选择 No(部署前我们还会做一些修改)。

要开始开发您的 Worker,通过 cd 进入您的新项目目录:

cd hijack-alerts

在您的 Wrangler 配置文件中,将默认检查频率(每小时一次)更改为您喜欢的频率。以下是配置 workers 每五分钟运行一次脚本的示例。

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "hijack-alerts",
	"main": "src/index.js",
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"triggers": {
		"crons": [
			"*/5 * * * *"
		]
	}
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "hijack-alerts"
main = "src/index.js"
# Set this to today's date
compatibility_date = "2026-08-17"

[triggers]
crons = [ "*/5 * * * *" ]

在此示例中,我们还需要使用 Cloudflare KV 来保存最新检查的事件 ID,以便我们知道哪些事件是新事件。创建 KV 后,您可以回到 wrangler.jsonc 文件并添加以下部分:

{
	"kv_namespaces": [
		{
			"binding": "HIJACKS_KV",
			"id": "KV_ID_FOR_PRODUCTION",
			"preview_id": "TEMPORARY_KV_FOR_DEV_ENVIRONMENT"
		}
	]
}
[[kv_namespaces]]
binding = "HIJACKS_KV"
id = "KV_ID_FOR_PRODUCTION"
preview_id = "TEMPORARY_KV_FOR_DEV_ENVIRONMENT"

获取新检测到的 BGP 劫持

从 API 获取函数开始。

以下 apiFetch(env, paramsStr) 负责接收请求参数字符串,构造正确的标头,并从 Cloudflare API BGP 劫持端点获取数据。

async function apiFetch(env, paramsStr) {
	const config = {
		headers: {
			Authorization: `Bearer ${env.CF_API_TOKEN}`,
		},
	};
	const res = await fetch(
		`https://api.cloudflare.com/client/v4/radar/bgp/hijacks/events?${paramsStr}`,
		config,
	);

	if (!res.ok) {
		console.log(JSON.stringify(res));
		return null;
	}
	return await res.json();
}

env 参数是从调用者传入的,我们无需担心如何构造它。paramsStr 是一个保存查询 URL 中查询参数的字符串变量。

现在在我们的主 cron 触发器函数中,我们需要构造查询参数并调用 API 获取函数。 默认的 cron 触发器 worker 脚本定义如下:


export default {
    async scheduled(controller, env, ctx) {
    ...
    }
}

在我们的示例中,我们使用 env 变量来获取运行时的变量,如 TOKEN 和感兴趣的 ASN,以及 Cloudflare KV 绑定。在此示例中,我们不使用 controllerctx 变量。

首先,我们需要了解哪些是新事件。我们将新事件定义为应用程序尚未处理的事件。 我们使用之前创建和定义的 Cloudflare KV 存储桶(HIJACKS_KV)来保存和检索最近处理的事件 ID。

let kv_latest_id = parseInt(await env.HIJACKS_KV.get("latest_id"));
const first_batch = isNaN(kv_latest_id);

检查最新事件的主循环如下所示(跳过了一些验证代码):

let new_events = [];
let page = 1;
while (true) {
	// 查询事件
	const query_params = `per_page=10&page=${page}&involvedAsn=${env.TARGET_ASN}&sortBy=ID&sortOrder=DESC`;
	const data = await apiFetch(env, query_params);

	// 第一批,仅保存 KV 值
	if (first_batch) {
		await env.HIJACKS_KV.put("latest_id", events[0].id.toString());
		return;
	}

	// 跳过一些验证
	// ...

	let reached_last = false;
	for (const event of data.result.events) {
		if (event.id <= kv_latest_id) {
			// 到达最新事件
			reached_last = true;
			break;
		}
		new_events.push(event);
	}
	if (reached_last) {
		break;
	}
	page += 1;
}

现在我们将所有新检测到的事件保存在 new_events 变量中,我们可以发送警报:

// 按递增的 ID 顺序对事件排序
new_events.sort((a, b) => a.id - b.id);
const kv_latest_id = new_events[new_events.length - 1].id;
// 推送新事件
for (const event of new_events) {
	await send_alert(env, event);
}
// 更新 latest_id KV 值
await env.HIJACKS_KV.put("latest_id", kv_latest_id.toString());

使用 webhook 发送警报

函数 send_alert 负责构建警报消息并使用 webhook 发送警报。在此,我们演示了一个使用 Google Hangouts webhook 的示例文本消息模板。用户可以根据其选择的平台和需求自定义消息和 webhook 的使用。

async function send_hangout_alert(env, event) {
	const webhook_url = `${env.WEBHOOK_URL}&threadKey=bgp-hijacks-event-${event.id}`;

	const data = JSON.stringify({
		text: `检测到 BGP 劫持事件 (${event.id}):
检测时间: *${event.min_hijack_ts} UTC*
检测到的 ASN: *${event.hijacker_asn}*
预期的 ASN: *${event.victim_asns.join(" ")}*
前缀: *${event.prefixes.join(" ")}*
标签: *${event.tags.map((tag) => tag.name).join(" ")}*
对等方数量: *${event.peer_ip_count}*
`,
	});
	await fetch(webhook_url, {
		method: "POST",
		headers: {
			"Content-Type": "application/json; charset=UTF-8",
		},
		body: data,
	});
}

请注意,webhook 被认为是机密的,应通过 wrangler secret put WEBHOOK_URL 命令设置为环境变量。

最后一步是使用命令 npx wrangler deploy 部署应用程序,应用程序应已启动并在您的 Cloudflare 账户上运行,并将每五分钟触发执行一次。

从 Workers 发送电子邮件警报

如果您为域启用了 电子邮件路由,您还可以直接从 Workers 发送电子邮件警报。请参阅从 Workers 发送电子邮件以了解更多信息。

为了使此警报生效,您需要在 Wrangler 配置文件中配置适当的电子邮件绑定。

{
	"send_email": [
		{
			"type": "send_email",
			"name": "SEND_EMAIL_BINDING",
			"destination_address": "<YOUR_EMAIL>@example.com"
		}
	]
}
[[send_email]]
type = "send_email"
name = "SEND_EMAIL_BINDING"
destination_address = "<YOUR_EMAIL>@example.com"

然后,您可以创建一个电子邮件发送函数,将警报电子邮件发送到您配置的目标地址:

async function send_email_alert(hijacker, prefixes, victims) {
	const msg = createMimeMessage();
	msg.setSender({
		name: "BGP Hijack Alerter",
		addr: "<YOUR_APP>@<YOUR_APP_DOMAIN>",
	});
	msg.setRecipient("<YOUR_EMAIL>@example.com");
	msg.setSubject("BGP 劫持警报");
	msg.addMessage({
		contentType: "text/plain",
		data: `检测到 BGP 劫持:
    检测到的来源: ${hijacker}
    预期来源: ${victims.join(" ")}
    前缀: ${prefixes.join(" ")}
    `,
	});

	var message = new EmailMessage(
		"<YOUR_APP>@<YOUR_APP_DOMAIN>",
		"<YOUR_EMAIL>@example.com",
		msg.asRaw(),
	);
	try {
		await env.SEND_EMAIL_BINDING.send(message);
	} catch (e) {
		return new Response(e.message);
	}
}

下一步

有关这些主题的更多信息,请参阅我们关于 BGP 路由泄露BGP 劫持的 API 文档。

这篇文档对您有帮助吗?