笨蛋ovo

笨蛋ovo

Add Backblaze B2 support to Cloudreve

image.png

The latest configuration tutorial has been synchronized to the Cloudreve official documentation
If you need a more concise version, please refer directly to the official documentation
The official documentation was also written by me

Problem Analysis#

First, configure according to the Cloudreve official documentation, and you will likely find that after configuration, uploading still reports an error (obviously, if it didn't report an error, I wouldn't be writing this article)

Open F12 to check the request; there is a cross-origin error in the console.

Access to XMLHttpRequest at 'https://s3.us-east-001.backblazeb2.com/xxx' from origin 'https://demo.cloudreve.org' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Then check the response headers.

Cache-Control: max-age=0, no-cache, no-store
Connection: keep-alive
Content-Length: 216
Content-Type: application/xml
Date: Wed, 19 Jun 2024 15:54:31 GMT
Server: nginx
Strict-Transport-Security: max-age=63072000
X-Amz-Id-2: aM+Y1ZDJYZBU2hn2JYjDlOMNkuWF2
X-Amz-Request-Id: 4c38if3n9n98732

It is obvious that the cross-origin header is missing.

Here we will compare with the response headers from Cloudflare R2.

Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag
Cf-Ray: 89649ob992b2d0f-LAX
Connection: keep-alive
Content-Length: 0
Date: Wed, 19 Jun 2024 15:56:54 GMT
Etag: "264f5757014d2dn3ij3ij2fc90cd7b"
Server: cloudflare
Vary: Origin, Accept-Encoding

Notice what is missing; the key points are:

Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag

The first one is for cross-origin, and the second one is needed for resumable uploads.

Solution#

First, configure the CORS rules in the Backblaze backend.
2024-06-19T16:57:09.png

Then you will find that it doesn't help much, as the Backblaze backend page is extremely simple, and you cannot directly modify the response headers in the web backend (this is for the request headers when reading files; you cannot modify the upload headers).
So we need to modify it in the B2 CLI.

First, go to Application Keys to create a new login key (either the Master Application Key or Application Key should work; if using Application Key, set the permissions yourself).
Then download B2 CLI.

If you are a Linux user, you can run the following command to download B2 CLI

# Download the latest binary
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
# Grant executable permissions
chmod +x ./b2-linux

Execute b2 account authorize to log in, and fill in keyID and applicationKey as prompted.
When you see output similar to the following, it means you have logged in successfully.

$ ./b2-linux account authorize
Backblaze application key ID: <keyID>
Backblaze application key: 
{
    "accountAuthToken": "<Token>",
    "accountFilePath": "/home/bakaArch/.config/b2/account_info",
    "accountId": "<accountID>",
    "allowed": {
        "bucketId": null,
        "bucketName": null,
        "capabilities": [
            "bypassGovernance",
            "deleteBuckets",
            "deleteFiles",
            "deleteKeys",
            "listAllBucketNames",
            "listBuckets",
            "listFiles",
            "listKeys",
            "readBucketEncryption",
            "readBucketNotifications",
            "readBucketReplications",
            "readBucketRetentions",
            "readBuckets",
            "readFileLegalHolds",
            "readFileRetentions",
            "readFiles",
            "shareFiles",
            "writeBucketEncryption",
            "writeBucketNotifications",
            "writeBucketReplications",
            "writeBucketRetentions",
            "writeBuckets",
            "writeFileLegalHolds",
            "writeFileRetentions",
            "writeFiles",
            "writeKeys"
        ],
        "namePrefix": null
    },
    "apiUrl": "https://api001.backblazeb2.com",
    "applicationKey": "<applicationKey>",
    "applicationKeyId": "<applicationKeyId>",
    "downloadUrl": "https://f001.backblazeb2.com",
    "isMasterKey": true,
    "s3endpoint": "https://s3.us-east-001.backblazeb2.com"
}

First, execute b2 bucket get <bucketName> to list the bucket details.

