亲自确认 etcd 里的明文,再把它堵上
目标
直接打开etcd确认Secret实际上是如何存储的,存储时分别用manifest写下加密、信封加密、访问控制、外部存储库这四层对应。
为什么重要
传播最广泛的误解是“Secret是base64,所以很安全”。base64是一种没有密钥的表达方式,所以只要一个命令就能还原,更重要的是,在默认设置中,apiserver将Secret直接写成等d。因此,在前一个模块中学习的etcd快照也是集群中最敏感的文件。在这个练习中,不是通过别人的话,而是亲自确认这个事实。对应不仅仅是一层。EncryptionConfiguration阻止获得磁盘的人,KMS信封加密甚至将该密钥从群集之外移除。但是即使加密存储也对通过API读取的人没有用,所以需要RBAC,resourceNames可以进一步缩小到以罗为单位,但那个list/watch也应该知道不能通用的局限性。最后,包括把值完全放在集群以外的外部秘密方式,区分四层分别阻止什么和什么,这是这个实训的核心。
阶段
- 名称空间
secret-lab制作并放入其中Secretdb-password请制作。类型是Opaque和身高password的值是labhub-Pr0d-2026是。作为后面比较权限的对照群,Secretother-secret请做一个。 db-password的data.password价格保持原样/root/ops/secrets/out/encoded.txt啊,解码了那个的平文/root/ops/secrets/out/decoded.txt请保存到(解码结果为labhub-Pr0d-2026必须相连,两个文件必须相互对应)。还有/root/ops/secrets/out/base64-note.txt请用一行文字写下结论,即base64只是编码,不是加密。/root/ops/secrets/encryption-config.yaml请使用。apiVersion银apiserver.config.k8s.io/v1,kind是EncryptionConfiguration并且resources[0].resources在secrets必须进去。providers的第一个是实际加密提供商(aescbc,secretbox,aesgcm其中之一)并且keys[0].name必须有这个,最后是identity必须是。/root/ops/secrets/kms-config.yaml请使用。kind是EncryptionConfiguration并且providers[0]是kms必须是。kms.apiVersion银v2,kms.endpoint是unix://以开始的套接字路径,kms.name也应该有。还有/root/ops/secrets/out/envelope-note.txt请说明信封加密的两层结构(数据密钥和主密钥)。/root/ops/secrets/external-secret.yaml请用两个文件。一个是kind: SecretStore,另一个是kind: ExternalSecret是。ExternalSecret里面有spec.refreshInterval,spec.secretStoreRef.name,spec.target.name,spec.target.creationPolicy,spec.data[0].remoteRef.key必须有全部。在这个文件中实际密码labhub-Pr0d-2026如果进入这里,就不能了。secret-labE ServiceAccountdb-client制作,Roledb-secret-reader请制作。规则是secrets关于资源resourceNames是db-password一个,verbs是get必须只有一个。这个角色db-client用RoleBinding进行。结果db-client是db-password读,other-secret不能阅读,查看秘密列表(list)也不能做。还有/root/ops/secrets/out/resourcenames-note.txt在resourceNames去list/watch请写上不通的情况。secret-labE Secretpinned-config请制作。immutable: true和身高build的值是2026-08-20是。然后尝试更改这个值,并发送拒绝消息。/root/ops/secrets/out/immutable-error.txt请保存。保存后也build价格仍然是2026-08-20应该接着。- 在etcd中
/registry/secrets/secret-lab/db-password查询了身高后打印出来的输出/root/ops/secrets/out/etcd-secret.txt请保存到。在这个文件里平文labhub-Pr0d-2026必须看到这个。还有/root/ops/secrets/out/secrets-audit.json请制作。total_secrets是secret-lab必须与实际Secret数量一致,encrypted_at_rest是false,plaintext_visible_in_etcd是true是。mitigations在配置中写入3个以上的对应方案,存储时加密(EncryptionConfiguration或“加密”)和访问权限控制(RBAC或者必须包含“权限”)。
参考
- 这个嵌入式系统中的etcd不需要客户端TLS
127.0.0.1:2379在听。etcdctl --endpoints=127.0.0.1:2379 get /registry/secrets/secret-lab/db-password可以查询。 - Kubernetes将对象存储在etcd中,而不是JSON,而是protobuf。所以看起来像输出有问题的二进制文件是正常的,里面混杂着人可以读到的字符串。密码里面不是base64,而是直接的纯文本——这就是这个阶段的重点。为了方便阅读,请
| strings我| hexdump -C扫一扫,将查询输出直接保存到文件中(如果网络字节过多的话| tr -d '\0'往里踢就可以了)。 - 3次加密密钥将32位随机值编码为base64。
head -c 32 /dev/urandom | base64可以做成。 - 7次修改尝试
kubectl patch我kubectl apply任何一方都可以。错误信息都会显示为标准错误。2>&1要用接收才能留在文件中。 - 8次秘密的数量是
kubectl get secrets -n secret-lab -o json | jq '.items | length'用手指数比较安全。用手数的话容易出错。 - 常见的错误1:在3次中
identity把放在列表最前面。用来写的就是第一个提供商,所以那一刻会回到普通文本保存。 - 常见的错误2:在6次中
verbs在list一起放进去。resourceNames无法缩小列表查询范围,所以所有秘密都会被暴露。 - 常见的错误3:在5次宣言中写下实际值。没有值是外部秘密方式存在的理由。
- 练习板每次练习都会重新生成,所以前一次练习制作的聚类状态不会保留。命名空间和Secret请在本次练习中亲自制作。之所以要将运行程序记在运行手册和宣言中,而不是记忆中,正是这个原因。
制作两个练习用的Secret
名称空间secret-lab制作并放入其中Secretdb-password请制作。类型是Opaque和身高password的值是labhub-Pr0d-2026是。作为后面比较权限的对照群,Secretother-secret请做一个。
请确认基本类型是什么。因为后面需要比较权限范围的对照组,所以要制作两个。
直接查看base64
db-password的data.password价格保持原样/root/ops/secrets/out/encoded.txt啊,解码了那个的平文/root/ops/secrets/out/decoded.txt请保存到(解码结果为labhub-Pr0d-2026必须相连,两个文件必须相互对应)。还有/root/ops/secrets/out/base64-note.txt请用一行文字写下结论,即base64只是编码,不是加密。
这是用手确认编码和加密差异的步骤。请确认反向值和编码值是否相互对应。
保存时写入加密设置
/root/ops/secrets/encryption-config.yaml请使用。apiVersion银apiserver.config.k8s.io/v1,kind是EncryptionConfiguration并且resources[0].resources在secrets必须进去。providers的第一个是实际加密提供商(aescbc,secretbox,aesgcm其中之一)并且keys[0].name必须有这个,最后是identity必须是。
用来写作的是列表的第一项。要继续阅读现有平文,请思考最后应该留下什么。键需要一个名称。
KMS v2 信封加密设置写入
/root/ops/secrets/kms-config.yaml请使用。kind是EncryptionConfiguration并且providers[0]是kms必须是。kms.apiVersion银v2,kms.endpoint是unix://以开始的套接字路径,kms.name也应该有。还有/root/ops/secrets/out/envelope-note.txt请说明信封加密的两层结构(数据密钥和主密钥)。
插件不是连接到网络,而是连接到插座。请把两层结构是什么留下来作为备忘录。
写外部秘密存储库关联文件夹
/root/ops/secrets/external-secret.yaml请用两个文件。一个是kind: SecretStore,另一个是kind: ExternalSecret是。ExternalSecret里面有spec.refreshInterval,spec.secretStoreRef.name,spec.target.name,spec.target.creationPolicy,spec.data[0].remoteRef.key必须有全部。在这个文件中实际密码labhub-Pr0d-2026如果进入这里,就不能了。
需要两个文件。一个定义从哪里拿来,另一个定义用什么名字做什么。如果manifest中包含实际密码,使用理由就会消失。
制作一个只打开一个秘密的角色
secret-labE ServiceAccountdb-client制作,Roledb-secret-reader请制作。规则是secrets关于资源resourceNames是db-password一个,verbs是get必须只有一个。这个角色db-client用RoleBinding进行。结果db-client是db-password读,other-secret不能阅读,查看秘密列表(list)也不能做。还有/root/ops/secrets/out/resourcenames-note.txt在resourceNames去list/watch请写上不通的情况。
有通过名字缩小范围的字段。但是请一起整理一下,这个字段不适用的一些动词。
制作不变Secret并确认拒绝修改
secret-labE Secretpinned-config请制作。immutable: true和身高build的值是2026-08-20是。然后尝试更改这个值,并发送拒绝消息。/root/ops/secrets/out/immutable-error.txt请保存。保存后也build价格仍然是2026-08-20应该接着。
关闭后尝试实际更改,并留下拒绝信息。错误会显示为标准错误。
从etcd中拿出平文作为证据留存
在etcd中/registry/secrets/secret-lab/db-password查询了身高后打印出来的输出/root/ops/secrets/out/etcd-secret.txt请保存到。在这个文件里平文labhub-Pr0d-2026必须看到这个。还有/root/ops/secrets/out/secrets-audit.json请制作。total_secrets是secret-lab必须与实际Secret数量一致,encrypted_at_rest是false,plaintext_visible_in_etcd是true是。mitigations在配置中写入3个以上的对应方案,存储时加密(EncryptionConfiguration或“加密”)和访问权限控制(RBAC或者必须包含“权限”)。
请回想一下容器对象的键路径规则。虽然值看起来像protobuf,但字符串会保持原样。