跳到主要內容
孤雲

阿里雲 OSS:中國大陸 + 備案全套

這條路線代價最大:要自己準備網域、完成 ICP 備案(通常 1–20 個工作日),再給網域配一張 HTTPS 憑證;都到位後,剩下的主控台步驟大約 10 分鐘。

本文是孤雲的官方引導。主控台若顯示簡體,按鈕名稱請按同義對照。

分步操作

  1. 第 1 步

    註冊並完成實名認證

    • 沒有帳號就先註冊,並按主控台提示完成實名認證;已有帳號可跳過。
    • 兩個入口,帳號不通用:國際站 www.alibabacloud.com(以英文介面為主、國際信用卡或 PayPal);中國站 www.aliyun.com(簡體中文、要實名認證、支付寶或微信支付一類)。註冊後就用同一個站點的主控台做完下面的步驟。
  2. 第 2 步

    開通 OSS

    • 在主控台搜尋「物件儲存 OSS」,進入產品頁點「立即開通」。
    • 必須勾選協議再確認;開通本身不收費。
  3. 第 3 步

    準備網域並完成備案

    • 網域在境外註冊商(GoDaddy、Namecheap 等)要先轉入境內註冊商,才能提交備案。
    • OSS 不提供備案服務碼:先買一台符合條件的內地伺服器(ECS 或輕量應用伺服器,包年包月且 ≥3 個月、帶公網頻寬),用它領服務碼再提交;審核通常 1–20 個工作日。
  4. 第 4 步

    建立儲存桶

    • 在「Bucket 列表」點「建立 Bucket」,填桶名(全域唯一,例如 your-bucket-name)並選一個內地地域。
    • 讀寫權限選「私有」,「阻止公共存取」保持開啟。
  5. 第 5 步

    綁定自訂網域、憑證與 CNAME

    • 開啟桶的「網域管理」→「綁定網域」,填你的網域,再在「憑證託管」裡選一張 HTTPS 憑證。
    • 順序:先在 OSS 裡加入網域並讓它自動加入解析;CNAME 要直連 OSS、不要開 CDN —— 三個實測要點見頁尾「其他情況」。
  6. 第 6 步

    建立 RAM 子使用者並取得金鑰

    • 在「存取控制 RAM」→「使用者」→「建立使用者」,勾選「OpenAPI 呼叫存取」,不要勾選主控台登入。
    • AccessKey ID 與 Secret 只顯示一次,立刻複製保存;不要用主帳號金鑰。
  7. 第 7 步

    把最小權限策略掛給這個子使用者

    • 在「權限管理 → 權限策略」新建自訂策略,切到腳本(JSON)編輯,貼上下面的策略並把 your-bucket-name 換成真實桶名。
    • 回到使用者頁面,把這條策略授權給剛才的子使用者。
  8. 第 8 步

    回孤雲填值並測試連線

    • 在孤雲「新增儲存」裡選「阿里雲 OSS」,選好地點,填名稱、桶名與金鑰,HTTPS Endpoint 填你的網域(例如 https://oss.example.com)——應用會按自訂網域存取、不會在主機名稱前加桶名——再點「測試連線並儲存」。

最小權限策略(必做)

在 RAM 裡新建自訂策略、切到腳本編輯,貼上這段 JSON。

json
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["oss:ListObjects", "oss:GetBucketLocation", "oss:ListMultipartUploads"],
      "Resource": ["acs:oss:*:*:your-bucket-name"]
    },
    {
      "Effect": "Allow",
      "Action": ["oss:GetObject", "oss:PutObject", "oss:DeleteObject", "oss:AbortMultipartUpload", "oss:ListParts", "oss:RestoreObject"],
      "Resource": ["acs:oss:*:*:your-bucket-name/*"]
    }
  ]
}

把 your-bucket-name 換成真實桶名。 也不要把資源範圍縮小到某個目錄:孤雲要在 .guyun/ 前綴下寫入垃圾桶清單與裝置記錄。 分段上傳(初始化 / 上傳分段 / 合併)都屬於 oss:PutObject,不需要額外權限;oss:RestoreObject 只對這個桶裡既有的物件發起解凍,不發就不會產生任何費用。

