summary
backblaze: also known as b2, it is a cloud storage platform that can upload its own files to the cloud and provide a url that can be accessed from the outside. Visit pictures in this article
Cloudflare: a CDN that caches web pages. Our purpose is to cache backblaze images so that users can see the traffic without backblaze and cloudflare.
Backblaze in the bandwidth alliance of cloudflare, the traffic between the two is free. Use backblaze here to make all user traffic go through the bandwidth alliance
Bandwidth Alliance: https://www.cloudflare.com/zh-cn/bandwidth-alliance/
backblaze
Register backblaze (your own test account)
B2 Cloud Storage -> Sign Up
Create bucket
My Account -> Buckets -> Create a Bucket
When creating, you need to fill in Bucket Unique Name and choose private or public
Here, in order to prevent people with ulterior motives from brushing the traffic of backblaze, a private bucket is created, so that users can not connect directly to backblaze, but only to cloudflare
Upload file
My account - > browse files or my account - > buckets - > upload / download
In the Browse Files interface, click the small "i" on the right side of each file to display the picture link
Interface calls are charged. The first 2500 calls a day are free. If the number of calls exceeds, an error will be reported unless you join the charging plan
# Error text Transaction cap exceeded, see the Caps & Alerts page to increase your cap.
Add app key
MyAccount -> App Keys -> add a new application key
Set the permissions of the key to which bucket s
The key id and the key ontology only appear once. Please write them down!!!
Apply for test domain name
Tencent cloud buys a one-year root domain name for more than 30 yuan
Tencent cloud - > search for domain name registration - > buy one for one year
Tencent cloud - > console - > go to dnspod console - > configure dns
cloudflare
Register cloudflare
https://dash.cloudflare.com/
Add root domain name to cloudflare
cloud flare console - > add site - > input the root domain name just registered - > select the "free" plan - > add a cname record and put < write a name yourself > superggn. Com points to the b2 domain name (f000.backblazeb2.com)
adopt https://image.superggn.com/file// Accessing public bucket files
Add cache rule
CF -> superggn.com -> Rules -> Create Page Rule
URL: image.superggn.com/*
Cache level: standard
Configure dns at the domain name service provider
Tencent cloud - > console - > go to dnspod console - > configure dns
Modify the domain name wherever you buy it
Configure worker
summary
Functions realized by worker:
Modify in direction link
Access b2 private bucket
Specific configuration
CF -> superggn. Com - > workers - > manage workers
Create worker
Do not edit temporarily, save and deploy directly
Remember the name of the worker
CF -> superggn. Com - > workers - > Add route
Route: image superggn. com/*
That is, our test domain name obtained in the dns configuration step is bound to the newly established worker
python script update worker
Preconditions:
backblaze
b2 bucket name
b2 bucket id
Get in bucket
b2 app key id
b2 app key
app key generated in backblaze (specifies which bucket can be accessed)
cloudflare
cf worker account id
workers -> manage workers
Right column account id
cf worker name
cf worker api key
my profile -> api tokens -> create token
Select the Edit Cloudflare Workers template
Script function
Worker is essentially a script running on an ip, so worker name and script name are equivalent
Send a request to backblaze to obtain the b2 auth token (you can't access the private bucket without this token) (the maximum validity is 7 days. You can try to set maxSecondsAuthValid longer and report an error directly), and update the obtained b2 auth token to cloudflare worker script to realize access authorization
Request lifecycle
Request - cloudflare - worker - backblaze
Script body
Pay attention to replacing variables
import base64 import json import requests ETC_ROOT = '/etc/DiceServer' with open('{}/cloudflare_backblaze_config.txt'.format(ETC_ROOT)) as f: CLOUDFLARE_BACKBLAZE_CONFIG_LIST = f.read().strip().split() # backblaze config B2_BUCKET_NAME = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[1] BUCKET_SOURCE_ID = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[3] # backblaze config for b64 encoding B2_APP_KEY_ID = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[5] B2_APP_KEY = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[7] B2_DOMAIN = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[9] # cloudflare config CF_WORKER_ACCOUNT_ID = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[11] CF_WORKER_API_KEY = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[13] CF_WORKER_NAME = CLOUDFLARE_BACKBLAZE_CONFIG_LIST[15] flagDebug = True # An authorization token is valid for not more than 1 week # This sets it to the maximum time value maxSecondsAuthValid = 7 * 24 * 60 * 60 # one week in seconds # DO NOT CHANGE ANYTHING BELOW THIS LINE ### baseAuthorizationUrl = 'https://api.backblazeb2.com/b2api/v2/b2_authorize_account' b2GetDownloadAuthApi = '/b2api/v2/b2_get_download_authorization' # Get fundamental authorization code idAndKey = B2_APP_KEY_ID.encode() + b':' + B2_APP_KEY.encode() b2AuthKeyAndId = base64.b64encode(idAndKey) basicAuthString = 'Basic ' + b2AuthKeyAndId.decode('UTF-8') authorizationHeaders = {'Authorization': basicAuthString} resp = requests.get(baseAuthorizationUrl, headers=authorizationHeaders) if flagDebug: print("resp.status_code", resp.status_code) print("resp.headers", resp.headers) print("resp.content", resp.content.decode()) print("_____________") respData = json.loads(resp.content.decode("UTF-8")) bAuToken = respData["authorizationToken"] bFileDownloadUrl = respData["downloadUrl"] bPartSize = respData["recommendedPartSize"] bApiUrl = respData["apiUrl"] # Get specific download authorization getDownloadAuthorizationUrl = bApiUrl + b2GetDownloadAuthApi downloadAuthorizationHeaders = {'Authorization': bAuToken} resp2 = requests.post(getDownloadAuthorizationUrl, json={'bucketId': BUCKET_SOURCE_ID, 'fileNamePrefix': "", 'validDurationInSeconds': maxSecondsAuthValid}, headers=downloadAuthorizationHeaders) resp2Content = resp2.content.decode("UTF-8") resp2Data = json.loads(resp2Content) bDownAuToken = resp2Data["authorizationToken"] if flagDebug: print("authorizationToken: " + bDownAuToken) print("downloadUrl: " + bFileDownloadUrl) print("recommendedPartSize: " + str(bPartSize)) print("apiUrl: " + bApiUrl) workerTemplate = """ addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { let authToken = '<B2_DOWNLOAD_TOKEN>' const b2Domain = '<B2_DOMAIN>' const b2UrlPath = '/file/<B2_BUCKET_NAME>/' let b2Headers = new Headers(request.headers) const url = new URL(request.url) if (url.host === b2Domain && !url.pathname.startsWith(b2UrlPath)) { url.pathname = b2UrlPath + url.pathname; } b2Headers.append("Authorization", authToken) modRequest = new Request(url, { method: request.method, headers: b2Headers }) const response = await fetch(modRequest) return response } """ workerCode = workerTemplate.replace('<B2_DOWNLOAD_TOKEN>', bDownAuToken) workerCode = workerCode.replace('<B2_BUCKET_NAME>', B2_BUCKET_NAME) workerCode = workerCode.replace('<B2_DOMAIN>', B2_DOMAIN) cfHeaders = {'Authorization': "Bearer " + CF_WORKER_API_KEY, 'Content-Type': 'application/javascript'} cfUrl = 'https://api.cloudflare.com/client/v4/accounts/' + CF_WORKER_ACCOUNT_ID + "/workers/scripts/" + CF_WORKER_NAME resp = requests.put(cfUrl, headers=cfHeaders, data=workerCode) if flagDebug: print(resp) print(resp.headers) print(resp.content) """ workerCode = workerTemplate.replace('<B2_DOWNLOAD_TOKEN>', bDownAuToken) workerCode = workerCode.replace('<B2_BUCKET_NAME>', b2BucketName) cfHeaders = {'Authorization': "Bearer " + cfWorkerApiKey, 'Content-Type': 'application/javascript'} cfUrl = 'https://api.cloudflare.com/client/v4/accounts/' + cfWorkerAccountId + "/workers/scripts/" + cfWorkerName resp = requests.put(cfUrl, headers=cfHeaders, data=workerCode) if flagDebug: print(resp) print(resp.headers) print(resp.content) print("_______________")
Set sensitive variables
Set the script to execute regularly through crontab
Update script file_ cloudflare_ worker. Py (whatever name you choose) is placed in the cron script directory of the test server (you can directly see where other scripts are placed through crontab -l)
cd /home/ubuntu/test_crontab vim update_cloudflare_worker.py # Paste the script in, save and exit crontab -l crontab -e # Add a row below * * * * * python3 /home/ubuntu/test_crontab/update_cloudflare_worker.py # Save exit
test
function
Reference link
public bucket
https://help.backblaze.com/hc/en-us/articles/217666928-Using-Backblaze-B2-with-the-Cloudflare-CDN
private bucket
https://help.backblaze.com/hc/en-us/articles/360010017893-How-to-allow-Cloudflare-to-fetch-content-from-a-Backblaze-B2-private-bucket
Remove / file in the middle of the link//
https://www.reddit.com/r/backblaze/comments/i3t104/using_cloudflarebackblaze_b2_can_i_remove/
https://jross.me/free-personal-image-hosting-with-backblaze-b2-and-cloudflare-workers/
Domestic course
https://dukeluo.me/2020/02/12/blog-clean-plan-1.html
https://www.wangfuchao.com/1290/