{
    "accountId": "<accountID>",
    "bucketId": "<bucketID>",
    "bucketInfo": {},
    "bucketName": "<bucketName>",
    "bucketType": "allPrivate",
    "corsRules": [
        {
            "allowedHeaders": [
                "authorization",
                "range"
            ],
            "allowedOperations": [
                "b2_download_file_by_id",
                "b2_download_file_by_name"
            ],
            "allowedOrigins": [
                "*"
            ],
            "corsRuleName": "downloadFromAnyOrigin",
            "exposeHeaders": null,
            "maxAgeSeconds": 3600
        },
        {
            "allowedHeaders": [
                "authorization",
                "range"
            ],
            "allowedOperations": [
                "s3_head",
                "s3_get"
            ],
            "allowedOrigins": [
                "*"
            ],
            "corsRuleName": "s3DownloadFromAnyOrigin",
            "exposeHeaders": null,
            "maxAgeSeconds": 3600
        }
    ],
    "defaultRetention": {
        "mode": null
    },
    "defaultServerSideEncryption": {
        "mode": "none"
    },
    "isFileLockEnabled": false,
    "lifecycleRules": [],
    "options": [
        "s3"
    ],
    "replication": {
        "asReplicationDestination": null,
        "asReplicationSource": null
    },
    "revision": 7
}

Note here corsRules, you can see that the allowedOperations only includes s3_head and s3_get methods (if you haven't configured cross-origin on the web side, you obviously won't see these two).
To operate files normally in Cloudreve, we also need to add s3_put, s3_post, and s3_delete methods.
Additionally, to allow B2 to return ETag for normal chunk uploads in the S3 compatible API, we need to modify the corsRules by adding ETag to exposeHeaders and content-type to allowedHeaders.
After modification, it should look like this:

"corsRules": [
    {
        "allowedHeaders": [
            "authorization",
            "range",
            "content-type"
        ],
        "allowedOperations": [
            "s3_head",
            "s3_get",
            "s3_put",
            "s3_post",
            "s3_delete"
        ],
        "allowedOrigins": [
            "*"
        ],
        "corsRuleName": "s3DownloadFromAnyOriginWithUpload",
        "exposeHeaders": ["ETag"],
        "maxAgeSeconds": 3600
    }
]

Since uploading files through Cloudreve only requires the S3 compatible API, I directly removed the B2 parts.

If you want better security, you can replace the asterisk in allowedOrigins with your Cloudreve domain name.

After modifying, use the command b2 bucket update <bucketName> --cors-rules 'configuration json' to update the configuration.
After updating, it will output the complete configuration again; check if it is correct.

$ ./b2-linux bucket update <bucketName> --cors-rules '[
    {
        "allowedHeaders": [
            "authorization",
            "range",
            "content-type"
        ],
        "allowedOperations": [
            "s3_head",
            "s3_get",
            "s3_put",
            "s3_post",
            "s3_delete"
        ],
        "allowedOrigins": [
            "*"
        ],
        "corsRuleName": "s3DownloadFromAnyOriginWithUpload",
        "exposeHeaders": ["ETag"],
        "maxAgeSeconds": 3600
    }
]'

{
    "accountId": "<accountID>",
    "bucketId": "<bucketID>",
    "bucketInfo": {},
    "bucketName": "<bucketName>",
    "bucketType": "allPrivate",
    "corsRules": [
        {
            "allowedHeaders": [
                "authorization",
                "range",
                "content-type"
            ],
            "allowedOperations": [
                "s3_head",
                "s3_put",
                "s3_delete",
                "s3_post",
                "s3_get"
            ],
            "allowedOrigins": [
                "*"
            ],
            "corsRuleName": "s3DownloadFromAnyOriginWithUpload",
            "exposeHeaders": [
                "etag"
            ],
            "maxAgeSeconds": 3600
        }
    ],
    "defaultRetention": {
        "mode": null
    },
    "defaultServerSideEncryption": {
        "mode": "none"
    },
    "isFileLockEnabled": false,
    "lifecycleRules": [],
    "options": [
        "s3"
    ],
    "replication": {
        "asReplicationDestination": null,
        "asReplicationSource": null
    },
    "revision": 9
}

At this point, there should be no issues.
Try uploading the file again, and the problem is resolved.
2024-06-19T17:43:57.png

This article was synchronized and updated to xLog by Mix Space
The original link is https://blog.baka.plus/posts/tech/Add-Backblaze-B2-support-to-Cloudreve


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.