ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Salt 密钥管理实战:掌握 salt-key 命令从入门到源码级解析

Salt 密钥管理实战:掌握 salt-key 命令从入门到源码级解析 Salt 密钥管理实战掌握 salt-key 命令从入门到源码级解析【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt导读salt-key是 Salt 基础设施中负责管理 master 与 minion 之间认证公钥的核心命令当一台 minion 首次向 master 发起连接时它会把自己的公钥提交给 master管理员必须通过salt-key在 master 上完成接受accept操作minion 才能与 master 建立受信通信。本文以仓库文档 doc/ref/cli/salt-key.rst 为骨架结合 salt/cli/key.py、salt/key.py 等源码实现系统讲解四种密钥状态、全部命令行选项、密钥生成与签名功能以及背后的实现原理与真实测试用例帮助你安全、熟练地管理 Salt 认证体系。命令概览salt-key 是什么salt-key的基本调用格式如下salt-key [ options ]从文档描述看salt-key执行的是 Salt 服务器端master用于认证的公钥的简单管理。在初始连接时Salt minion 会将它的公钥发送给 Salt master这个公钥必须在 master 上通过salt-key命令接受。也就是说所有 minion 公钥的生命周期管理查看、接受、拒绝、删除、指纹比对都由这一条命令完成。从源码入口 salt/cli/key.py 可以看到它的完整执行路径SaltKey.run()首先解析参数然后实例化salt.key.KeyCLI并执行key.run()。其中SaltKey继承自 salt/utils/parsers.py 中的SaltKeyOptionParser该解析器组合了多个 mixinConfigDirMixIn配置目录、LogLevelMixIn日志级别、OutputOptionsMixIn输出格式、RunUserMixin运行用户、EAuthMixIn外部认证等其描述字符串为 salt-key is used to manage Salt authentication keys。四种密钥状态理解 Salt 认证模型文档明确指出Salt minion 密钥可以处于以下四种状态之一unaccepted未接受密钥正在等待被接受。minion 首次连接 master 后即处于此状态。accepted已接受密钥已被接受minion 可以与 Salt master 正常通信。rejected已拒绝密钥被使用salt-key命令手动拒绝。处于该状态的 minion 不会从 Salt master 收到任何通信。denied已拒绝/自动拒绝密钥被 Salt master 自动拒绝。这通常发生在minion 使用了重复的 ID或者 minion 被重建/重新生成了新密钥而旧密钥未从 master 上删除。处于该状态的 minion 同样不会从 master 收到任何通信。这四种状态在源码 salt/key.py 的Key类中有对应的目录常量定义ACC minions # 已接受密钥目录minions/ PEND minions_pre # 待接受密钥目录minions_pre/ REJ minions_rejected # 已拒绝密钥目录minions_rejected/ DEN minions_denied # 自动拒绝密钥目录minions_denied/对应到磁盘上这些状态表现为 master 的pki_dir默认/etc/salt/pki/master下的同名子目录Key._check_minions_directories()方法正是将这四个常量与pki_dir拼接出实际的密钥存放路径minions_accepted os.path.join(self.pki_dir, self.ACC) minions_pre os.path.join(self.pki_dir, self.PEND) minions_rejected os.path.join(self.pki_dir, self.REJ) minions_denied os.path.join(self.pki_dir, self.DEN)关于状态转换文档特别强调要改变某个 minion 密钥的状态请使用-d删除该密钥然后重新接受或拒绝它。这是因为 Salt 的认证模型中一个 minion ID 在同一时刻只能对应一种密钥状态跨状态的直接转换并不被支持。通用选项控制运行方式与安全性salt-key的通用选项控制了命令的运行用户、交互方式、日志与输出行为选项说明-u USER, --userUSER指定运行 salt-key 的用户。源码中SaltKey.run()会调用check_user(self.config[user])校验该用户是否有权限操作密钥目录--hard-crash抛出原始异常而不是优雅退出默认值为 False对应HardCrashMixin-q, --quiet抑制输出。结合 salt/key.py 中的KeyCLI.run()可以看到quiet模式下发生SaltException时不会打印错误信息-y, --yes对所有提问回答 Yes默认值为 False--rotate-aes-keyROTATE_AES_KEY设为 False 可阻止 master 在删除或拒绝密钥时刷新密钥会话key session但这会降低删除/拒绝操作的安全性默认值为 True其中--rotate-aes-key值得重点关注当密钥被删除或拒绝后master 默认会轮换 AES 加密密钥使被移除的 minion 即使残留旧凭据也无法继续与 master 通信。若设置为 False虽然操作更快但已删除的密钥在旧会话有效期内可能仍被信任因此生产环境不建议关闭。日志相关选项遵循LogLevelMixIn的约定salt-key 的日志文件配置项名为key_logfile默认值取自 master 配置中的key_logfile在 conf/master 中默认为/var/log/salt/key默认日志级别为warning。此外还支持--output等输出格式选项OutputOptionsMixIn例如--outjson便于脚本化处理。动作选项密钥的查看、接受、拒绝与删除列出密钥-l, --list与-L, --list-allsalt-key -l all # 列出所有密钥等价于 -l un, -l rej, -l acc 的合集 salt-key -l unaccepted # 列出未接受/未签名密钥 salt-key -l accepted # 列出已接受/已签名密钥 salt-key -l rejected # 列出已拒绝密钥 salt-key -l denied # 列出被自动拒绝的密钥参数pre、un、unaccepted都用于列出未接受/未签名密钥acc、accepted列出已接受/已签名密钥rej、rejected列出已拒绝密钥den、denied列出自动拒绝密钥all列出全部密钥。-L, --list-all在文档中标记为已弃用Deprecated请改用--list all。源码解析器中的 help 文本同样注明 Deprecated: use --list all。此外解析器process_list()会对--list的参数做前置校验只允许acc、pre、un、rej、den、all开头的取值非法参数会直接报错退出。接受密钥-a, --accept与-A, --accept-allsalt-key -a minion1 # 接受指定密钥 salt-key -a minion* # 接受匹配通配符的密钥支持 glob salt-key -A # 接受所有待接受pending密钥--accept默认只匹配待接受pending密钥如需同时匹配已拒绝rejected密钥可结合--include-all即同时设置--include-rejected与--include-denied使用。源码解析器支持更细粒度的--include-rejected与--include-denied选项其中--include-all已被标注为弃用。拒绝密钥-r, --reject与-R, --reject-allsalt-key -r minion1 # 拒绝指定密钥 salt-key -r minion* # 拒绝匹配通配符的密钥支持 glob salt-key -R # 拒绝所有待接受密钥与接受操作对称--reject默认只匹配 pending 密钥可用--include-accepted和--include-denied扩展匹配范围。打印密钥内容-p, --print与-P, --print-allsalt-key -p minion1 # 打印指定公钥内容 salt-key -P # 打印所有公钥内容删除密钥-d, --delete与-D, --delete-allsalt-key -d minion1 # 删除指定密钥支持 glob salt-key -D # 删除所有密钥注意-D不接受任何额外参数源码 salt/cli/key.py 中明确检查delete_all时若有残留参数会抛出SaltInvocationError(Delete all takes no arguments...)这一点也被集成测试 tests/pytests/integration/cli/test_salt_key.py 的test_remove_all_keys_with_arg用例验证。指纹比对-f, --finger与-F, --finger-allsalt-key -f minion1 # 打印指定密钥的指纹 salt-key -F # 打印所有密钥的指纹指纹fingerprint是公钥的哈希摘要用于在无法建立可信信道的场景下通过电话、邮件等带外方式与 minion 侧输出的指纹进行人工比对确认密钥未被中间人篡改。交互确认与匹配的底层实现在执行accept、reject、delete这类有副作用的操作时KeyCLI.run()salt/key.py会先调用glob_match()做 glob 匹配将命中的密钥以key输出格式展示给用户然后默认弹出确认提示对delete操作提示Proceed? [N/y]默认不执行回车相当于n对accept/reject操作提示Proceed? [n/Y]默认执行回车相当于y。只有回答了y或使用-y/--yes跳过确认后才会真正调用对应的_run_cmd()执行。执行过程中若匹配不到任何密钥会输出形如The key glob ... does not match any ... keys.的提示。密钥生成选项生成密钥对与 master 签名salt-key还具备密钥生成能力属于SaltKeyOptionParser中的 Key Generation Options 选项组选项说明--gen-keysGEN_KEYS指定一个名称来生成用于 Salt 的密钥对--gen-keys-dirGEN_KEYS_DIR指定保存生成的密钥对的目录仅与--gen-keys配合使用默认为当前目录--keysizeKEYSIZE指定生成密钥的位数仅与--gen-keys配合使用密钥大小必须为 2048 或更高低于 2048 会被向上取整到 2048默认值为 2048--gen-signature创建 master 公钥的签名文件名为master_pubkey_signature。该签名可在 master 的 auth-reply 中发送给 minion使 minion 能够以密码学方式验证 master 的公钥这需要一对新的签名密钥对可通过--auto-create参数自动创建--privPRIV用于创建签名的私钥文件--signature-pathSIGNATURE_PATH签名文件的写入路径--pubPUB用于创建签名的公钥文件--auto-create若签名密钥对尚不存在则自动创建--keysize的实际校验逻辑在 salt/utils/parsers.py 的process_keysize()中小于 2048 报错、大于 32768 也报错即合法范围为[2048, 32768]。--gen-keys还会触发process_config_dir()的特殊分支当没有权限访问配置文件目录时会把配置目录直接指向生成密钥的目录以便在无 master 配置的环境下也能独立生成密钥对。从源码 salt/key.py 的gen_keys()方法可以看出密钥生成最终调用master_keys.find_or_create_keys(keyname, keysizekeysize, cachecache)即复用 master 的密钥生成逻辑而gen_keys_signature()则实现了签名流程默认公钥取pki_dir/master.pub默认私钥取pki_dir/master_sign.pem对应 master 配置中的master_sign_key_name若私钥不存在且开启了--auto-create则会强制重新生成签名密钥对并计算签名。在生成签名密钥对时如果 master 配置了signing_key_pass见 conf/master 中的# signing_key_pass: sdb://masterkeyring/signing_pass示例可以通过 sdb 引用保管私钥的 passphrase。与 master 配置的联动salt-key的行为与 master 配置文件conf/master中的多个参数直接相关pki_dir默认/etc/salt/pki/master所有 minion 密钥及 master 自身密钥的存放根目录四种状态的密钥分别存放在其下的minions/、minions_pre/、minions_rejected/、minions_denied/子目录中。auto_accept默认False设为 True 时 master 自动接受所有传入密钥通常仅用于测试环境生产环境保持关闭由管理员手动salt-key -a接受。key_logfile默认/var/log/salt/keysalt-key 自身的日志文件。keys.cache_driver如localfs_key、mmap_key密钥缓存驱动。从 salt/key.py 的list_keys()注释可以看到支持list_all的驱动mmap_key、localfs_key可以单次遍历密钥存储避免逐个探测性能更好。key_cache设为sched时master 会将已接受 minion 列表缓存到pki_dir/minions/.key_cache文件salt-key列出已接受密钥时可直接读取缓存避免大规模环境下全量扫描。preserve_minions/preserve_minion_cache--preserve-minions设为 True 时master 在删除密钥后不清理对应 minion 的缓存数据。源码check_minion_cache()默认会在密钥删除时清理grains、pillar等缓存 bank保留缓存可能带来安全隐患被删除的 minion ID 若被重新注册可能复用旧数据。另外在 Salt 集群cluster场景下Key类会使用cluster_pki_dir替代pki_dir定位密钥见 salt/key.py 的__init__这一点与 conf/master 中cluster_pki_dir的注释描述一致。两种运行模式本地直连与 eauth 认证从KeyCLI的源码可以看出salt-key支持两种执行路径本地模式默认未指定--eauth时直接在 master 本机调用Key对象的对应方法操作文件系统认证基于本地 master 密钥.root_key与check_user校验。eauth 远程模式指定--eauth如pam、ldap时通过salt.wheel.WheelClient将请求发送给 master 上的 wheel 模块key.accept、key.reject、key.delete等执行此时需要提供 eauth 凭据--username/--password或 token。集成测试 tests/pytests/integration/cli/test_salt_key.py 中的test_remove_key_eauth用例演示了通过 PAM 认证执行salt-key -d删除密钥的完整流程这为需要远程或权限分离管理密钥的场景提供了参考实现。实战示例完整管理一个 minion 密钥综合上述内容一个典型的密钥生命周期管理流程如下# 1. 查看当前所有密钥及其状态 salt-key -L # 2. minion 首次连接后查看待接受密钥 salt-key -l unaccepted # 3. 查看待接受密钥的指纹并通过带外方式与 minion 核对 salt-key -f minion-id # 4. 接受该 minion也可使用通配符批量接受 salt-key -a minion-id # 5. 确认已接受 salt-key -l accepted # 6. 如需移除该 minion例如重建 minion、更换密钥先删除再重新接受 salt-key -d minion-id -y # minion 重新提交新密钥后 salt-key -a minion-id # 7. 维护时也可手动拒绝可疑密钥 salt-key -r suspicious-minion-id # 8. 独立生成一对测试用密钥对无需 master 配置目录 salt-key --gen-keystestminion --gen-keys-dir/tmp/salt-test-keys --keysize2048当遇到minion 无法通信的排查场景时应首先使用salt-key -l all确认该 minion 密钥处于何种状态denied状态通常意味着 minion ID 重复或密钥被重建此时按文档建议删除旧密钥、让 minion 重新提交新密钥并接受即可恢复通信。小结salt-key虽是一个命令行工具但它承载着 Salt 安全体系的第一道关口——认证信任。理解四种密钥状态unaccepted / accepted / rejected / denied、熟练使用-l/-a/-r/-d/-p/-f等动作选项并掌握--rotate-aes-key、--gen-keys、--gen-signature等安全与生成类选项是每个 Salt 管理员的基本功。透过 salt/key.py 的Key/KeyCLI类与 salt/utils/parsers.py 的SaltKeyOptionParser我们可以清楚地看到状态即目录、动作即文件操作、确认机制保护操作安全这也为深入理解 Salt master 的认证流程打下了坚实基础。更多细节可参阅同目录下的 salt(7)、salt-master(1) 与 salt-minion(1) 手册页。【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址: https://gitcode.com/gh_mirrors/sa/salt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表