笨蛋ovo

笨蛋ovo

Cloudreve に Backblaze B2 サポートを追加

image.png

現在最新の設定チュートリアルは Cloudreve 公式ドキュメント に同期されています
より簡略なバージョンが必要な場合は、公式ドキュメントを直接参照してください
公式ドキュメントも私が書いたものです

問題分析#

まず Cloudreve 公式ドキュメント に従って設定を行います。その後、アップロード時にエラーが発生することが多いです (当たり前ですが、エラーが出なければこの記事を書くこともないでしょう)

F12 を開いてリクエストを確認すると、コンソールにクロスオリジンエラーが表示されます。

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.

次にレスポンスヘッダーを確認します。

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

明らかに、クロスオリジンヘッダーが欠けています。

ここで 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

何が欠けているか分かりますか?重要なのは

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

上記はクロスオリジン、下は断点続行に必要なものです。

解決策#

まず、Backblaze の管理画面で CORS ルールを設定します。
2024-06-19T16:57:09.png

その後、何も効果がないことに気づくでしょう。Backblaze の非常にシンプルな管理画面では、Web 管理画面でレスポンスヘッダーを直接変更することはできません(ここで変更するのはファイルのリクエストヘッダーで、アップロードのものは変更できません)。
したがって、B2 CLIで変更を行う必要があります。

まず、Application Keysで新しいログインキーを作成します(ここでは Master Application Key または Application Key のどちらでも構いません。Application Key の場合は自分で権限を設定してください)。
次に、B2 CLIをダウンロードします。

Linux ユーザーの場合、以下のコマンドを実行して B2 CLI をダウンロードできます。

# 最新のバイナリをダウンロード
wget https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
# 実行権限を付与
chmod +x ./b2-linux

b2 account authorizeを実行してアカウントにログインし、プロンプトに従ってkeyIDapplicationKeyを入力します。
以下のような出力が表示されれば、ログイン成功です。

$ ./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"
}

まず、b2 bucket get <bucketName>を実行してストレージバケットの詳細をリストします。

{
    "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
}

ここで注意すべきはcorsRulesです。ここではallowedOperationss3_heads3_getメソッドのみであることがわかります(Web 側でクロスオリジンを設定していない場合、これらは見えないでしょう)。
Cloudreve でファイルを正常に操作するためには、s3_puts3_posts3_deleteメソッドを追加する必要があります。
また、S3 互換 API で正常に分割アップロードを行うために、B2 がETagを返すことを許可する必要があります。
前にコピーしたストレージバケットの詳細の中で、corsRulesallowedOperationsを変更し、exposeHeadersETagを追加し、allowedHeaderscontent-typeを追加します。
変更後は次のようになります。

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

Cloudreve を通じてファイルをアップロードする際には S3 互換 API のみを使用するため、B2 の部分はそのまま削除しました。

より良いセキュリティを希望する場合は、allowedOriginsのアスタリスクを Cloudreve のドメイン名に変更してください。

変更後、b2 bucket update <bucketName> --cors-rules '設定json'コマンドを使用して設定を更新します。
更新後、完全な設定が再度出力されるので、正しいかどうかを確認します。

$ ./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
}

これで問題は解決されるはずです。
再度ファイルをアップロードしてみて、問題が解決されたか確認してください。
2024-06-19T17:43:57.png

この記事は Mix Space によって xLog に同期更新されました
元のリンクは https://blog.baka.plus/posts/tech/Add-Backblaze-B2-support-to-Cloudreve


読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。