天空 Blond - Cloudflare
type: channel
link: https://skyblond.info/tag/Cloudflare/
items: 【歪门邪道】使用BackBlaze B2和CloudFlare搭建CDN
items: 【歪门邪道】使用Cloudflare作为ddns更新IPv6域名DNS

【歪门邪道】使用BackBlaze B2和CloudFlare搭建CDN
type: item
date: 2025-03-01T09:39:00+08:00
description: 前些日子买了相机，于是我开始随地大小拍。拍了半天，总不能只把照片放在NAS里留着传家，总归要发出来给大家看的。虽然我的服务器租用的是CN2线路，能够在海外为国内用户提供良好的访问体验，但问题是它流量贵啊，我这一张照片10MB，这一个月下来看不了几张照片就没了。想来想去，还是得整个CDN。本文记述如何使用BackBalze B2存储和CloudFlare Worker搭建一个四舍五入就是不要钱的CDN。计费机制在开始搭建之前我想首先介绍一下我这个方案的计费机制。首先我们的大慈善家CloudFlare允许免费用户使用CDN和缓存机制，虽然你没办法控制缓存的细节，但对于我的需求来说，只要能缓存就行，完全不需要这种细粒度的控制和其他任何花哨的功能。其次为了保证我们的桶不被滥用，我们需要使用Worker来访问私有桶，而Worker的免费计划也非常慷慨：每天10万请求，每个调用限制10毫秒CPU时间。对于我的需求来说，Worker需要做的就是将用户访问的URL转换成对桶的签名URL访问，然后让CloudFlare去抓取即可。抓取的耗时并不计算在调用的CPU时间内，实际计算的时间只是解析URL、生成签名URL。除非我的照片每天被访问10万次以上，否则不会有任何账单产生。对于存储来说，除了付存储的账单，最要命的实际是流量费。而BackBlaze和CloudFlare是带宽联盟，这就意味着从BackBlaze传送到CloudFlare的流量是不计费的。因此我们只需要付出最基本的存储费用即可。当然CloudFlare本身也提供R2存储，但R2每月每TB需要15美元，而B2只需要6美元。另外我喜欢BackBlaze的一点是，他们有月均存储量x3的免费出站流量。比如说你一个月平均下来每天存储了1TB数据，那么你从BackBlaze下载，每个月有3TB的免费出站流量，这个和带宽联盟是单独计算的。带宽联盟的流量就是免费的，不占用你的三倍免费额度。这是什么？这是大善人啊！你再看看AWS，传入是免费的，但传出的每一个比特都要计费。没有一个人能看着自己的AWS账单笑得出来。搭建CDN其实BackBlaze官方有提供如何使用CloudFlare来提供对B2桶的访问。根据桶的访问权限，主要分为两种：公开和私有。公开桶意味着所有人都可以不需要任何许可地访问你其中的文件，而你要为此付钱。私有桶则需要使用API Key之类的东西鉴权后才能访问，这通常要求实现了特定协议的客户端（比如S3协议），而浏览器是不具备这种功能的。我不是百万富翁，我怕被别人刷流量刷爆账单，所以我选择私有桶。搭建过程主要参考这篇文章：https://www.backblaze.com/docs/cloud-storage-deliver-private-backblaze-b2-content-through-cloudflare-cdn第一步是去BackBlaze创建一个私有桶，然后创建一个Application Key用来给Worker访问这个桶（推荐使用只读权限，并仅限于这个桶，并且不允许list bucket）。你也可以上传一些测试图片用于验证。接下来我们要配置CloudFlare Worker。由于CloudFlare Worker使用JavaScript（虽然他们也支持别的语言，但从费用上来说还是JS最划算），因此NodeJS必不可少。我电脑上有安装nvm（视窗操作系统用户可以考虑使用nvm-windows），使用它可以方便地管理多个NodeJS版本。要使用Worker的sdk，NodeJS版本要在16.17.0之后。我使用的是20.17.0版本，之前安装过的。首先使用npx wrangler安装这个名叫wrangler的工具，它是我们和Worker交互的命令行工具。我不善JS，索性BackBlaze官方给出了一个示例仓库，我们直接clone即可：git clone https://github.com/backblaze-b2-samples/cloudflare-b2.git cd cloudflare-b2 npm install cp wrangler.toml.template wrangler.toml现在我们就可以编辑wrangler.toml这个文件了。按照里面的注释，填写B2_APPLICATION_KEY_ID和B2_ENDPOINT等字段，这些信息都可以在BackBlaze的控制台找到。我这里没有开list bucket和rclone下载，因为我只是想用它做个分发图片的CDN。至于桶的名称，由于我的域名中不包含任何桶的名称，因此我直接填写的固定值。根据这个字段的注释，你可以实现一些更高端的功能。如果你想追求极致的精简（比如通过减少一些分支判断来节省几纳秒的CPU时间…