其他情況(用不到可以跳過)

為什麼必須自訂網域

阿里雲自 2025-03-20 起,新開通 OSS 的帳號用預設外網網域存取內地桶的資料類 API(上傳、下載)會被拒絕,錯誤碼 PublicEndpointForbidden。

它限制的是網域,不是權限:桶設成私有、不對外提供任何連結,甚至改用 S3 相容網域,都一樣受限。

判斷依據是這個帳號的 OSS 開通時間,不是建立桶的時間;老帳號後來新建的桶不受限。

綁定自訂網域:三個實測要點

  1. 網域必須 CNAME 直連 OSS。 同一個桶上如果已經有一個走阿里雲 CDN 的網域(CNAME 指向 *.w.kunlunaq.com、憑證配在 CDN 主控台),那個網域不能當端點 —— 實測拿它連孤雲會失敗。要給孤雲當端點的網域必須 CNAME 直連 OSS,並且不要開啟 CDN。在桶的「網域管理」裡一眼能分辨:已開 CDN 的那一行會顯示「阿里雲 CDN 加速:已設定」;憑證也要配在對應那一側。
  2. 順序:先在 OSS 裡加入網域,讓它自動加解析。 反過來(先在 DNS 手動加好 CNAME、再回 OSS 點「自動加入解析」)會因「解析記錄已存在」報錯,看起來像失敗。如果確實要手動加,加完就不要再點自動加入。
  3. 憑證放在 OSS 的「憑證託管」裡。 位置:OSS 主控台 → 該 Bucket → Bucket 設定 → 網域管理 → 目標網域 → 「憑證託管」→ 選擇憑證 → 上傳。憑證要先存在於數位憑證管理服務(CAS):在阿里雲買的直接在清單裡選,第三方憑證要先在 CAS 裡上傳「憑證公鑰 + 私密金鑰」,否則這一步的下拉裡選不到;憑證的綁定網域要包含你填的這個網域。

兩個容易踩的細節

OSS 給出的 CNAME 目標形如 <bucket>.<region>.taihangtop.cn(實測 airdiode-upload.cn-beijing.taihangtop.cn),不是常見的 <bucket>.oss-<region>.aliyuncs.com —— 以主控台目前顯示的為準,兩種寫法都指向 OSS。

一個網域同一時間只能綁一個桶,同一個主機名稱也只能有一條 CNAME:別動已有的 CDN 網域,另起一個子網域即可(例如 guyun.godar.cn)。憑證更新在同一位置換新憑證,不影響已綁定的 CNAME 與桶。

