Skip to content

AWS S3 存储桶创建与配置

租户管理员可以把自有的 Amazon S3 存储桶配置为对象存储。保存后在 OSS 页面选择“手动选择”,并选中该配置,后续上传的图片、视频、音频、PDF 等素材将直接保存到该存储桶,相关存储空间、请求次数和下载流量费用由对应的 AWS 账号承担。

推荐方案

使用私有存储桶、保持“阻止所有公共访问”开启,并在管理端将“访问域名”留空。软件会使用临时签名 URL 上传和访问对象,不需要公开存储桶。

准备工作

开始前需要准备:

  • 一个可用的 AWS 账号。
  • 一个尚未被占用的全局唯一存储桶名称。
  • 存储桶所在区域的 Region 代码,例如 ap-southeast-1
  • Web 管理端的完整来源地址,例如 https://admin.example.com,用于配置 CORS。
  • 云端租户管理员账号,或 APP 内置服务中通过 LAN 登录的租户管理员账号。

建议根据主要用户所在区域选择 Region。存储桶创建后不能更改 Region;跨区域访问还可能增加延迟和流量费用。

创建 S3 存储桶

  1. 登录 AWS 管理控制台
  2. 打开 Amazon S3
  3. 进入 Buckets,选择 Create bucket
  4. Bucket type 选择 General purpose
  5. 输入 Bucket name。名称必须全局唯一,建议只使用小写字母、数字和连字符,例如 tenant-media-001
  6. 选择 AWS Region,并记录其 Region 代码。
  7. Object Ownership 保持 Bucket owner enforced,即 ACLs disabled。
  8. Block Public Access 保持四项全部启用。
  9. Bucket Versioning 初期建议保持 Disabled。
  10. Default encryption 选择 SSE-S3
  11. Object Lock 保持 Disabled。
  12. 选择 Create bucket

不建议为了素材访问而关闭公共访问限制。管理端可以通过预签名请求访问私有对象。

如果启用 Versioning,删除素材时旧版本仍可能保留并继续产生存储费用。确有版本恢复需求时,应同时配置非当前版本清理规则。

配置 Web 跨域访问

Android、iOS 和桌面客户端不需要 CORS。使用 Web 管理端上传时,需要为 Bucket 配置允许上传来源的 CORS 规则。

进入:

text
Bucket → Permissions → Cross-origin resource sharing (CORS)

填写以下 JSON,并把域名替换成实际 Web 管理端来源:

json
[
  {
    "AllowedHeaders": [
      "*"
    ],
    "AllowedMethods": [
      "GET",
      "PUT",
      "HEAD"
    ],
    "AllowedOrigins": [
      "https://admin.example.com"
    ],
    "ExposeHeaders": [
      "ETag"
    ],
    "MaxAgeSeconds": 3600
  }
]

AllowedOrigins 必须包含协议、域名和非默认端口,不包含路径。例如 https://admin.example.com,不要填写 https://admin.example.com/login

生产环境不建议使用 "*" 作为 AllowedOrigins。存在多个正式管理端域名时,可以将它们分别加入数组。

ETag 用于确认分片上传结果,必须通过 ExposeHeaders 暴露给浏览器。

创建专用 IAM 用户

不要使用 AWS Root 账号的 Access Key,也不要给存储用户授予整个 AWS 账号的管理权限。

  1. 打开 IAM
  2. 进入 Users,选择 Create user
  3. 输入专用用户名,例如 tenant-media-storage
  4. 不启用 AWS Management Console access。
  5. 创建用户后,打开该用户的 Permissions
  6. 选择 Add permissions,创建 Inline policy。
  7. 切换到 JSON 编辑器,填写下面的最小权限策略。

YOUR_BUCKET_NAME 替换为实际 Bucket 名称:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "TenantObjectStorage",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload"
      ],
      "Resource": [
        "arn:aws:s3:::YOUR_BUCKET_NAME/*"
      ]
    }
  ]
}

这些权限分别用于下载及对象检查、直传与分片上传、用户删除对象和取消未完成的分片上传。租户自有存储不参与平台定时扫描和清理,因此无需为该清理任务授予 s3:ListBucket。当前软件不需要 AmazonS3FullAccess

如果 Bucket 使用自定义 SSE-KMS 密钥,还需要配置对应 KMS 权限。初次接入建议使用 SSE-S3,减少额外权限和费用。

创建 Access Key

  1. 打开刚创建的 IAM 用户。
  2. 进入 Security credentials
  3. 在 Access keys 区域选择 Create access key
  4. 用途选择 Application running outside AWS;控制台版本不同也可能显示为 Other
  5. 创建并妥善保存 Access Key ID 和 Secret Access Key。

Secret Access Key 通常只完整显示一次。不要通过聊天、邮件、工单或截图发送凭据。

