Featured image of post 使用 CloudFlare R2 作为图床时的安全防护设置,避免被恶意刷B类文件请求

使用 CloudFlare R2 作为图床时的安全防护设置,避免被恶意刷B类文件请求

CloudFlare R2 是大善人推出的重磅免费服务,默认即为用户提供 10G 存储空间和无限流量。不过这个无限还是有限制的,即每月写入类操作不超过 100 万次,每月读取类操作不能超过 1000万次,否则就将按量计费。最近我搬迁了 11 万多张图片到 R2 ,有点担心使用超限,所以对其作了严格的防护设置。

防护原理

我需要设置防护的这个 R2 存储桶是此前在 将Soomal.cc迁移到Hugo 这篇文章中提到的 soomal.cc 网站中的图片。

该网站已经托管在 Cloudflare Pages ,由 Cloudflare Pages 提供免费服务,只需要对 html 中引用的图片进行防护。

1.限制直接对R2存储桶访问。禁止使用链接直接访问 R2 存储桶,而是只能通过 Cloudflare Workers 服务进行访问。

2.限制对图库链接的直接访问。禁止直接使用 https://images.soomal.cc/test.webp 这种网址请求图片,对所有图片的访问均需在原网站下进行。

3.对原站启用适当防护策略。由于图片本身不适合设置太多防护规则,主要是通过在原站上设置,变相增加直接请求图片链接的难度。


设置方法

禁用 R2 公开地址

在 R2 设置中,不要设置自定义域访问,不要在网络上公开 R2。

在 Cors 策略中,设置仅通过原站访问。

R2设置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
[
  {
    "AllowedOrigins": [
      "https://soomal.cc",
      "https://www.soomal.cc"
    ],
    "AllowedMethods": [
      "GET",
      "HEAD"
    ],
    "AllowedHeaders": [
      "*"
    ],
    "ExposeHeaders": [
      "ETag"
    ],
    "MaxAgeSeconds": 3600
  }
]

添加 Workers 访问规则

  1. 创建一个 Worker

创建worker

  1. 绑定 R2 存储桶

绑定存储桶

  1. 添加自定义域和路由

添加路由

  1. 添加 Workers代码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);
  const referer = request.headers.get('referer');
  const allowedDomains = ['soomal.cc', 'www.soomal.cc'];

  // 处理 images.soomal.cc 的图片请求
  if (url.host === 'images.soomal.cc') {
    if (referer && allowedDomains.some(domain => referer.includes(domain))) {
      const filePath = url.pathname.replace(/^\//, '');
      try {
        const object = await R2.get(filePath);
        if (object === null) {
          console.log(`File not found: ${filePath}`);
          return new Response('File Not Found', {
            status: 404,
            headers: { 'Content-Type': 'text/plain' }
          });
        }
        const headers = new Headers();
        headers.set('Content-Type', object.httpMetadata.contentType || 'image/webp');
        headers.set('Cache-Control', 'public, max-age=31536000');
        headers.set('Access-Control-Allow-Origin', 'https://soomal.cc');
        return new Response(object.body, { status: 200, headers });
      } catch (error) {
        console.log(`Error: ${error.message}`);
        return new Response('Internal Server Error', {
          status: 500,
          headers: { 'Content-Type': 'text/plain' }
        });
      }
    }

    console.log(`Unauthorized: Referer ${referer} not allowed`);
    return new Response('Unauthorized Access', {
      status: 403,
      headers: { 'Content-Type': 'text/plain', 'Cache-Control': 'no-store, no-cache' }
    });
  }

  // 如果主机名不是 images.soomal.cc 或 www.soomal.cc,直接返回 404
  return new Response('Not Found', {
    status: 404,
    headers: { 'Content-Type': 'text/plain' }
  });
}

这个脚本主要作用是将所有包含 images.soomal.cc 的请求,都通过 Workers 去访问。

利用 Workers 每天 10 万次的限额(30天就是300万次),确保对 R2 存储桶的访问数不会爆单。

其实设置到这里,我的目的也就达到了。因为每天 10万次访问,已经足够这个备份网站使用。一旦超额,workers 直接罢工,图片也就无法访问了。

添加必要的防护策略(可选)

经过上边设置后,所有对 R2 存储桶的请求,都只能通过原站 soomal.cc 访问。

这样,就可以继续通过对原站添加必要防护,变相提升对图片的防护能力。

  1. 启用SSL严格模式

开启SSL严格模式

  1. 启用缓存。建议是能缓存的全缓存。

缓存规则

  1. 安全规则。可以启用连续脚本监视、浏览器完整性检查、速率限制、自动程序攻击模式等功能,进一步增加防护。

简单速率限制

开启境外访问托管质询

Built with Hugo, Powered by Github.
全站约 342 篇文章 合计约 974614 字
本站已加入BLOGS·CN