# Zeabur 2026 年十月安全事件（初步报告）

> 攻击者入侵了共享集群与 GCP 专用服务器，并读取了存放在 Zeabur 平台数据库中的环境变量。本文说明发生了什么、哪些数据受影响、我们做了什么，以及您需要做什么。

**本文时间均为协调世界时（UTC）。调查仍在进行，本文会随进展更新。**

## 摘要

- **发生了什么：** 2026 年 10 月 14 日至 15 日，攻击者使用泄露的 Zeabur 内部凭证，入侵了共享集群、部分专用服务器与 Zeabur 内部系统，最后读取了平台数据库。
- **已关闭的入口：** 攻击者使用的集群管理令牌、AWS 与 GCP 密钥、内部网络节点都已撤销或移除，管理接口与服务器的公网 SSH 已封禁。所有用户都已被登出，平台访问令牌已全部撤销。目前记录中，攻击者最后的活动是 10 月 15 日 21:05。
- **影响谁：** 主要是**共享集群上的服务**与 **GCP 专用服务器**。存放在 Zeabur 平台数据库中的环境变量也遭读取；八月后已按指引把环境变量迁移到自己专用服务器的项目，这些变量不在平台数据库遭读取的范围内。
- **您需要做什么：** 已泄露的数据仍可能被利用。请更换存放在 Zeabur 的所有密码与密钥，即使八月事件后已经换过。步骤见[您需要做什么](#user-actions)。
- **根本原因：** 这起事件的根本原因在 Zeabur：长期有效的管理凭证以明文保存，并可从公网使用。详见[为什么会发生](#root-causes)。
- **与八月事件的关系：** 八月的轮换没有覆盖这次被使用的凭证；已按八月指引迁移环境变量的项目则避开了平台数据库的泄露。详见[与八月事件的关系](#august-relation)。

**本文用语：**“已确认”表示有日志直接记录；“研判”表示时间与内容吻合，但缺少直接记录；“无法确认”表示没有记录可查，我们一律按已泄露处理；“推测”表示只有间接证据支持的可能解释，集中列在[尚未证实的推测](#hypotheses)。

<div id="what-happened" />

## 发生了什么

攻击者走了两条路径，最后在 Zeabur 的内部网络会合。

**路径 A：共享集群与 AWS**

1. 10 月 14 日 01:36 起，攻击者使用 Zeabur 内部的 AWS 密钥，01:40 起使用共享集群的管理令牌。这些凭证以明文保存在 Zeabur 的私有配置仓库中。攻击者如何取得它们，目前**无法确认**；我们推测与八月事件泄露的 GitHub App 私钥有关，见[尚未证实的推测](#hypotheses)。
2. 共享集群的管理接口当时对公网开放，管理令牌也没有有效期。攻击者因此能从外部访问 9 个区域的共享集群。
3. 01:51 起，攻击者读取了部分系统机密。12:39 起，范围扩大到所有服务的配置与机密，包括环境变量。有完整读取记录的区域已确认读到内容；其余区域缺少记录，我们一律按已泄露处理。
4. 13:40 起，攻击者在用户数据库的容器内执行读取命令。先是少数 new-api／one-api，15:41 起大量读取 n8n，16:50 起逐表读取部分 PostgreSQL，最后一条命令在 17:04。攻击者共在 865 个数据库服务中执行过命令，但并非每条命令都成功。
5. 攻击者使用集群中另一组权限过大的密钥，读取了一份旧集群的备份（**研判**）。备份中有一组可读取 Zeabur 机密管理服务的密钥。
6. 10 月 15 日 14:52 至 16:51，攻击者读取了约 53 条生产环境机密（**已确认**）。其中包括内部网络的管理凭证、平台数据库的账号，以及 GitHub App 私钥。

**路径 B：GCP 专用服务器**

1. 10 月 14 日 13:40 起，攻击者以 root 身份登录由 Zeabur 托管于 GCP 的专用服务器，共 101 台。
2. 这些服务器的初始化配置以明文保存 root 密码。攻击者持有一把能读取这些配置的旧 GCP 密钥。我们**研判**攻击者用这把密钥取得了密码。
3. 10 月 15 日 14:26 起，攻击者用旧 GCP 密钥修改服务器配置，加入自己的 SSH 密钥。15:05，攻击者又从机密管理服务取得一把生产环境的 GCP 密钥。我们在 17:17 停用旧密钥后，攻击者 17:28 改用这把密钥再次加入 SSH 密钥，我们在 17:31 也停用了它。10 月 14 日首次登录 GCP 服务器，早于 10 月 15 日首次已知的生产环境机密读取记录；不能把后者当作前者的起点。
4. 更早之前，9 月 1 日至 5 日已有不明来源以 root 密码登录同一批服务器，9 月 5 日当天约 98 台。是否为同一攻击者，目前**无法确认**。

**两条路径会合**

1. 10 月 15 日 15:30，攻击者在一台遭入侵的 GCP 服务器上，用路径 A 取得的内网管理凭证，让一个节点加入 Zeabur 内部网络。
2. 内部网络的规则允许这类节点连接平台数据库。16:10 至 16:47，攻击者以内部只读账号读取了平台数据库（**已确认**）。我们比对了内部网络两端的连接记录与数据库日志。这段期间的 29 个数据库连接都能对应到这个节点，连接中的登录与查询也能逐一追踪，共 8,903 条操作记录。3. 17:58，我们移除了这个节点。

<ConvergingChain
  title="事件路径"
  description="两条路径在内部网络会合。箭头旁是攻击者在每一步利用的凭证或漏洞。"
  lanes={[
    {
      label: '路径 A　共享集群与 AWS',
      steps: [
        {
          zone: '起点',
          title: '已持有 AWS 密钥与集群管理令牌',
          detail: '获取方式无法确认',
        },
        {
          via: '管理令牌没有有效期，管理接口对公网开放',
          zone: '9 个区域的共享集群',
          title: '所有服务的环境变量、865 个数据库容器',
        },
        {
          via: '研判：权限过大的密钥读取旧集群备份',
          zone: 'AWS',
          title: '机密管理服务的密钥',
        },
        {
          via: '已确认：读取生产环境机密',
          zone: 'Zeabur 机密管理服务',
          title: '约 53 条生产环境机密',
          detail: '包括内网管理凭证与数据库账号',
        },
      ],
    },
    {
      label: '路径 B　GCP 专用服务器',
      steps: [
        {
          zone: '起点',
          title: '一把旧的 GCP 服务账号密钥',
          detail: '泄露来源无法确认',
        },
        {
          via: '研判：读取初始化配置中的 root 密码',
          zone: 'GCP 专用服务器',
          title: '101 台服务器的 root 权限',
        },
      ],
    },
  ]}
  merge={{
    via: '在遭入侵的服务器上，用内网管理凭证加入节点',
    zone: 'Zeabur 内部网络',
    title: '一个带有生产环境权限的节点',
  }}
  after={[
    {
      via: '内网规则允许连接，再以内部只读账号登录',
      zone: 'Zeabur 平台数据库',
      title: '存放在 Zeabur 的环境变量、账号与项目数据',
    },
  ]}
  caption="图 1：这次攻击者在路径 B 入侵的服务器上，用路径 A 取得的内网凭证加入节点。但入侵客户服务器并不是加入内网的必要条件。"
/>

**事件期间轮换的部分凭证，后续仍遭未授权使用。** Zeabur 的集群每日备份会保存所有机密，而攻击者在 10 月 15 日 15:04 读取了备份的访问密钥。我们在 15:40 换上的新密钥，被 16:00 的备份收录；攻击者在 20:30 使用了它。我们在 18:51 删除备份的访问密钥，并在 21:47 再次轮换受影响的凭证。新密钥被备份收录、之后遭使用，这两点已确认；攻击者是否下载了这份备份属于研判。攻击者可能在 18:51 前就已取得备份，所以 20:30 的使用不代表 18:51 之后仍能下载。

<div id="what-information" />

## 涉及哪些数据

| 系统                             | 受影响的数据                                               | 范围                                        | 确定程度                 |
| -------------------------------- | ---------------------------------------------------------- | ------------------------------------------- | ------------------------ |
| 平台数据库                       | 存放在 Zeabur 的服务环境变量（名称与值）                   | 3,218,965 条                                | 已确认                   |
| 平台数据库                       | 账号（电子邮箱、用户名、手机号码等）、项目、环境与服务数据 | 账号 321,810 条                             | 已确认                   |
| 平台数据库                       | zSend API 密钥（明文）                                     | 566 个，已撤销                              | 已确认                   |
| 平台数据库                       | 平台访问令牌                                               | 11,536 条，仅有哈希值，无法还原；已全部撤销 | 已确认                   |
| 共享集群                         | 所有服务的环境变量与机密                                   | 9 个区域                                    | 部分已确认，其余无法确认 |
| 共享集群                         | 数据库内容                                                 | 865 个数据库服务                            | 研判（见下方说明）       |
| GCP 专用服务器                   | 服务器上的所有数据                                         | 101 台，92 位用户                           | 已确认登录               |
| Hetzner、DigitalOcean 专用服务器 | 服务器的管理权限                                           | 359 台与 48 台                              | 无法确认是否遭使用       |
| GitHub App                       | 访问用户授权的 GitHub 仓库                                 | 10/15 15:05 至 18:54                        | 未发现遭使用             |
| 用户数据库备份                   | 台北（tpe1）与香港（hkg1）区域的备份                       | 两个区域                                    | 无法确认是否遭下载       |

**平台数据库。** 10 月 15 日 16:10 至 16:47，攻击者读取了上表的数据。账号数据包含个人主页上的信息，例如电子邮箱、用户名与手机号码。攻击者也搜索了环境变量与配置文件中的 API 密钥与私钥。从命令内容与后续行为来看，攻击者主要在寻找可以直接使用的 API 密钥，特别是 AI 服务的密钥：攻击者在平台数据库中搜索密钥、大量读取 n8n 与 new-api／one-api 中的凭证，也尝试用 Zeabur 的 AWS 密钥调用 Amazon Bedrock。这只是对攻击者意图的观察；攻击者也读取了账号数据，我们仍把所有读取到的数据按已泄露处理。双因素认证与通行密钥的数据表只被查询了统计信息，没有读取内容的记录。我们已撤销所有用户的平台访问令牌，旧令牌都无法再使用。

**已迁移的环境变量不在平台数据库遭读取的范围内。** 八月事件后，Zeabur 为专用服务器的用户提供了轮换凭证、删除存放在 Zeabur 的环境变量与配置文件，以及一键迁移到自己服务器的指引与功能。已完成迁移的项目，这些数据只存放在用户的服务器上，Zeabur 没有保存，因此不在这次平台数据库遭读取的数据中。尚未迁移的项目，环境变量仍存放在 Zeabur，这次也遭读取。这不排除主机入侵造成的泄露；遭入侵的 GCP 专用服务器仍适用下方的处置建议。

**冒用账号。** 攻击者读取了用来签发登录凭证的密钥，我们**研判**攻击者用它伪造了登录凭证。攻击者到 16:47 才大量读取平台访问令牌，而且令牌只存哈希值，无法解释 16:12 就开始的冒用。10 月 15 日 16:12 至 17:19，攻击者以两个账号的身份调用 Zeabur API，读取账号与项目列表；其中一个是 Zeabur 员工的账号。这些请求没有修改任何资源。我们在 20:25 轮换了签名密钥，所有用户都已被登出。

**共享集群的数据库。** 攻击者在 865 个数据库的容器内执行了读取命令。审计记录只记录命令，不记录输出，部分命令也因出错而失败，所以每个数据库实际被读走多少无法确认。我们根据命令内容判断：

| 对象                   | 数量 | 被读取的数据                               |
| ---------------------- | ---: | ------------------------------------------ |
| 使用 PostgreSQL 的 n8n |  736 | 第三方凭证、用户、项目、变量与 workflow    |
| PostgreSQL（逐表读取） |  211 | 每张表最多 50,000 条；台北（tpe1）区域没有 |
| new-api／one-api       |   10 | AI 服务密钥、访问令牌与用户                |
| Redis                  |    1 | 名称含 token、secret 等字样的条目          |
| MongoDB、MariaDB       | 各 1 | 台北（tpe0）没有命令内容，按全部泄露处理   |

使用 PostgreSQL 的 n8n，有 602 个（在检查的 607 个中）把加密密钥写在环境变量中，所以 n8n 内的第三方凭证等同以明文泄露。由于此次数据读取发生于容器内部，八月事件后的数据库密码轮换，并未能阻断此次访问路径。

另外，东京（hnd1）区域至少 2 个 PostgreSQL 自 10 月 14 日 01:51 起被植入会回连外部的程序，其中一个在 10 月 15 日 16:24 仍有回连。它的入口是否为八月泄露的密码，目前**无法确认**。我们已在发现时通知受影响的用户更换凭证。

**GCP 专用服务器。** 调查确认，攻击者曾以 root 权限登录 101 台服务器，最后一次登录时间为 10 月 15 日 20:36。攻击者另于其中 50 台服务器新增其控制的 SSH 公钥，建立持续访问途径；并在 Zeabur 的 GCP 项目内创建 5 台虚拟机，将 16 份客户服务器磁盘副本挂载至其创建的虚拟机。

基于上述访问范围，这 101 台服务器均被列为可能发生数据泄露及留有未授权访问机制的受影响主机。我们已通过电子邮件通知受影响用户，并重置相关服务器的 root 密码。

**Hetzner 与 DigitalOcean。** 管理这两家客户服务器的令牌写在内部代码与环境变量中，随平台数据库一起泄露。持有令牌可以重置密码、重装系统或复制磁盘。我们在 10 月 16 日 01:09 撤销了全部令牌。两家都没有操作审计记录；Hetzner 账号的事件都能对应到用户本人或系统定时任务，DigitalOcean 仍在比对。

**Linode 与腾讯云。** Linode 890 台服务器中，有记录的 847 台没有攻击者登录。腾讯云的管理凭证没有遭使用的记录。

**GitHub App。** 攻击者在 10 月 15 日 15:05 读取了 Zeabur GitHub App 的私钥。持有私钥就能访问用户授权 Zeabur 访问的仓库。我们在 18:54 轮换私钥，目前没有发现它遭使用。我们已向 GitHub Support 申请完整的审计记录，尚未收到回复。

**Zeabur 内部系统。** 攻击者使用了多组 Zeabur 的 AWS 密钥。大多数请求被拒绝，但攻击者列出了两个区域的用户数据库备份与源代码上传的内容；是否下载**无法确认**。攻击者尝试调用 Amazon Bedrock，全部失败，没有产生费用。

<div id="what-we-did" />

## 我们做了什么

### 已完成

| 时间（10 月 15 日） | 处置                                                            |
| ------------------- | --------------------------------------------------------------- |
| 14:43–15:56         | 共享集群的管理接口只允许 Zeabur 系统连接                        |
| 15:32               | 撤销遭使用的集群管理令牌；21:47 再轮换一次                      |
| 17:17、17:31        | 停用攻击者使用的两把 GCP 密钥                                   |
| 17:58               | 移除攻击者的内网节点，并撤销创建它的凭证                        |
| 18:51               | 删除集群备份的访问密钥                                          |
| 18:54               | 轮换 GitHub App 私钥、支付服务密钥与 GitHub OAuth 密钥          |
| 18:55               | 移除 GCP 服务器初始化配置中的 root 密码                         |
| 20:05–21:22         | 停用 24 组已泄露或无法排除泄露的 AWS 密钥，换上权限更小的新密钥 |
| 20:25               | 轮换登录签名密钥，所有用户被登出                                |
| 20:34–20:36         | 移除 GCP 服务器默认服务账号的权限；封禁 GCP 服务器的公网 SSH    |
| 20:47               | 撤销全部 566 个 zSend API 密钥                                  |
| 21:46               | Zeabur 管理的专用集群只允许 Zeabur 系统连接                     |
| 10/16 01:09         | 撤销泄露的 Hetzner 与 DigitalOcean 令牌                         |

我们也停用了硬编码在代码中的腾讯云、阿里云与 Linode 凭证，从 GCP 服务器移除了攻击者的 SSH 密钥，并保全了各系统的审计记录。

之后我们也完成了：

- 撤销所有用户的平台访问令牌。
- 轮换其余遭读取的生产环境机密，包括平台数据库的账号密码，并撤销其他泄露的凭证。
- 发送邮件通知 GCP 专用服务器的用户，并重置服务器的 root 密码。
- 限制只有指定的服务能连接平台数据库。
- 集群备份不再保存明文机密，备份密钥与其他机密分开保存。
- 删除攻击者留下的磁盘副本、快照与测试资源。

### 进行中

- 追查配置仓库、旧 GCP 密钥与 9 月初服务器登录的泄露来源。
- 新增告警：管理权限的异常使用、在容器内执行命令、大量读取机密或数据库、内网加入新节点、云密钥从陌生来源使用。

### 对服务的影响

| 功能                           | 影响期间（UTC）                            | 目前状态                     |
| ------------------------------ | ------------------------------------------ | ---------------------------- |
| 登录                           | 10/15 20:25 起需重新登录                   | 正常                         |
| zSend 与系统邮件（含登录链接） | 10/15 20:00–22:02                          | 已恢复；zSend 密钥需重新创建 |
| GitHub 登录与部署              | 10/15 18:54–22:49                          | 已恢复                       |
| 构建                           | 10/15 20:05–22:56；中国区至 10/16 01:44    | 已恢复                       |
| 数据库备份                     | 10/15 20:33–22:13                          | 已恢复                       |
| GCP 专用服务器管理             | 10/15 17:31–20:35                          | 已恢复；只能使用网页 SSH     |
| 专用服务器自动续费             | 腾讯云 10/15 22:55–10/16 01:08 失败 154 次 | 已恢复；扣款已退回账户余额   |
| 腾讯云重置密码、SSH 登录记录   | 10/15 起                                   | 已恢复                       |
| Linode 专用 Kubernetes 集群    | 10/15 起                                   | 已恢复                       |

<div id="user-actions" />

## 您需要做什么

请现在就处理，无需等待通知邮件。八月事件后换过的凭证，也要再换一次。

### 所有用户

1. **更换环境变量中的所有凭证。** 包括 API 密钥、云密钥、数据库密码、签名与加密密钥。先到服务商处撤销旧的，再创建新的并重新部署。八月后已把环境变量迁移到自己专用服务器的项目，这些变量不在这次平台数据库读取范围内；若主机本身遭入侵，仍须更换主机上保存的凭证。
2. **重新登录并重新创建 Access Token。** 旧的平台访问令牌已全部撤销。到 [Access Token 管理页面](https://zeabur.com/account/api-keys)创建新的令牌，并检查有没有不明请求。
3. **zSend 用户：** 重新创建 zSend API 密钥。
4. **GitHub 用户：** 检查您的 GitHub 审计记录中，10 月 15 日 15:05 至 18:54 来自 Zeabur GitHub App 的操作。留意以下项目：
   - 非预期的 clone 或推送
   - 新增的 deploy key
   - 被修改的 webhook
5. **核对账单。** 检查各服务自 2026 年 10 月 14 日起的用量与账单，GCP 专用服务器用户请回溯到 9 月 1 日。10 月 14 日是我们目前所知攻击者最早使用凭证的时间，不代表凭证在此之前没有泄露；如果有更早的记录，也请一并检查。

### 共享集群用户

1. **在数据库内更换密码。** 只修改 Zeabur 上的环境变量，不会改到数据库内的密码。更换密码也不会让已泄露的数据失效；如果数据库存有您用户的密码哈希、登录会话或令牌，请一并撤销并重新生成。
2. **n8n：** 更换 n8n 加密密钥，并重新创建 n8n 内所有第三方凭证。
3. **new-api／one-api：** 撤销上游 AI 服务密钥，并重新生成访问令牌。
4. **PostgreSQL：** 检查有没有您不认识的角色、函数、触发器、定时任务或扩展。如有疑虑，创建新数据库并只导入数据。
5. **台北（tpe1）与香港（hkg1）区域：** 把数据库备份中的数据按已泄露处理。

### GCP 专用服务器用户

把服务器视为已遭入侵：

1. **备份数据后重建服务器。** 这是清除后门最可靠的方法。
2. **暂时无法重建时，至少：**
   - 移除 `/root/.ssh/authorized_keys` 中注释为 `@zeabur-pentest` 或您不认识的密钥。
   - 检查 `google-sudoers` 用户组、系统账号、crontab、systemd 服务与 k3s 工作负载。
   - 更换 root 密码，并关闭 SSH 的密码登录。
3. **更换服务器上的所有凭证**，包括您自己的云凭证，并检查对应账单。
4. **对照[入侵指标](#indicators-of-compromise)检查登录记录**，回溯到 2026 年 9 月 1 日。

### Hetzner 与 DigitalOcean 专用服务器用户

在控制台检查 10 月 14 日之后 root 密码是否被重置、系统是否被重装，并按上方 GCP 的检查项确认没有不明的登录方式。

<div id="root-causes" />

## 为什么会发生

**触发：** 攻击者持有 Zeabur 的集群管理令牌与多组云密钥。这些凭证以明文保存在配置仓库中。攻击者如何取得它们，目前无法确认；最可能的路径见[尚未证实的推测](#hypotheses)。

**影响范围扩大的相关因素：**

- **管理令牌生命周期与接口访问管控。** 管理令牌未设置有效期限，自 2024 年 1 月创建后从未轮换，也未纳入八月事件后的轮换范围；管理接口可通过公网访问。
- **机密存储与改进进度。** 配置仓库、代码、共享集群的服务配置及构建任务中，均存在明文存储的密钥。GCP 服务器初始化配置也保存 root 密码，此问题已于 9 月 3 日识别，但事件发生前尚未完成修复。10 月 3 日启动的机密迁移变更，事发时尚未合并至主分支。
- **备份内容与密钥隔离。** 集群备份包含所有机密，且备份访问密钥与其他机密存放于同一环境，形成进一步访问备份内容的途径。事件期间轮换的部分凭证也被后续备份收录。
- **访问权限与资源范围。**
  - 仅需读取单一存储空间的密钥，实际具备读取整个 AWS 账号内存储空间的权限。
  - GCP 服务器的默认服务账号具备项目级的修改权限。
  - 内网规则允许带有特定标签的节点连接至平台数据库。
  - 内部只读数据库账号具备读取所有数据的权限。
  - 已停用服务的部署密钥，在服务停用四个月后仍然有效。
- **内部服务与用户服务的环境隔离。** 两者部署于同一集群，使攻击者在读取用户配置时，也能获取内部服务凭证。
- **检测与审计记录覆盖范围。** 10 月 14 日持续超过 16 小时的攻击活动未触发告警，团队于次日收到用户反馈后识别事件。由于存储、GCP 与 GitHub 的访问记录不完整，部分访问及影响范围目前仍无法确认。

<div id="august-relation" />

## 与八月事件的关系

这是 Zeabur 不到两个月内的第二起安全事件。许多用户在八月后按我们的指引做了调整，也会想知道：既然做了这些措施，为什么还会发生，两起事件有没有关联。

**八月后做了什么。** 我们轮换了当时确认泄露的内部密钥，并停用 Legacy API Key。产品上，专用服务器的项目可以把环境变量与配置文件迁移到自己的服务器，也可以删除 Zeabur 保存的 SSH 凭证，并查看 SSH 登录记录。八月事件的通知与公告中，也建议用户轮换凭证、删除存放在 Zeabur 的环境变量与配置文件，并迁移到自己的服务器。

**为什么还是发生。** 八月的轮换没有覆盖配置仓库中以明文保存的集群管理令牌与 AWS 密钥，GCP 服务器初始化配置中的 root 密码也还没修复。这次攻击者使用的正是这些凭证。八月事件报告中写“已停用或轮换所有内部管理密钥”，这个说法并不完整，我们在此更正。攻击者如何取得这些凭证，目前无法确认；我们的推测见[尚未证实的推测](#hypotheses)。

**做对的地方。** 已按八月指引完成迁移的项目，环境变量与配置文件只存放在用户自己的服务器上，不在这次平台数据库遭读取的数据中。

## 时间轴

<ActivityTimeline
  legendLabels={{
    attacker: '攻击者的操作',
    presence: '攻击者有访问权限、没有连续记录',
    response: '我们的处置',
  }}
  title="攻击者活动与我们的响应"
  description="10 月 14 日至 15 日，各系统上的攻击者活动与我们的处置，按 UTC 时间绘制"
  start="2026-10-14T00:00:00Z"
  end="2026-10-16T00:00:00Z"
  ticks={[
    { at: '2026-10-14T00:00:00Z', label: '10/14' },
    { at: '2026-10-14T06:00:00Z', label: '06:00' },
    { at: '2026-10-14T12:00:00Z', label: '12:00' },
    { at: '2026-10-14T18:00:00Z', label: '18:00' },
    { at: '2026-10-15T00:00:00Z', label: '10/15' },
    { at: '2026-10-15T06:00:00Z', label: '06:00' },
    { at: '2026-10-15T12:00:00Z', label: '12:00' },
    { at: '2026-10-15T18:00:00Z', label: '18:00' },
  ]}
  markers={[{ at: '2026-10-15T13:56:00Z', label: '启动调查' }]}
  lanes={[
    {
      label: '共享集群管理接口',
      spans: [
        { from: '2026-10-14T01:40:00Z', to: '2026-10-14T01:52:00Z' },
        { from: '2026-10-14T12:39:00Z', to: '2026-10-14T13:34:00Z' },
        { from: '2026-10-15T14:17:00Z', to: '2026-10-15T14:48:00Z' },
      ],
      responses: [
        {
          from: '2026-10-15T14:43:00Z',
          to: '2026-10-15T15:56:00Z',
          label: '限制管理接口的连接来源',
        },
        {
          from: '2026-10-15T21:46:00Z',
          to: '2026-10-15T21:48:00Z',
          label: '专用集群只允许 Zeabur 系统连接；再次轮换管理令牌',
        },
      ],
    },
    {
      label: '用户数据库容器',
      spans: [{ from: '2026-10-14T13:40:00Z', to: '2026-10-14T17:04:00Z' }],
    },
    {
      label: 'AWS 密钥与机密',
      spans: [
        { from: '2026-10-14T01:36:00Z', to: '2026-10-14T01:50:00Z' },
        { from: '2026-10-14T14:47:00Z', to: '2026-10-14T17:53:00Z' },
        { from: '2026-10-15T14:36:00Z', to: '2026-10-15T17:04:00Z' },
        { from: '2026-10-15T19:06:00Z', to: '2026-10-15T19:11:00Z' },
        { from: '2026-10-15T19:57:00Z', to: '2026-10-15T20:04:00Z' },
        { from: '2026-10-15T20:30:00Z', to: '2026-10-15T20:34:00Z' },
        { from: '2026-10-15T21:05:00Z', to: '2026-10-15T21:06:00Z' },
      ],
      responses: [
        {
          from: '2026-10-15T18:51:00Z',
          to: '2026-10-15T18:52:00Z',
          label: '删除集群备份的访问密钥',
        },
        {
          from: '2026-10-15T20:05:00Z',
          to: '2026-10-15T21:22:00Z',
          label: '停用 24 组 AWS 密钥',
        },
      ],
    },
    {
      label: 'GCP 专用服务器',
      spans: [
        { from: '2026-10-14T13:40:00Z', to: '2026-10-14T13:50:00Z' },
        {
          from: '2026-10-14T13:50:00Z',
          to: '2026-10-15T14:05:00Z',
          faint: true,
        },
        { from: '2026-10-15T14:05:00Z', to: '2026-10-15T17:42:00Z' },
        { from: '2026-10-15T19:50:00Z', to: '2026-10-15T20:53:00Z' },
      ],
      responses: [
        {
          from: '2026-10-15T17:17:00Z',
          to: '2026-10-15T17:18:00Z',
          label: '停用第一把 GCP 密钥',
        },
        {
          from: '2026-10-15T17:31:00Z',
          to: '2026-10-15T17:32:00Z',
          label: '停用第二把 GCP 密钥',
        },
        {
          from: '2026-10-15T18:55:00Z',
          to: '2026-10-15T18:56:00Z',
          label: '移除初始化配置中的 root 密码',
        },
        {
          from: '2026-10-15T20:34:00Z',
          to: '2026-10-15T20:36:00Z',
          label: '移除默认服务账号权限、封禁公网 SSH',
        },
      ],
    },
    {
      label: '内部网络与平台数据库',
      spans: [
        {
          from: '2026-10-15T15:30:00Z',
          to: '2026-10-15T17:58:00Z',
          faint: true,
        },
        { from: '2026-10-15T16:10:00Z', to: '2026-10-15T16:47:00Z' },
      ],
      responses: [
        {
          from: '2026-10-15T17:58:00Z',
          to: '2026-10-15T17:59:00Z',
          label: '移除攻击者的内网节点',
        },
      ],
    },
    {
      label: '账号与第三方密钥',
      spans: [
        {
          from: '2026-10-15T16:12:00Z',
          to: '2026-10-15T17:19:00Z',
          label: '冒用账号调用 Zeabur API',
        },
      ],
      responses: [
        {
          from: '2026-10-15T18:54:00Z',
          to: '2026-10-15T18:55:00Z',
          label: '轮换 GitHub App 私钥、支付服务密钥与 GitHub OAuth 密钥',
        },
        {
          from: '2026-10-15T20:25:00Z',
          to: '2026-10-15T20:26:00Z',
          label: '轮换登录签名密钥，所有用户被登出',
        },
        {
          from: '2026-10-15T20:47:00Z',
          to: '2026-10-15T20:48:00Z',
          label: '撤销全部 zSend API 密钥',
        },
      ],
    },
  ]}
  caption="图 2：每个系统上方是攻击者的活动，下方是我们的处置。攻击者使用的是有效的凭证与 Zeabur 的正式访问渠道，从首次已知的凭证使用（10/14 01:36）到启动调查约 36 小时，这段期间的访问没有触发告警。启动调查后约 4 小时，已移除攻击者的内网节点。"
/>

| 时间（UTC）           | 事件                                                             |
| --------------------- | ---------------------------------------------------------------- |
| 2024 年 1 月 10 日    | 创建共享集群的管理令牌，没有有效期                               |
| 2026 年 1 月 20 日    | 管理令牌以明文写入配置仓库                                       |
| 8 月 27 日            | 八月事件中，GitHub App 私钥遭读取；与本事件的关联为推测          |
| 8 月 30 日、9 月 2 日 | 配置仓库以员工的 GitHub 授权被下载为压缩包，下载者无法确认       |
| 8 月 31 日            | 更换 GitHub App 私钥；配置仓库中的明文凭证没有轮换               |
| 9 月 1–5 日           | 不明来源以 root 密码登录约 98 台 GCP 专用服务器                  |
| 9 月 3 日             | 发现 GCP 服务器的初始化配置保存 root 密码，未在事发前修复        |
| 10 月 10 日 18:27     | 后续用于凭证滥用的 IP 首次出现在 Zeabur API 访问记录中（未登录） |
| 10 月 13 日 21:27     | 攻击者 IP 尝试 SSH 登录 3 台专用服务器，至 23:04，全部失败       |
| 10 月 14 日 01:36     | 攻击者首次使用 Zeabur 的 AWS 密钥                                |
| 10 月 14 日 01:40     | 攻击者首次以管理令牌访问共享集群                                 |
| 10 月 14 日 12:39     | 攻击者读取共享集群所有服务的配置与机密                           |
| 10 月 14 日 13:40     | 攻击者开始在数据库容器内读取数据；同时开始登录 GCP 专用服务器    |
| 10 月 14 日 17:04     | 数据库容器内的最后一条命令                                       |
| 10 月 15 日 13:56     | 收到用户反馈后，启动调查                                         |
| 10 月 15 日 14:43     | 开始限制共享集群管理接口的连接来源                               |
| 10 月 15 日 14:52     | 攻击者开始读取约 53 条生产环境机密，至 16:51                     |
| 10 月 15 日 15:02     | 已停用服务的部署密钥读取配置仓库（推测为攻击者）                 |
| 10 月 15 日 15:30     | 攻击者让一个节点加入 Zeabur 内部网络                             |
| 10 月 15 日 15:42     | 攻击者下载 Zeabur 存储中的用户数据库备份                         |
| 10 月 15 日 16:06     | 攻击者在取得的数据中搜索 API 密钥，至 18:13                      |
| 10 月 15 日 16:10     | 攻击者开始读取平台数据库，至 16:47                               |
| 10 月 15 日 16:12     | 攻击者开始冒用账号调用 API，至 17:19                             |
| 10 月 15 日 17:58     | 移除攻击者的内网节点                                             |
| 10 月 15 日 19:50     | 攻击者第二波登录 GCP 专用服务器，至 20:36                        |
| 10 月 15 日 20:25     | 轮换登录签名密钥，所有用户被登出                                 |
| 10 月 15 日 20:36     | 封禁 GCP 专用服务器的公网 SSH，攻击者的登录停止                  |
| 10 月 15 日 20:48     | 状态页更新为平台数据库与专用服务器也受影响                       |
| 10 月 15 日 21:01     | 攻击者尝试访问共享集群节点，被拒绝                               |
| 10 月 15 日 21:05     | 目前观察到的攻击者最后活动（AWS）                                |
| 10 月 16 日 01:09     | 撤销 Hetzner 与 DigitalOcean 令牌                                |
| 10 月 16 日 01:50     | 一位用户的 OpenAI 密钥遭滥用，至 02:56（推测来自本次泄露）       |

<div id="investigation-limits" />

## 尚待厘清的事项与调查限制

以下事项因现有记录的覆盖范围或完整性限制，目前尚无法确认。对于无法排除遭未授权访问的数据与凭证，我们按可能已泄露的情形采取应对措施。

- **初始凭证的获取途径。** 现有 GitHub 审计记录未覆盖 clone 操作，仅记录压缩包下载。记录显示，8 月 30 日及 9 月 2 日曾通过员工的 GitHub 授权下载配置仓库，但尚无法确认实际操作者。我们已请 GitHub 提供完整记录。目前的研判详见[尚未证实的推测](#hypotheses)。
- **共享集群数据库的实际数据读取范围。** 审计记录保留了执行的命令，但未记录输出内容，因此无法完整确认实际获取的数据。
- **备份与存储对象的下载范围。** 被入侵主机上的证据已确认，攻击者于 10 月 15 日 15:42 通过预签名下载链接获取客户数据库备份。此项证据与研判涉及内部凭证泄露的集群备份不同；后者是否被下载，尚未确认。由于当时未启用对象访问日志，其余对象及集群备份的实际下载范围仍无法完整确认。
- **GCP 资源的读取范围。** 现有 GCP 项目记录未覆盖读取操作，目前仅能确认写入操作。
- **Hetzner 与 DigitalOcean 令牌的使用情况。** 两家服务未提供可供本次调查使用的操作审计记录，因此无法确认相关令牌是否被使用。
- **平台数据库查询返回的具体内容。** 已确认攻击者执行的查询，以及其中 7 个主要查询的返回条数。但数据库日志未记录返回内容，也无法确认攻击者后续如何保存或使用相关数据。
- **部分集群的活动范围。** 台北（tpe0）集群及攻击者曾创建资源的专用集群，其审计记录不完整，限制了相关活动的核查范围。
- **10 月 14 日之前的活动与影响。** 现有共享集群及 AWS 记录中，未见 10 月 14 日 01:36 前使用有效凭证的活动。部分后续涉及凭证滥用的 IP，自 10 月 10 日起已出现在未登录的 Zeabur API 访问记录中；但这些 IP 可能由代理服务共用，无法仅凭 IP 相同确认操作者身份。10 月 13 日另有针对专用服务器的 SSH 登录尝试，均未成功。目前尚无法确认此期间是否发生数据泄露。

<div id="hypotheses" />

## 尚未证实的推测

以下是我们目前认为最可能的解释。它们有间接证据支持，但缺少直接记录，不能作为事实引用。取得新证据后，我们会更新或撤回。

**1. 最初的凭证可能来自八月事件**

- **推测：** 攻击者利用八月事件泄露的 GitHub App 私钥，取得了 Zeabur 私有配置仓库的内容，包括 10 月 14 日使用的 AWS 密钥与集群管理令牌。
- **目前没有任何证据直接证明这条路径。** 以下只是时间与能力上吻合的间接线索。
- **哪些换了、哪些没换：**
  - **GitHub App 私钥：已更换。** 八月事件中，这把私钥在 8 月 27 日遭读取。根据 GitHub 审计记录与机密管理服务的版本时间，私钥在 8 月 31 日更换，可被利用的时间窗口约 4 天。这个 App 安装在 Zeabur 的 GitHub 组织上，持有私钥就能读取组织内所有仓库。
  - **配置仓库中的明文凭证：没有更换。** 10 月 14 日攻击者最先使用的 AWS 密钥与集群管理令牌，8 月 27 日时已经以明文存在于配置仓库中。八月事件后我们只更换了私钥，没有更换这些凭证，直到 10 月 15 日事件响应时才停用。因此，即使私钥已经更换，若有人在 8 月 27 日至 31 日间取得了仓库内容，其中的凭证到 10 月仍然有效。
- **其他间接线索：**
  - 攻击者尝试读取的部分内部机密名称，只出现在另一个内部仓库中。攻击者可能同时持有两个仓库的内容，这与 App 私钥的组织级权限相符。
  - 10 月 14 日 01:36 之前，共享集群与 AWS 没有有效凭证的使用记录，后来滥用凭证的 IP 在 Zeabur API 上也都没有登录。这符合“只持有仓库中的凭证”的情况。
- **不支持的线索：** 八月事件与这次事件的攻击者 IP 没有重叠。
- **取证进展：** 我们已向 GitHub Support 申请相关记录，包括 8 月 27 日至 31 日间这个 App 签发的访问令牌、配置仓库的 clone 与下载记录，以及 8 月 30 日与 9 月 2 日以员工授权下载配置仓库的来源。截至本文更新时尚未收到回复。在取得记录前，这条路径只是推测；员工授权的下载也不能排除是另一条获取渠道。

**2. 10 月 14 日前的探测可能是同一攻击者的侦察**

- **推测：** 10 月 10 日至 13 日的匿名探测与 SSH 尝试，是同一攻击者在使用凭证前的侦察。
- **支持的证据：**
  - `103.237.102.191`：10 月 10 日 18:27 未登录浏览 Zeabur，10 月 14 日以管理令牌访问共享集群。
  - `23.106.46.239`：10 月 12 日 12:52 起未登录大量尝试 Zeabur API，10 月 13 日尝试 SSH 登录专用服务器，10 月 14 日 01:36 首次使用泄露的 AWS 密钥。
- **尚待证实：** 攻击者大量使用代理服务器，同一个 IP 可能由不同人共用，仅凭 IP 相同无法确认是同一人。

**3. 10 月 15 日的部署密钥访问可能是攻击者**

- **推测：** 10 月 15 日 15:02，一把已停用服务的部署密钥读取了配置仓库，研判为攻击者所为。
- **支持的证据：** 这次访问发生在攻击者读取生产环境机密期间（14:52 至 16:51）；密钥所属的服务已停用四个月，不应有正常访问。
- **尚待证实：** 目前没有记录能把这次访问直接关联到攻击者。

**4. 泄露的用户密钥可能已遭滥用**

- **推测：** 10 月 16 日 01:50 至 02:56，一位用户存放在 Zeabur 的 OpenAI API 密钥被用来发出约 1,107 次图片生成请求。我们推测这把密钥来自本次泄露的环境变量。
- **尚待证实：** 无法排除密钥从其他渠道泄露。这也是本文建议所有用户更换密钥的原因，见[您需要做什么](#user-actions)。

<div id="indicators-of-compromise" />

## 入侵指标

在您的系统或服务商记录中发现下列指标时，请把相关凭证按已泄露处理，并联系我们。攻击者大量使用轮换的代理服务器，下表只列出有代表性的地址。

| 类型       | 指标                                                                               | 出现在                                                        |
| ---------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| IP         | `23.106.46.239`                                                                    | 集群访问、云 API、SSH 登录                                    |
| IP         | `102.244.78.57`                                                                    | 云 API、GCP 配置修改                                          |
| IP         | `103.237.102.191`                                                                  | 集群访问、云 API                                              |
| IP         | `103.112.139.162`                                                                  | 首次使用集群管理令牌                                          |
| IP         | `45.146.232.28`                                                                    | 验证 AWS 密钥                                                 |
| IP         | `216.98.11.198`、`45.58.38.175`                                                    | 专用服务器 SSH 登录                                           |
| IP         | `52.220.72.188`                                                                    | 被植入程序的 PostgreSQL 回连地址                              |
| IP         | `31.57.201.201`                                                                    | 9 月初以 root 密码登录 GCP 专用服务器；与本事件的关联无法确认 |
| SSH 密钥   | 注释 `*@zeabur-pentest`，指纹 `SHA256:EdBc0uephoOMemIRKK0SRV2TRR45n52tJm1yErVU1iM` | 攻击者加入专用服务器的密钥                                    |
| User-Agent | `Boto3/1.43.111`（Linux 6.12.86）                                                  | 攻击者使用 AWS 密钥的客户端                                   |

## 术语说明

- **共享集群（Shared Cluster）：** 多位用户的服务一起运行的 Kubernetes 集群。我们已在 2026 年 2 月[公告下线](/changelogs/phasing-out-shared-cluster)，受影响的服务都在公告前部署。
- **专用服务器（Dedicated Server）：** 由 Zeabur 托管、只运行单一用户服务的服务器。
- **管理令牌：** 能管理整个集群的凭证，持有者可以读取所有服务的配置并在任何容器内执行命令。
- **机密管理服务：** Zeabur 用来集中保存生产环境机密的 AWS 服务。
- **内部网络：** 连接 Zeabur 生产环境服务的私有网络（Tailscale），平台数据库只接受来自这个网络的连接。
- **平台数据库：** 保存所有账号、项目、服务与环境变量的 Zeabur 生产数据库。

## 更多信息

如需协助，或发现异常访问与不明费用，请通过 [Zeabur Support](https://zeabur.com/support) 联系我们。联系前请先撤销相关凭证，并只提供脱敏后的信息；请勿在工单或公开渠道中贴出仍然有效的密钥或密码。

若您的第三方 API 密钥或云账号因本事件产生额外费用，请通过支持工单申请补偿。我们会核对服务商的使用记录与费用，并说明核查结果。

Zeabur 已[宣布将于 2026 年 12 月 31 日停止运营](/blogs/zeabur-is-shutting-down)，这是运营上的决定。在此之前，我们会持续处理本事件的支持与补偿申请，并持续更新本文与[状态页](https://status.zeabur.com)。我们向所有受影响的用户致歉。

Zeabur 团队