怎麼知道這條鏈路成了

  1. 在 OSS 裡給某個檔案「複製檔案 URL」(網域選自訂網域),瀏覽器開啟看有沒有 HTTPS 鎖標。
  2. 回到孤雲:新增儲存 → 阿里雲 OSS → 地點選北京 → 桶名 → HTTPS Endpoint 填 https://guyun.godar.cn → 金鑰 → 點「測試連線並儲存」,成功即通。
  3. 這條路徑 2026-09-28 已實測跑通(桶 airdiode-upload + 端點 https://guyun.godar.cn,憑證在 OSS 憑證託管、未開 CDN)。

備案服務碼

  • OSS 不在贈送備案服務碼的產品名單裡,不能單獨申請。
  • 要給 OSS 用的網域備案,得先買一台符合條件的內地伺服器:ECS 或輕量應用伺服器,包年包月且時長 ≥3 個月、已購公網頻寬;免費試用與按量付費的 ECS 都不符合。
  • 備案審核通常 1–20 個工作日。
  • 主網域已備案時,給 OSS 單獨用一個子網域(例如 oss.example.com)即可,子網域不用再備案;網域在境外註冊商時先轉入境內註冊商。

ROS 一鍵範本(選用捷徑)

讓資源編排(ROS)一次建好私有桶、只授權該桶的 RAM 使用者與 AccessKey。

  • 先複製下面的範本全文。
  • 在 ROS 建立頁選「指定範本 → 輸入範本」貼上。
  • 必須勾選「安全確認」,否則建立會被擋下。
  • 失敗時點資源棧的「事件」看原因,桶名被佔用最常見。

ROS 範本

json
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "为孤云创建:私有且阻止公共访问的 OSS Bucket、只授权该桶读写的 RAM 用户、以及该用户的 AccessKey。AccessKey ID 与 Secret 会出现在资源栈的「输出」里,复制回应用即可。",
    "en": "Creates, for Guyun: a private OSS bucket with public access blocked, a RAM user limited to that bucket, and an AccessKey for it. The AccessKey ID and secret appear in the stack outputs; copy them back into the app."
  },
  "Parameters": {
    "BucketName": {
      "Type": "String",
      "Label": {
        "zh-cn": "Bucket 名称",
        "en": "Bucket name"
      },
      "Description": {
        "zh-cn": "全局唯一。3–63 位,只能用小写字母、数字和短横线,首尾必须是字母或数字。例如 my-photos-2026。",
        "en": "Globally unique. 3–63 characters: lowercase letters, digits and hyphens, starting and ending with a letter or digit. For example my-photos-2026."
      },
      "AllowedPattern": "^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$",
      "MinLength": 3,
      "MaxLength": 63
    },
    "RamUserName": {
      "Type": "String",
      "Label": {
        "zh-cn": "RAM 用户名",
        "en": "RAM user name"
      },
      "Description": {
        "zh-cn": "给应用专用的子账号。如果账号下已经有同名用户,请改成别的名字再创建。",
        "en": "A dedicated sub-account for the app. If a user with this name already exists, pick another one."
      },
      "Default": "guyun-app",
      "AllowedPattern": "^[a-zA-Z0-9._-]{1,64}$",
      "MinLength": 1,
      "MaxLength": 64
    }
  },
  "Resources": {
    "Bucket": {
      "Type": "ALIYUN::OSS::Bucket",
      "Properties": {
        "BucketName": {
          "Ref": "BucketName"
        },
        "AccessControl": "private",
        "StorageClass": "Standard",
        "BlockPublicAccess": true
      }
    },
    "AppUser": {
      "Type": "ALIYUN::RAM::User",
      "Properties": {
        "UserName": {
          "Ref": "RamUserName"
        },
        "DisplayName": {
          "Fn::Sub": "孤云存储"
        },
        "Comments": {
          "Fn::Sub": "孤云专用存储用户;授权桶 ${BucketName} 的读写;随资源栈删除。"
        }
      }
    },
    "BucketPolicy": {
      "Type": "ALIYUN::RAM::ManagedPolicy",
      "DependsOn": "AppUser",
      "Properties": {
        "PolicyName": {
          "Fn::Sub": "guyun-${BucketName}-rw"
        },
        "Description": {
          "Fn::Sub": "Guyun: read and write ${BucketName} only. No bucket-level administration."
        },
        "PolicyDocument": {
          "Version": "1",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "oss:ListObjects",
                "oss:GetBucketLocation",
                "oss:ListMultipartUploads"
              ],
              "Resource": [
                {
                  "Fn::Sub": "acs:oss:*:*:${BucketName}"
                }
              ]
            },
            {
              "Effect": "Allow",
              "Action": [
                "oss:GetObject",
                "oss:PutObject",
                "oss:DeleteObject",
                "oss:AbortMultipartUpload",
                "oss:ListParts",
                "oss:RestoreObject"
              ],
              "Resource": [
                {
                  "Fn::Sub": "acs:oss:*:*:${BucketName}/*"
                }
              ]
            }
          ]
        },
        "Users": [
          {
            "Fn::GetAtt": [
              "AppUser",
              "UserName"
            ]
          }
        ]
      }
    },
    "AccessKey": {
      "Type": "ALIYUN::RAM::AccessKey",
      "DependsOn": "AppUser",
      "Properties": {
        "UserName": {
          "Fn::GetAtt": [
            "AppUser",
            "UserName"
          ]
        }
      }
    }
  },
  "Outputs": {
    "BucketName": {
      "Label": {
        "zh-cn": "Bucket 名称",
        "en": "Bucket name"
      },
      "Description": {
        "zh-cn": "填到应用的「Bucket 名称」里。",
        "en": "Paste into the app's bucket name field."
      },
      "Value": {
        "Ref": "BucketName"
      }
    },
    "RegionId": {
      "Label": {
        "zh-cn": "地域",
        "en": "Region"
      },
      "Description": {
        "zh-cn": "资源栈所在地域,也就是 Bucket 的地域。",
        "en": "The stack's region, which is the bucket's region."
      },
      "Value": {
        "Ref": "ALIYUN::Region"
      }
    },
    "Endpoint": {
      "Label": {
        "zh-cn": "HTTPS Endpoint",
        "en": "HTTPS endpoint"
      },
      "Description": {
        "zh-cn": "走默认域名时填到应用的「HTTPS Endpoint」里;如果之后绑了自定义域名,Endpoint 要改成那个域名。",
        "en": "With the default endpoint, paste this into the app's HTTPS endpoint field. If you bind a custom domain later, the endpoint becomes that domain instead."
      },
      "Value": {
        "Fn::Sub": "https://oss-${ALIYUN::Region}.aliyuncs.com"
      }
    },
    "AccessKeyId": {
      "Label": {
        "zh-cn": "AccessKey ID",
        "en": "AccessKey ID"
      },
      "Description": {
        "zh-cn": "复制后填到应用的「AccessKey ID」里。",
        "en": "Copy into the app's AccessKey ID field."
      },
      "Value": {
        "Fn::GetAtt": [
          "AccessKey",
          "AccessKeyId"
        ]
      }
    },
    "AccessKeySecret": {
      "Label": {
        "zh-cn": "AccessKey Secret",
        "en": "AccessKey secret"
      },
      "Description": {
        "zh-cn": "只在这里显示,复制后填进应用的 Keychain;不要粘贴到聊天、文档或代码里。",
        "en": "Shown here only. Copy it into the app's Keychain; never paste it into a chat, document or repository."
      },
      "Value": {
        "Fn::GetAtt": [
          "AccessKey",
          "AccessKeySecret"
        ]
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "ParameterGroups": [
        {
          "Parameters": [
            "BucketName"
          ],
          "Label": {
            "default": "OSS"
          }
        },
        {
          "Parameters": [
            "RamUserName"
          ],
          "Label": {
            "default": "RAM"
          }
        }
      ],
      "Outputs": [
        "BucketName",
        "RegionId",
        "Endpoint",
        "AccessKeyId",
        "AccessKeySecret"
      ]
    }
  }
}

範本建立的資源與權限和手動路線完全相同。

主控台網址

阿里雲國際站 https://www.alibabacloud.com/;中國站 https://www.aliyun.com/。

兩邊介面略有差別,按同義按鈕操作即可。

抄下這三個值

它們要填進孤雲「新增儲存」頁對應的格子: 地點:在 App 裡選「北京 / 中國香港 / 廣州 / us-west-004 …」對應的那一項 —— 選好地點,地域與 HTTPS Endpoint 會自動填好。

抄下這個值填進孤雲的哪一格
桶名
主控台裡的桶名,全域唯一,例如 your-bucket-name。
桶名稱
端點
你的網域,例如 https://oss.example.com。
Endpoint
金鑰
剛才那個 RAM 子使用者的 AccessKey ID 與 Secret。
AccessKey ID 與 Secret

怎麼知道成了

  • 孤雲回報成功並列出桶的根目錄;空桶回傳空清單也算成功。
  • 再上傳、下載、刪除一個小檔案,確認這個網域既能讀也能寫。
  • 連線報錯時,到常見錯誤對照排查。

回到孤雲,點「測試連線並儲存」。