ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Telegraf 集成 systemd 凭据存储(systemd-creds)实现安全的明文凭据注入

Telegraf 集成 systemd 凭据存储(systemd-creds)实现安全的明文凭据注入 Telegraf 集成 systemd 凭据存储systemd-creds实现安全的明文凭据注入【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf导读Telegraf 的systemd密钥存储插件Secret Store Plugin让 Telegraf 能够直接消费由 systemd 注入服务单元service unit的凭据credentials并在配置中以{systemd:secret_key}的方式引用它们。本文基于plugins/secretstores/systemd/README.md结合仓库中的源码与测试系统讲解 systemd 凭据机制的运行原理、systemd-creds的加密/解密操作、Telegraf 侧的配置方法、多密钥存储链式解锁chaining实战以及常见故障排查手段帮助读者在 Telegraf 中安全地管理用户名、密码、Token 等敏感信息避免将明文凭据写入配置文件。插件概述与适用条件plugins/secretstores/systemd是一个只读的密钥存储插件它只负责读取 systemd 为服务注入的凭据文件不能创建或修改这些凭据。凭据由 systemd 以明文文件形式呈递给受信服务但在宿主系统上以加密形态存储在硬件支持的情况下加密还可使用 TPM2 芯片进行保护。使用该插件需要注意两个版本门槛插件要求 systemd 250。仓库源码plugins/secretstores/systemd/systemd.go中以常量systemdMinimumVersion 250硬编码了最低版本插件在Init()阶段通过 systemd D-Bus 查询Version属性见getSystemdMajorVersion低于 250 会直接报错systemd version %d below minimum version %d。若使用默认服务文件中的ImportCredential则需要 systemd 254。scripts/telegraf.service中第 12 行即为ImportCredentialtelegraf.*更低版本只能改用LoadCredentialEncrypted在 service-override 中显式声明凭据。该插件仅在 Linux 上构建plugins/secretstores/systemd/systemd_nonlinux.go在非 Linux 平台为空实现且插件注册代码secretstores.Add(systemd, ...)位于 Linux 构建标签的systemd.go中。使用方式{store-id:secret_key}引用语法密钥存储的使用方式与 Telegraf 全局的 secret 机制一致参见 docs/includes/secret_usage.md在 Telegraf 配置中用{store-id:secret_key}引用某个密钥存储中的密钥。需要注意只有声明了Secret store support章节的插件和选项才支持密钥存储。例如 plugins/outputs/influxdb/README.md 就明确写明username和password两个选项支持从密钥存储取密钥。secretstores.systemd插件的密钥是静态的只在 Telegraf 启动时解析一次之后不会刷新。因此修改或重新加密凭据后需要重启 Telegraf 服务才能生效。配置参数完整的配置示例如下内容同步自plugins/secretstores/systemd/sample.conf# Reading systemd credentials [[secretstores.systemd]] ## Unique identifier for the secret store. ## This id can later be used in plugins to reference the secrets ## in this secret store via {id:secret_key} (mandatory) id systemd ## Path to systemd credentials directory ## This should not be required as systemd indicates this directory ## via the CREDENTIALS_DIRECTORY environment variable. # path ${CREDENTIALS_DIRECTORY} ## Prefix to remove from systemd credential-filenames to derive secret names # prefix telegraf.参数说明id必填该密钥存储的唯一标识符用于在插件中通过{id:secret_key}引用其中的密钥。path可选systemd 凭据目录的路径。正常情况下无需配置——systemd 会通过CREDENTIALS_DIRECTORY环境变量告知服务该目录位置。从源码Init()看若CREDENTIALS_DIRECTORY未定义且未显式配置path插件会直接报错path required without CREDENTIALS_DIRECTORY。同时Init()会把路径转换为绝对路径并校验目录可访问os.Stat否则报accessing credentials directory %q failed。prefix可选默认telegraf.从 systemd 凭据文件名中剥离的前缀用于推导密钥名。默认前缀在注册代码中设定secretstores.Add(systemd, func(_ string) telegraf.SecretStore { return Systemd{Prefix: telegraf.} })。List()实现里通过strings.TrimPrefix(entry.Name(), s.Prefix)去掉前缀后作为密钥名Get(key)则通过filepath.Join(s.Path, s.Prefixkey)还原真实文件路径。若你使用了其他前缀或没有前缀必须同步调整本项。在服务进程内部每个由 systemd 提供的密钥都以${CREDENTIALS_DIRECTORY}/secret-name文件形式呈现。普通非 telegraf用户看不到这些文件其他 systemd 服务能否看到这些凭据由其 service unit 中的User与PrivateMounts指令决定详见 systemd.exec 手册。值得注意的是源码中Get()还对拼接后的路径做了目录校验若filepath.Dir(secretFile) ! s.Path会返回invalid directory detected用于防止路径逃逸。凭据管理Credential management插件本身不能创建凭据创建与管理交给systemd-creds完成。下文步骤浓缩自 systemd-creds 手册命令的具体选项和动词可能随你使用的 systemd 版本而不同请以对应手册为准。示例中统一使用/etc/credstore.encrypted作为加密凭据的存储目录并假设 Telegraf 通过包管理器安装如需其他安装方式可能需要自行创建该目录同时假设密钥存储 ID 已设为systemd。环境初始化Setup如果打算用系统 TPM2 芯片保护凭据先确认其可用性sudo systemd-creds has-tpm2输出形如partial -firmware driver system subsystem若 TPM2 可用凭据可通过 TPM2 sealing 与当前设备绑定。注意一旦使用 TPM2 sealing凭据只能在创建它的同一台机器上创建和使用无法复制到其他机器——所需的解密密钥存放在 TPM2 中。随后创建根密钥root key以完成凭据系统初始化sudo systemd-creds setup若生成密钥落在未加密磁盘上命令可能给出警告——官方不建议将密钥存放在未加密磁盘。创建凭据创建加密凭据的基本命令echo -n john-doe-jr | sudo systemd-creds encrypt - /etc/credstore.encrypted/telegraf.http_user该命令会生成加密文件telegraf.http_user其文件名即密钥存储提供密钥时的 key。为了避免明文凭据进入 shell 历史或显示在屏幕上推荐用systemd-ask-password交互式输入systemd-ask-password -n | sudo systemd-creds encrypt - /etc/credstore.encrypted/telegraf.http_password关于命名有两处易错点Telegraf 期望凭据文件以telegraf.为前缀且不要使用--name自定义名称。默认情况下 Telegraf 会剥离telegraf.前缀。若使用其他前缀或完全没有前缀必须调整密钥存储的prefix配置。关键限制由于凭据来自 systemd 注入本插件只在 Telegraf 作为 systemd 服务启动时才可用命令行手动启动 Telegraf 时找不到任何凭据。因此不要对该插件使用 Telegraf 的secrets管理命令如telegraf secrets get/set/...。在 Telegraf 配置中使用凭据先在配置中实例化systemd密钥存储[[secretstores.systemd]] id systemd假设已有http_user与http_password两个凭据即可在插件中这样引用[[inputs.http]] urls [http://localhost/metrics] username {systemd:http_user} password {systemd:http_password}链式解锁Chaining实现无人值守启动当凭据数量很多、或需要跨主机共享凭据时把所有凭据一一列在 service 文件中既繁琐也难以在命令行下手动测试配置因为systemd密钥存储只在服务方式下可用。此时可以借助密钥存储链用一个密钥存储这里是secretstores.systemd解锁另一个密钥存储示例为secretstores.jose。[[secretstores.systemd]] id systemd [[secretstores.jose]] id mysecrets path /etc/telegraf/secrets password {systemd:initial}此处假设initial凭据经由 service 文件注入它被用来解锁jose密钥存储后者由加密文件承载、可以提供大量不同密钥。随后输入/输出插件即可通过{mysecrets:...}引用jose提供的密钥填充用户名、密码或 Token 等敏感数据。这既规避了 service 文件中堆砌大量凭据的问题也让共享/分发密钥更灵活。源码实现要点从源码层面可以更清晰地理解插件行为plugins/secretstores/systemd/systemd.goInit()检测 systemd 版本低于 250 报错→ 读取CREDENTIALS_DIRECTORY环境变量作为默认路径 → 解析绝对路径并校验目录存在与可访问。List()读取凭据目录下的所有文件剥掉prefix前缀后返回密钥名列表。Get(key)按path prefix key拼出文件路径做目录防逃逸校验后读取文件内容返回。GetResolver(key)返回一个解析函数其中动态标记恒为false印证了“密钥是静态的、启动后不刷新”的特性。接口契约secretstore.go中定义的telegraf.SecretStore接口要求实现Init、SampleConfig、Get、List、GetResolver可读写的密钥存储还要实现可选的SecretStoreEditor接口Set/Remove。systemd 插件不实现SecretStoreEditor源码注释也明确这是“只读源”。注册机制plugins/secretstores/registry.go维护全局SecretStores注册表init()中通过secretstores.Add(systemd, ...)完成注册。测试文件plugins/secretstores/systemd/systemd_test.go与testdata/目录内含secret-file-1、secretFile、secret_file_2三个模拟凭据文件覆盖了版本下限校验、缺少CREDENTIALS_DIRECTORY时的报错、目录不可访问、List/Get/GetResolver及不存在的密钥报错等场景可作为理解插件行为的参考。故障排查Troubleshooting排查前先确认 systemd 版本满足要求250ImportCredential需 254。服务无法启动检查服务日志。常见原因是使用了--name选项——它和 systemd 的ImportCredential设置不兼容。同时核对systemd-creds encrypt时写入的名称与LoadCredentialEncrypted语句中使用的名称是否一致。Telegraf 中引用不到凭据可以用下面的命令查看当前可用凭据CREDENTIALS_DIRECTORY指向加密凭据目录CREDENTIALS_DIRECTORY/etc/credstore.encrypted sudo systemd-creds list对应前文的示例输出类似NAME SECURE SIZE PATH ------------------------------------------------------------------- telegraf.http_password insecure 146B /etc/credstore.encrypted/telegraf.http_password telegraf.http_user insecure 142B /etc/credstore.encrypted/telegraf.http_user注意NAME列中的名称还要去掉密钥存储中配置的prefix默认telegraf.才能得到密钥的key。查看凭据实际值sudo systemd-creds decrypt /etc/credstore.encrypted/telegraf.http_password -⚠️ 上述命令会泄露凭据的明文值请务必谨慎使用补充说明本插件只支持读取密钥无法创建或修改它们创建/修改请使用systemd-creds。默认的 Telegraf systemd 服务文件scripts/telegraf.service已配置ImportCredentialtelegraf.*与Usertelegraf、PrivateMountstrue安装 Telegraf 后基本可开箱即用使用低于 254 的 systemd 时需改用LoadCredentialEncrypted覆盖声明。有关 Telegraf 密钥存储的全局配置方式与更多插件支持情况可查阅 docs/CONFIGURATION.md 中 secret store 相关章节以及各插件 README 的Secret store support部分。【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进