使用Backblaze B2搭建免费的自定义域名图床和对象存储

使用Backblaze B2和Cloudflare Workers搭建免费的自定义域名图床和对象存储。

在我们建设运行博客和其他中小型网站的时候,常常需要用到类似于阿里OSS和腾讯COS这类似的对象存储服务,用于作为图床和zip、rar等文件的存储。尧言来来回回折腾了N多家的对象存储服务,最后某些网站的对象存储定为了阿里云的OSS。

某些站点由于备案和众所周知的其他原因,国内的对象存储是比较难满足需求的,在尝试了AWS的S3和Google Cloud之后,还是觉得美中不足,直到有一天遇到Backblaze。下面记录一下如何使用Backblaze B2和Cloudflare Workers搭建免费的自定义域名图床和对象存储。

各组件服务介绍

  • Backblaze B2

Backblaze B2 是一个云存储解决方案,类似于Amazon AWS S3, 但是价格稍微便宜一些. 前 10GB 存储是完全免费的.  通常情况下,像使用 AWS S3 这类的服务,你必须为所提供的内容支付带宽费用,这通常是费用中最高的部分。不过,由于有了 Bandwidth Alliance(带宽联盟),Backblaze 到 Cloudflare 之间的出口是完全免费的,我们将大量使用这一优势。

  • Cloudflare

最强大实用的DNS和CND服务提供商,没有之一。

免费额度

100,000 requests per day.(一天 10万次请求)

Up to 10ms CPU time per request.(每次请求最大占用 CPU 工作时间为 10ms)

First 10 GB for free.(前 10GB 存储免费)

The first 1 GB of data downloaded each day is free.(每天前 1GB 下载免费)

因为有 Bandwidth Alliance(带宽联盟),这个限制我们可以忽略不计。

Class “B” transactions - $0.004 per 10,000 with 2,500 free per day.(B 类传输,每天前 2500 次免费)

Cloudflare Workers 需要用到的 b2_download_file_by_name,属于 B 类传输。

Backblaze B2 提供了 10G 的免费存储空间,并且搭配 Cloudflare 的 page rules 来配置一些缓存规则,对于个人用户绰绰有余。Backblaze 当前的配额使用量可以在面板的 “Caps & Alerts” 查看,修改配额会要求提供信用卡,以便用于付费。所以,在你提供信用卡之前,一切都是免费的。

开始设置和配置

  • 创建 Backblaze B2 Bucket(存储桶)

注册登陆Backblaze账号后,创作一个桶,然后会得到一个类似于下面的界面,这里有我们下一步需要用到的信息。我们需要记住下图标记的类似于s3.us-west-002.backblazeb2.com的域名。

  • Cloudflare DNS

获取了上面的信息后,我们需要去到Cloudflare添加一条我们图床域名的解析记录,主机名我们自己决定,尧言用的是img;记录值是“桶的名字.上一步我们获取的域名”,就像yaoyan.s3.us-west-002.backblazeb2.com

例如尧言用的图床域名是img.yaoyan.info,桶的名字是yaoyan,则是把img解析到yaoyan.s3.us-west-002.backblazeb2.com就可以了。对了,要开启代理哦,就是Cloudflare的那朵云是亮的,这代表请求是通过了 Cloudflare 的 CDN 代理层。Cloudflare 默认的 TTL 将被设置为 auto(自动),对于我们的使用已经足够。

如果你的文件不会经常改变,我强烈建议你,添加一条 page-rule(页面规则) 来设置 “cache level(缓存等级)” 为 “everything(所有)”, 并且 “edge cache TTL(边界缓存存活时间)” 设置为较高的值,比如 7天。

然后,你还需要到Backblaze B2,在Bucket Info:处添加缓存时间,该时间越长那么文件在CloudFlare CDN节点上缓存的时间越长,单位为秒,请根据需要来设定。以一年的时间为例也就是31536000秒,一月的话就是2592000秒,一周的话就是604800秒,一天的话就是86400秒。

{"cache-control":"max-age=31536000"}

  • Cloudflare Workers

通常来说, 现在这样,一切都可以正常工作了,如果你只要一个基础的图片存储,那么,你不需要配置其他的东西。但是,为了一些其他的酷炫效果,我们可以使用 Cloudflare Workers来重写图片的 URL 使链接更加友好, 比如从 URL 中去掉无用的 /file// 部分. 举个例子, https://subdomain.domain.com/file//test.txt链接将会变成https://subdomain.domain.com/test.txt.

Cloudflare Workers 允许你在 Cloudflare 全球网络中的边界服务器运行 JavaScript 代码, 使开发者可以部署 serverless(无需服务器) 的应用程序,并且自动缩放. 对于部署的 worker , 以下是我们想要达到的目标:

