Skip to content

Instantly share code, notes, and snippets.

@lzjluzijie
Last active April 23, 2025 12:39
Show Gist options
  • Save lzjluzijie/3f1294f47755972f9bcd68f90ffc0b73 to your computer and use it in GitHub Desktop.
Save lzjluzijie/3f1294f47755972f9bcd68f90ffc0b73 to your computer and use it in GitHub Desktop.

Revisions

  1. lzjluzijie revised this gist Dec 19, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion how-to.md
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ Cloudflare now offers free Transform Rules, so BackBlaze B2 users can use URL Re

    URL Rewrite is quite simple. In Cloudflare dashboard, choose your domain -> Rules -> Transform Rules. Create a new Rewrite URL rule. It simply matches the domain, and dynamically rewrites to `concat("/file/<YOUR_BUCKET_ID>", http.request.uri.path)`.

    ![url-rewrite-rule](/图片/通过-cloudflare-transform-rules-访问-private-backblaze-b2-bucket/url-rewrite-rule.png)
    ![url-rewrite-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/url-rewrite-rule.png)

    ## Access Private Bucket

  2. lzjluzijie revised this gist Dec 19, 2021. 2 changed files with 56 additions and 35 deletions.
    26 changes: 19 additions & 7 deletions README.md → how-to.md
    Original file line number Diff line number Diff line change
    @@ -2,30 +2,34 @@

    [Original post](https://halu.lu/%E7%AC%94%E8%AE%B0/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/) from my Blog.

    Cloudflare now offers free Transform Rules, so BackBlaze B2 users can use `URL Rewrite Rules` rules to hide bucket name and use `Request Header Modification Rules` to provide access to private bucket.
    Cloudflare now offers free Transform Rules, so BackBlaze B2 users can use URL Rewrite rules to hide bucket name and provide access to private bucket.

    **TLDR**: Create a URL Rewrite Rule and hide your bucket name. If your bucket is private, you also need to create a Cloudflare Worker, copy the code and fill in the config.

    ## Hide Bucket Name

    URL Rewrite is quite simple. In Cloudflare dashboard, choose your domain -> Rules -> Transform Rules. Create a new Rewrite URL rule. It simply matches the domain, and dynamically rewrites to `concat("/file/<YOUR_BUCKET_ID>", http.request.uri.path)`.

    ![url-rewrite-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/url-rewrite-rule.png)
    ![url-rewrite-rule](/图片/通过-cloudflare-transform-rules-访问-private-backblaze-b2-bucket/url-rewrite-rule.png)

    ## Access Private Bucket

    If you want to access your private bucket from Cloudflare. You first need to create a BackBlaze Application Key. You need the `keyID` and `applicationKey` to generate a token, which is used to access files from the private bucket.

    You can read the [B2 documentation](https://www.backblaze.com/b2/docs/b2_authorize_account.html) about how to generate the token. Once you have the token, still under Transform Rules, create a new Modify Request Header Rule. It still matches the domain, and statically adds the token to the `Authorization` header.
    You can read the [B2 documentation](https://www.backblaze.com/b2/docs/b2_authorize_account.html) about how to generate the token. We can use the token to download files from private buckets in two ways: add `Authorization` in request header or add `Authorization` param in request query. The first header option needs additional "Request Header Modification rule" and the response cannot be cached by Cloudflare, so we use the second method.

    ![request-header-modification-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/request-header-modification-rule.png)
    Edit the URL Rewrite rule we created to hide bucket name, in `Query` choose "Rewrite to", select `Static` and enter `Authorization=<Token>`.

    The problem is that the token is only at most 24 hours. So I write this script to automatically create token and update the rule. You can create a Cloudflare worker to do the job and set `Triggers` to run every 30 minutes.

    Create a Cloudflare worker. The name does not matter since we use the Trigger of the worker. Open the quick editor. Copy and paste the code.

    The constants you need to fill in:
    The configs you need to fill in:

    - `B2KeyID` and `B2AppKey` by create a BackBlaze Application Key.

    - `B2BucketID`: Your BackBlaze B2 bucket ID.

    - `cfDomain`: The domain you want to access b2 from.

    - `cfAuthEmail`: Your Cloudflare email.
    @@ -34,14 +38,22 @@ The constants you need to fill in:

    - `cfZoneID`: Your domain zone ID from the overview dashboard of your domain.

    - `cfRulesetID`: This one is a little hard. You need first create the Modify Request Header Rule. Then use the following curl command to view all the rules you have. Find the rule with phase `http_request_late_transform`. Its `id` is the `cfRulesetID` we want.
    - `cfRulesetID`: You need first create the URL Rewrite rule. Then use the following curl command to view all the rulesets you have. Find the ruleset with phase `http_request_transform`. Its `id` is the `cfRulesetID` we want.

    ```bash
    curl -X GET \
    -H "X-Auth-Email: <cfAuthEmail>" \
    -H "X-Auth-Key: <cfAuthKey>" \
    "https://api.cloudflare.com/client/v4/zones/<cfZoneID>/rulesets"
    ```

    - `cfRuleID`: Once you have the `cfRulesetID`, use the following curl command to view the rules you have in the rule set. Find the rule you created in Cloudflare dashboard, its `id` is the `cfRuleID` we want.

    Once you fill in the constants, you can by `Save and Deploy` and then `Run`.
    ```bash
    curl -X GET \
    -H "X-Auth-Email: <cfAuthEmail>" \
    -H "X-Auth-Key: <cfAuthKey>" \
    "https://api.cloudflare.com/client/v4/zones/<cfZoneID>/rulesets/<cfRulesetID>"
    ```

    Once you fill in the constants, you can by `Save and Deploy` and then `Run`.
    65 changes: 37 additions & 28 deletions worker.js
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,26 @@
    // B2 settings
    const B2KeyID = ''
    const B2AppKey = ''
    // Cloudflare settings
    const cfDomain = ''
    const cfAuthEmail = ''
    const cfAuthKey = ''
    const cfZoneID = ''
    const cfRulesetID = ''
    const config = {
    // B2 config
    B2KeyID: '',
    B2AppKey: '',
    B2BucketID: '',
    // Cloudflare config
    cfDomain: '',
    cfAuthEmail: '',
    cfAuthKey: '',
    cfZoneID: '',
    cfRulesetID: '',
    cfRuleID: ''
    }

    addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
    })
    addEventListener("scheduled", event => {
    event.waitUntil(handleRequest(event.request))
    event.waitUntil(updateRule(config))
    })

    const getB2Token = async () => {
    const getB2Token = async (config) => {
    const { B2KeyID, B2AppKey } = config
    const res = await fetch('https://api.backblazeb2.com/b2api/v2/b2_authorize_account', {
    headers: {
    'Authorization': 'Basic ' + btoa(B2KeyID + ":" + B2AppKey)
    @@ -25,35 +30,39 @@ const getB2Token = async () => {
    return data.authorizationToken
    }

    async function handleRequest(request) {
    const b2Token = await getB2Token()
    const updateRule = async (config) => {
    const b2Token = await getB2Token(config)
    const { B2BucketID, cfDomain, cfAuthEmail, cfAuthKey, cfZoneID, cfRulesetID, cfRuleID} = config

    const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${cfZoneID}/rulesets/${cfRulesetID}`, {
    method: 'PUT',
    const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${cfZoneID}/rulesets/${cfRulesetID}/rules/${cfRuleID}`, {
    method: 'PATCH',
    headers: {
    'X-Auth-Email': cfAuthEmail,
    'X-Auth-Key': cfAuthKey
    },
    body: `{
    "rules": [
    {
    "expression": "(http.host eq \\\"${cfDomain}\\\")",
    "description": "B2 auth",
    "action": "rewrite",
    "action_parameters": {
    "headers": {
    "Authorization": {
    "operation": "set",
    "value": "${b2Token}"
    }
    }
    "description": "B2 ${B2BucketID}",
    "action": "rewrite",
    "expression": "(http.host eq \\\"${cfDomain}\\\")",
    "action_parameters": {
    "uri": {
    "path": {
    "expression": "concat(\\\"/file/${B2BucketID}\\\", http.request.uri.path)"
    },
    "query": {
    "value": "Authorization=${b2Token}"
    }
    }
    ]
    }
    }`
    })

    const data = await res.text()
    console.log(data)
    return data
    }

    async function handleRequest(request) {
    const data = await updateRule(config)
    return new Response(data)
    }
  3. lzjluzijie revised this gist Dec 16, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion worker.js
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ async function handleRequest(request) {
    body: `{
    "rules": [
    {
    "expression": "(http.host eq \\\"b2.halu.lu\\\") or (http.host eq \\\"yy.halu.lu\\\")",
    "expression": "(http.host eq \\\"${cfDomain}\\\")",
    "description": "B2 auth",
    "action": "rewrite",
    "action_parameters": {
  4. lzjluzijie revised this gist Dec 16, 2021. 1 changed file with 7 additions and 2 deletions.
    9 changes: 7 additions & 2 deletions worker.js
    Original file line number Diff line number Diff line change
    @@ -11,6 +11,9 @@ const cfRulesetID = ''
    addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
    })
    addEventListener("scheduled", event => {
    event.waitUntil(handleRequest(event.request))
    })

    const getB2Token = async () => {
    const res = await fetch('https://api.backblazeb2.com/b2api/v2/b2_authorize_account', {
    @@ -34,7 +37,7 @@ async function handleRequest(request) {
    body: `{
    "rules": [
    {
    "expression": "(http.host eq \\\"${cfDomain}\\\")",
    "expression": "(http.host eq \\\"b2.halu.lu\\\") or (http.host eq \\\"yy.halu.lu\\\")",
    "description": "B2 auth",
    "action": "rewrite",
    "action_parameters": {
    @@ -50,5 +53,7 @@ async function handleRequest(request) {
    }`
    })

    return new Response(await res.text())
    const data = await res.text()
    console.log(data)
    return new Response(data)
    }
  5. lzjluzijie revised this gist Dec 12, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ You can read the [B2 documentation](https://www.backblaze.com/b2/docs/b2_authori

    ![request-header-modification-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/request-header-modification-rule.png)

    The problem is that the token is only at most 24 hours. So I write this script to automatically create token and update the rule. You can create a Cloudflare worker to do the job and set `Triggers` to run every 3 hours.
    The problem is that the token is only at most 24 hours. So I write this script to automatically create token and update the rule. You can create a Cloudflare worker to do the job and set `Triggers` to run every 30 minutes.

    Create a Cloudflare worker. The name does not matter since we use the Trigger of the worker. Open the quick editor. Copy and paste the code.

  6. lzjluzijie created this gist Dec 6, 2021.
    47 changes: 47 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    # Access Private BackBlaze B2 Bucket from Cloudflare Transform Rules

    [Original post](https://halu.lu/%E7%AC%94%E8%AE%B0/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/) from my Blog.

    Cloudflare now offers free Transform Rules, so BackBlaze B2 users can use `URL Rewrite Rules` rules to hide bucket name and use `Request Header Modification Rules` to provide access to private bucket.

    ## Hide Bucket Name

    URL Rewrite is quite simple. In Cloudflare dashboard, choose your domain -> Rules -> Transform Rules. Create a new Rewrite URL rule. It simply matches the domain, and dynamically rewrites to `concat("/file/<YOUR_BUCKET_ID>", http.request.uri.path)`.

    ![url-rewrite-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/url-rewrite-rule.png)

    ## Access Private Bucket

    If you want to access your private bucket from Cloudflare. You first need to create a BackBlaze Application Key. You need the `keyID` and `applicationKey` to generate a token, which is used to access files from the private bucket.

    You can read the [B2 documentation](https://www.backblaze.com/b2/docs/b2_authorize_account.html) about how to generate the token. Once you have the token, still under Transform Rules, create a new Modify Request Header Rule. It still matches the domain, and statically adds the token to the `Authorization` header.

    ![request-header-modification-rule](https://halu.lu/%E5%9B%BE%E7%89%87/%E9%80%9A%E8%BF%87-cloudflare-transform-rules-%E8%AE%BF%E9%97%AE-private-backblaze-b2-bucket/request-header-modification-rule.png)

    The problem is that the token is only at most 24 hours. So I write this script to automatically create token and update the rule. You can create a Cloudflare worker to do the job and set `Triggers` to run every 3 hours.

    Create a Cloudflare worker. The name does not matter since we use the Trigger of the worker. Open the quick editor. Copy and paste the code.

    The constants you need to fill in:

    - `B2KeyID` and `B2AppKey` by create a BackBlaze Application Key.

    - `cfDomain`: The domain you want to access b2 from.

    - `cfAuthEmail`: Your Cloudflare email.

    - `cfAuthKey`: Your **Global API Key** from [API Tokens](https://dash.cloudflare.com/profile/api-tokens).

    - `cfZoneID`: Your domain zone ID from the overview dashboard of your domain.

    - `cfRulesetID`: This one is a little hard. You need first create the Modify Request Header Rule. Then use the following curl command to view all the rules you have. Find the rule with phase `http_request_late_transform`. Its `id` is the `cfRulesetID` we want.

    ```bash
    curl -X GET \
    -H "X-Auth-Email: <cfAuthEmail>" \
    -H "X-Auth-Key: <cfAuthKey>" \
    "https://api.cloudflare.com/client/v4/zones/<cfZoneID>/rulesets"
    ```

    Once you fill in the constants, you can by `Save and Deploy` and then `Run`.

    54 changes: 54 additions & 0 deletions worker.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    // B2 settings
    const B2KeyID = ''
    const B2AppKey = ''
    // Cloudflare settings
    const cfDomain = ''
    const cfAuthEmail = ''
    const cfAuthKey = ''
    const cfZoneID = ''
    const cfRulesetID = ''

    addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
    })

    const getB2Token = async () => {
    const res = await fetch('https://api.backblazeb2.com/b2api/v2/b2_authorize_account', {
    headers: {
    'Authorization': 'Basic ' + btoa(B2KeyID + ":" + B2AppKey)
    }
    })
    const data = await res.json()
    return data.authorizationToken
    }

    async function handleRequest(request) {
    const b2Token = await getB2Token()

    const res = await fetch(`https://api.cloudflare.com/client/v4/zones/${cfZoneID}/rulesets/${cfRulesetID}`, {
    method: 'PUT',
    headers: {
    'X-Auth-Email': cfAuthEmail,
    'X-Auth-Key': cfAuthKey
    },
    body: `{
    "rules": [
    {
    "expression": "(http.host eq \\\"${cfDomain}\\\")",
    "description": "B2 auth",
    "action": "rewrite",
    "action_parameters": {
    "headers": {
    "Authorization": {
    "operation": "set",
    "value": "${b2Token}"
    }
    }
    }
    }
    ]
    }`
    })

    return new Response(await res.text())
    }