该模块的功能 #
你实例上几乎每个服务都需要一个密钥:数据库密码、完整性工具的口令、一个 API 密钥……手动保存它们——或者更糟,让它们保持默认值——是机器最终被攻陷的最常见方式之一。
secrets 模块在本地处理这套生命周期:它用一个加密安全的生成器(CSPRNG)生成每个密钥,以 0600 权限存储(只有 root 能读取),以干净的输出返回它、随时可用于管道串联,并在你需要时轮换它。一切都按域组织(例如 mariadb 或 tripwire),且每个域可以有多个字段。
generate 是幂等的:如果某个域的密钥已经存在,它不会去动它。这样一来,单个镜像就能在每个实例首次启动时创建各自的密钥,而不会让两台机器共用同一个密码。这些值永远不会被记入日志,也不会在 list 中显示。
常见任务 #
选择你想做的事。每份配方都附有写好的命令——只需把域换成你自己的,然后点击复制。
1
生成某个服务的密钥
为一个域创建一个强密码,仅在它尚不存在时才创建。
用 ubuntu 用户通过 SSH 连接到你的服务器。
为 mariadb 域生成密钥。由于它是幂等的,你可以随意多次运行,完全不用担心覆盖:
$ sudo imaxe secrets generate mariadb需要为另一个工具准备一个长口令并放在某个特定字段?调整 --format、--len 和 --field:
$ sudo imaxe secrets generate tripwire --field local.passphrase --format passphrase --len 400600 权限存储。如果它已经存在,则没有任何改变——命令仍然以成功结束。2
读取密钥以便使用
获取原始值,可直接串联到另一条命令中。
get 只打印值,没有任何修饰或多余的换行,因此你可以通过管道把它传给另一个进程:
$ sudo imaxe secrets get mariadb密钥在域的某个特定字段里?用 --field 指向它:
$ sudo imaxe secrets get tripwire --field local.passphrasePASS="$(sudo imaxe secrets get mariadb)" 并在脚本中直接使用它。3
轮换一个密钥
用一个新值替换旧值,并把该域标记为已轮换。
为该域生成一个新值。与 generate 不同,rotate 会替换已存在的密钥:
$ sudo imaxe secrets rotate mariadblist 中看到日期)。记得用 get 得到的新值去更新使用该密钥的服务。4
查看有哪些域
查询元数据,而不暴露任何值。
列出各个域及其元数据(何时创建、何时轮换)。它从不显示密钥本身:
$ sudo imaxe secrets list需要用于脚本或自动化检查?请求 JSON 输出:
$ sudo imaxe secrets list --json密钥只有在它存于磁盘上时才仅对 root 可读。一旦你用 get 读取它,它就进入了你的终端和你的 shell:避免让它留在历史记录(history)里、留在被过度导出的环境变量里,或留在日志里。优先使用像 "$(sudo imaxe secrets get mariadb)" 这样一次性的命令替换。
用法概要 #
imaxe secrets <subcomando> [<dominio>] [--field CLAVE] [flags]所有子命令都需要 root 权限(使用 sudo),因为它们会读写 /etc/imaxe/ 下的 0600 文件。为 list 添加 --json 可获得机器可读的输出,适用于脚本。记住:get 输出的是原始值,没有任何修饰,可直接用于管道。
子命令 #
| 子命令 | 功能 | 相关标志 |
|---|---|---|
| generate | 如果某个域的密钥不存在则创建它(幂等,CSPRNG)。不带域时,生成 generate_on_first_boot 中列出的那些。 | --len, --format, --field |
| get | 以干净的输出返回某个密钥的值,适用于管道。 | --field |
| rotate | 生成一个新密钥并把该域标记为已轮换。 | --field |
| list | 列出各个域及元数据(创建、轮换)。从不显示值。 | --json |
参数与标志 #
| 标志 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| <dominio> | string | — | 密钥域(例如 mariadb、tripwire)。在 get 和 rotate 中为必填。在 generate 中,留空 = generate_on_first_boot 中的那些域。 |
| --field | string | value | 域内的字段。允许你为每个域存储多个密钥(例如 local.passphrase)。 |
| --len | int | 32 | 在 generate 中:密钥的字符长度。 |
| --format | enum | password | 在 generate 中:值的格式——password、passphrase 或 hex。 |
| --json | bool | false | 在 list 中,将元数据以结构化 JSON 输出到 stdout。 |
文件与路径 #
| 路径 | 内容 |
|---|---|
| /etc/imaxe/secrets.yml | 模块配置:默认值(length、format)、各个域以及 generate_on_first_boot 列表。以 0600 权限存储。 |
secrets.yml 示例:
defaults:
length: 32
format: password
domains: {}
generate_on_first_boot:
- mariadb
- tripwire使用该配置时,首次启动时一条不带域的 sudo imaxe secrets generate 会以默认长度和格式为 mariadb 和 tripwire 创建密钥。
退出码与日志 #
每次执行都会返回一个退出码,你可以用 echo $? 查看——便于在脚本中串联:
get 不带域)。脚本中的典型用法,利用 get 的干净输出:
$ sudo imaxe secrets generate mariadb \
&& sudo imaxe secrets get mariadb | some-tool --stdin-password \
|| echo "falló con código $?"故障排查 #
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 出现 NOTFOUND(退出码 3) | 该域或 --field 尚未生成。 | 先用 secrets generate <dominio>(以及相同的 --field)创建它。 |
| 出现 USAGE(退出码 2) | 运行 get 或 rotate 时没有指定域。 | 把域作为参数传入;在这些子命令中它是必填的。 |
generate 没有改变值 | 密钥已经存在:generate 按设计是幂等的。 | 如果你想要一个新值,使用 secrets rotate <dominio>。 |
读取时出现 Permission denied | 文件是 0600,而你在没有权限的情况下运行了它。 | 用 sudo 运行该命令;只有 root 能访问密钥。 |
Secrets 模块遇到问题了?
把「imaxe <module> status --json」的输出发给我们,我们会尽快回复你。