配置到租户对象存储

使用云端租户管理员账号登录,或通过已认证的 LAN 租户管理员连接进入 APP 内置服务,然后打开:

text
账号设置 → 配置管理 → 对象存储服务(OSS)→ 新增对象存储

建议按下表填写:

字段AWS S3 填写方式
名称自定义名称,例如“AWS S3 生产存储”。
描述选填,可记录用途、负责人和 AWS 账号。不要记录 Secret Key。
服务商选择“S3 兼容存储”。
Endpoint标准 AWS S3 留空。只有接入兼容 S3 的第三方服务时才填写。
区域(Region)填写 Region 代码,例如 ap-southeast-1。不能填写“新加坡”等区域名称。
Bucket填写实际 Bucket 名称,区分连字符等字符。
Access Key填写 IAM 用户的 Access Key ID。
Secret Key填写对应的 Secret Access Key。
访问域名私有 AWS S3 Bucket 留空,以便软件生成签名下载 URL。
使用路径形式访问标准 AWS S3 关闭。

访问域名

不要把普通的私有 Bucket URL 填入“访问域名”。只要该字段不为空,软件就会把它当作可以直接访问的公开或 CDN 域名,不再为下载地址生成 S3 签名,私有对象会因此返回 403。

只有已经配置公开 CDN 或自定义域名,并确认该域名能够直接读取对象时,才填写“访问域名”。

测试、保存并选择使用

  1. 填完表单后先选择 测试连接
  2. 后台会上传一个很小的临时对象、读取对象信息并尝试删除。
  3. 测试成功后选择 保存。测试连接不会自动保存表单。
  4. 返回对象存储列表,将选择模式改为 手动选择
  5. 选中刚保存的 AWS S3 配置并保存。

新建配置不会自动被使用。手动选中后,只影响之后开始的新上传:

  • 已有素材继续使用原对象存储。
  • 已经开始的上传继续使用开始时选定的配置。
  • 系统不会自动搬迁 Bucket 之间的对象。

配置分片上传清理规则

为了避免异常中断的分片长期占用空间,建议进入:

text
Bucket → Management → Create lifecycle rule

创建一条对整个 Bucket 生效的规则:

  • Lifecycle rule action:删除未完成的分片上传。
  • Days after initiation:建议 7 天。

该规则只清理没有完成的分片,不会删除已经成功完成的对象。

上线验证

建议在正式使用前完成以下验证:

  1. 上传一个小图片,确认直传成功并能预览。
  2. 上传一个较大文件,确认分片上传成功。
  3. 在 S3 的 Objects 页面确认已经生成对象。
  4. 打开和播放素材,确认签名下载地址可用。
  5. 删除一个专门用于测试且没有被节目引用的素材,确认对象可以被清理。
  6. Web 管理端和至少一个原生客户端分别测试一次。

对象 Key 通常采用以下形式:

text
<uuid>.<ext>

对象 Key 是扁平文件名,不含租户或 Profile 目录;无需在 S3 控制台提前创建目录。

常见问题

测试连接返回 AccessDenied

检查 Access Key、Secret Key、Bucket 名称和 IAM policy,并确认 AWS Organizations SCP、Bucket policy 或权限边界没有额外拒绝请求。

返回 PermanentRedirect 或 SignatureDoesNotMatch

优先检查 Region 是否与 Bucket 实际区域完全一致。标准 AWS S3 的 Endpoint 应留空,使用路径形式访问应关闭。

原生客户端可以上传,但 Web 上传失败

通常是 CORS 配置问题。检查 AllowedOrigins 是否与浏览器地址栏中的协议、域名和端口完全一致,同时确认允许 PUT、所有签名请求头,并暴露 ETag

上传成功,但打开素材返回 403

私有 Bucket 的“访问域名”应留空。填写了 Bucket URL 或不能匿名读取的 CDN 域名时,请清空该字段后重新测试。

分片上传取消失败

确认 IAM policy 包含 s3:AbortMultipartUpload,并配置自动清理未完成分片的生命周期规则。

更新凭据时无法保存

Access Key 和 Secret Key 必须同时填写或同时留空。编辑已有配置时两项都留空表示继续使用原凭据。

安全与费用建议

  • 保持 Block Public Access 全部开启。
  • 使用独立 IAM 用户和最小 Bucket 权限,定期轮换 Access Key。
  • 不要使用 Root Access Key,也不要配置 AmazonS3FullAccess
  • 使用 AWS Budgets、Bucket 标签或成本分配标签跟踪费用。
  • 没有版本恢复需求时不要启用 Versioning;已经启用时应清理非当前版本。
  • 配置生命周期规则自动终止未完成的分片上传。
  • 删除或停用 IAM 凭据前,先确认没有对象存储配置仍在使用它。

AWS 参考文档