【歪门邪道】使用Cloudflare作为ddns更新IPv6域名DNS
type: item
date: 2024-11-01T08:19:00+08:00
description: 上一篇文章无意中发现了我的公网IPv6地址是能够联通的，并且实际联机体验较为不错。但由于没钱买商宽，所以没有静态IP，而每次IP变动都会带来麻烦，因此本篇将探索如何使用Cloudflare API来更新域名DNS，四舍五入成为一个dDNS。IPv6公网地址虽然好，但毕竟是动态的。虽然Minecraft本身对于服务器的地址没什么要求，但一些mod，例如小地图，它使用服务器的地址来区分数据。也就是说，当IP变动时，即便服务器还是原来的服务器，但对于小地图mod来说，这就是一个新的服务器，因此之前加载的地图缓存和路经点也就全没了。前些日子刚好想起来我还有个域名托管在Cloudflare，主要是利用它的tunnel服务来将内网或一些临时性的服务分享到公网上（一方面是懒得更新DNS，另一方面是懒得搞SSL证书）。我原本也想用tunnel服务将Minecraft服务器映射出去，但简单测试后发现延迟波动比较大，而且延迟普遍有点高，不适合联机。这时我突然意识到，Cloudflare提供了完备的API，即便官方没有提供ddns客户端，我也可以通过调用API的方式更新域名的DNS记录。想来想去，由于我用的是Linux系统，因此实现的最佳方式便是bash，恰好Cloudflare的API文档也提供了多种多样的调用例子，其中就包含了Shell/curl：https://developers.cloudflare.com/api/operations/zones-get要访问Cloudflare API，第一步就是要获取访问密钥，也就是所谓的API Token，这一步在账户设置里就可以找到。关键点在于创建的Token不光要能Edit Zone设置，还要能Read，不然后面第一步获取id就失败了。我一开始以为Edit蕴含了Read权限，所以是我调用的方式不对，结果发现是我token的权限没给。api_email="your login email address" api_key="your api token"在Cloudflare中，网页中显示的website，实际上是DNS Zone。要操作一个DNS Zone，我们不能直接用名字，我们要用它的ID。根据文档，我们可以直接按照Zone的名字（也就是域名）进行筛选：zone_name="example.com" zone_id=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" \ -H "X-Auth-Email: $api_email" \ -H "Authorization: Bearer $api_key" \ -H "Content-Type: application/json" | jq -r .result[0].id ) echo Zone $zone_name id is: $zone_id这里我们用jq这个工具从返回的Json中获取我们想要的结果。拿到Zone ID之后，若要修改一个记录（Record），我们同样需要ID。根据文档，我们使用记录的完整域名和zone id进行查询：record_name="ddns.example.com" record_id=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?type=AAAA&name=$record_name" \ -H "X-Auth-Email: $api_email" \ -H "Authorization: Bearer $api_key" \ -H "Content-Type: application/json" | jq -r .result[0].id ) echo Record $record_name id is: $record_id同样地，使用jq来解析Json。拿到了这两个ID我们就可以更新DNS记录了。这里要先在网页面板上创建好一个AAAA记录（用于IPv6），至于实际地址可以随便写，比如::1。关于TTL，因为IP可能会随时变动，因此直接设置为最小值，以便IP更新后朋友那边可以直接获取到最新的记录。那么，IPv6怎么获取呢？经过一番awk的现学现卖，我得到了如下命令：v6Addr=$(ip -6 addr show scope global | grep /128 | awk -F '[ \t]+|/' '{print $3}' | grep -v ^fd7a)在上一篇文章中可以得知，我的NUC是能够获得一个/128的公网IP。我先通过ip addr命令的变体找出所有公网IPv6地址，然…