阿里云 OSS:中国大陆 + 备案全套
这条路线代价最大:要自己准备域名、完成 ICP 备案(通常 1–20 个工作日),再给域名配一张 HTTPS 证书;都到位后,剩下的控制台步骤大约 10 分钟。
本文是孤云的官方引导。控制台若显示英文或繁体,按按钮的同义词对照操作即可。
分步操作
-
第 1 步
注册并完成实名验证
- 没有账号就先注册,并按控制台提示完成实名验证;已有账号可跳过。
- 两个入口,账号不通用:国际站 www.alibabacloud.com(英文界面为主、国际信用卡或 PayPal);中国站 www.aliyun.com(简体中文、要实名验证、支付宝或微信支付一类)。注册后就用同一个站点的控制台做完下面的步骤。
-
第 2 步
开通 OSS
- 在控制台搜索「对象存储 OSS」,进入产品页点「立即开通」。
- 必须勾选协议再确认;开通本身不收费。
-
第 3 步
准备域名并完成备案
- 域名在境外注册商(GoDaddy、Namecheap 等)要先转入境内注册商,才能提交备案。
- OSS 不提供备案服务码:先买一台符合条件的内地服务器(ECS 或轻量应用服务器,包年包月且 ≥3 个月、带公网带宽),用它领服务码再提交;审核通常 1–20 个工作日。
-
第 4 步
创建存储桶
- 在「Bucket 列表」点「创建 Bucket」,填桶名(全球唯一,例如
your-bucket-name)并选一个内地地域。 - 读写权限选「私有」,「阻止公共访问」保持开启。
- 在「Bucket 列表」点「创建 Bucket」,填桶名(全球唯一,例如
-
第 5 步
绑定自定义域名、证书与 CNAME
- 打开桶的「域名管理」→「绑定域名」,填你的域名,再在「证书托管」里选一张 HTTPS 证书。
- 顺序:先在 OSS 里添加域名并让它自动添加解析;CNAME 要直连 OSS、不要开 CDN —— 三个实测要点见页尾「其他情况」。
-
第 6 步
创建 RAM 子用户并取密钥
- 在「访问控制 RAM」→「用户」→「创建用户」,勾选「OpenAPI 调用访问」,不要勾选控制台登录。
- AccessKey ID 与 Secret 只显示一次,立刻复制保存;不要用主账号密钥。
-
第 7 步
把最小权限策略挂给这个子用户
- 在「权限管理 → 权限策略」新建自定义策略,切到脚本(JSON)编辑,粘贴下面的策略并把
your-bucket-name换成真实桶名。 - 回到用户页面,把这条策略授权给刚才的子用户。
- 在「权限管理 → 权限策略」新建自定义策略,切到脚本(JSON)编辑,粘贴下面的策略并把
-
第 8 步
回孤云填值并测试连接
- 在孤云「添加存储」里选「阿里云 OSS」,选好地点,填名称、桶名与密钥,HTTPS Endpoint 填你的域名(例如
https://oss.example.com)——应用会按自定义域名访问、不会在主机名前加桶名——再点「测试连接并保存」。
- 在孤云「添加存储」里选「阿里云 OSS」,选好地点,填名称、桶名与密钥,HTTPS Endpoint 填你的域名(例如
最小权限策略(必做)
在 RAM 里新建自定义策略、切到脚本编辑,粘贴这段 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 开通时间,不是建桶时间;老账号后来新建的桶不受限。
绑定自己的域名:三个实测要点
- 域名必须 CNAME 直连 OSS。 同一个桶上如果已经有一个走阿里云 CDN 的域名(CNAME 指向
*.w.kunlunaq.com、证书配在 CDN 控制台),那个域名不能当端点 —— 实测拿它连孤云会失败。要给孤云当端点的域名必须 CNAME 直连 OSS,并且不要开启 CDN。在桶的「域名管理」里一眼能分辨:已开 CDN 的那一行会显示「阿里云 CDN 加速:已配置」;证书也要配在对应那一侧。 - 顺序:先在 OSS 里添加域名,让它自动加解析。 反过来(先在 DNS 手工加好 CNAME、再回 OSS 点「自动添加解析」)会因「解析记录已存在」报错,看起来像失败。如果确实要手工加,加完就不要再点自动添加。
- 证书放在 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 与桶。
怎么知道这条链路成了
- 在 OSS 里给某个文件「复制文件 URL」(域名选自定义域名),浏览器打开看有没有 HTTPS 锁标。
- 回到孤云:添加存储 → 阿里云 OSS → 地点选北京 → 桶名 → HTTPS Endpoint 填
https://guyun.godar.cn→ 密钥 → 点「测试连接并保存」,成功即通。 - 这条路径 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 模板
{
"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/。
两边界面略有差别,按同义按钮操作即可。
官方来源
- 地域与 Endpoint 总表 (在新窗口打开)
- PublicEndpointForbidden 错误说明 (在新窗口打开)
抄下这三个值
它们要填进孤云「添加存储」页对应的格子: 地点:在 App 里选「北京 / 中国香港 / 广州 / us-west-004 …」对应的那一项 —— 选好地点,地域与 HTTPS Endpoint 会自动填好。
| 抄下这个值 | 填进孤云的哪一格 |
|---|---|
| 桶名 控制台里的桶名,全球唯一,例如 your-bucket-name。 | 桶名称 |
| 端点 你的域名,例如 https://oss.example.com。 | Endpoint |
| 密钥 刚才那个 RAM 子用户的 AccessKey ID 与 Secret。 | AccessKey ID 与 Secret |
怎么知道成了
- 孤云返回成功并列出桶的根目录;空桶返回空列表也算成功。
- 再上传、下载、删除一个小文件,确认这个域名既能读也能写。
- 连接报错时,到常见错误对照排查。
回到孤云,点「测试连接并保存」。