去除 URL 中的 /file/ 部分;
去除一些从 Backblaze B2 响应的无用请求头;
加上基本的 CORS 请求头,以便允许图片嵌入到网站中;
为图片优化缓存 (浏览器的缓存, 以及 CDN 边界服务器上的缓存)

在 Cloudflare 你的域名处, 创建一个新的 worker 脚本。

以下代码是我在 worker 中使用的(感谢原作者,他的脚本利用的 Cloudflare 边界服务器的缓存,使得请求不再发送到 Backblaze 去获取图片文件,我在他的脚本基础上进行修改)。

使用前,注意修改 b2Domain 和 b2Bucket 这两个变量的值。b2Domain是你图床的二级域名。 b2Bucket是你的 bucket 存储桶的名字。

'use strict';
const b2Domain = 'img.domain.com'; // configure this as per instructions above
const b2Bucket = 'bucket-name'; // configure this as per instructions above
const b2UrlPath = `/file/${b2Bucket}/`;
addEventListener('fetch', event => {
return event.respondWith(fileReq(event));
});

// define the file extensions we wish to add basic access control headers to
const corsFileTypes = ['png', 'jpg', 'gif', 'jpeg', 'webp'];

// backblaze returns some additional headers that are useful for debugging, but unnecessary in production. We can remove these to save some size
const removeHeaders = [
'x-bz-content-sha1',
'x-bz-file-id',
'x-bz-file-name',
'x-bz-info-src_last_modified_millis',
'X-Bz-Upload-Timestamp',
'Expires'
];
const expiration = 31536000; // override browser cache for images - 1 year

// define a function we can re-use to fix headers
const fixHeaders = function(url, status, headers){
let newHdrs = new Headers(headers);
// add basic cors headers for images
if(corsFileTypes.includes(url.pathname.split('.').pop())){
newHdrs.set('Access-Control-Allow-Origin', '*');
}
// override browser cache for files when 200
if(status === 200){
newHdrs.set('Cache-Control', "public, max-age=" + expiration);
}else{
// only cache other things for 5 minutes
newHdrs.set('Cache-Control', 'public, max-age=300');
}
// set ETag for efficient caching where possible
const ETag = newHdrs.get('x-bz-content-sha1') || newHdrs.get('x-bz-info-src_last_modified_millis') || newHdrs.get('x-bz-file-id');
if(ETag){
newHdrs.set('ETag', ETag);
}
// remove unnecessary headers
removeHeaders.forEach(header => {
newHdrs.delete(header);
});
return newHdrs;
};
async function fileReq(event){
const cache = caches.default; // Cloudflare edge caching
const url = new URL(event.request.url);
if(url.host === b2Domain && !url.pathname.startsWith(b2UrlPath)){
url.pathname = b2UrlPath + url.pathname;
}
let response = await cache.match(url); // try to find match for this request in the edge cache
if(response){
// use cache found on Cloudflare edge. Set X-Worker-Cache header for helpful debug
let newHdrs = fixHeaders(url, response.status, response.headers);
newHdrs.set('X-Worker-Cache', "true");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHdrs
});
}
// no cache, fetch image, apply Cloudflare lossless compression
response = await fetch(url, {cf: {polish: "lossless"}});
let newHdrs = fixHeaders(url, response.status, response.headers);

if(response.status === 200){

response = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHdrs
});
}else{
response = new Response('File not found!', { status: 404 })
}

event.waitUntil(cache.put(url, response.clone()));
return response;
}

你需要进入 workers 功能,点击 Launch Editor ,进入编辑器,将以上代码拷贝到编辑器中,然后保存 worker。

使用了这个 worker 后, 你可以从 URL 中去掉 /file// 部分, 使得生成的 URL 是这样的形式 https://subdomain.domain.com/test.txt, 而不是 https://subdomain.domain.com/file//test.txt

你需要添加一条 worker 的路由规则,使访问 subdomain.domain.com/*时,请求先由 worker 来处理。

  • 防盗链

可以在 Cloudflare 的 Firewall 功能中,添加一条 firewall rule

(not http.referer contains “www.yaoyan.info” and http.request.full_uri contains “https://img.yaoyan.info")

拒绝block你不想要的请求达到防盗链的效果。

当然还有一个防盗链更直接的方法,就是直接在Cloudflare的Scrape Shield里面开启Hotlink 保护即可。

两种方法各有优劣,根据自己的需求配置即可。

相关推荐:

  1. 腾讯云优惠活动汇总
  2. 2021中季度全球访问量最高网站榜单
  3. AWS亚马逊S3存储如何绑定自定义域名
  4. 可以利用这些工具来进行批量外链发布
  5. 最好的免费博客平台之一

评论