免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Cockpit 基于 SSH 公钥的多主机认证机制(pam_ssh_add 与 ssh-agent 实战解析)

Cockpit 基于 SSH 公钥的多主机认证机制(pam_ssh_add 与 ssh-agent 实战解析) 后端运维【免费下载链接】cockpitCockpit is a web-based graphical interface for servers.项目地址https://gitcode.com/gh_mirrors/co/cockpit点击查看免费下载Cockpit 允许你通过浏览器同时监控和管理多台服务器。虽然访问主服务器primary server通常需要密码或 Kerberos 票据但通过基于公钥的认证public key based authentication你可以无密码地访问辅助服务器secondary machine。本文将围绕 doc/key-auth.md 展开深入剖析 Cockpit 如何通过pam_ssh_addPAM 模块启动 ssh-agent、自动加载 SSH 密钥并结合源码与配置说明其完整流程、权限语义及安全边界读完你就能理解 Cockpit 多主机连接时登录一次、密钥随行的原理并学会查看与调整相关 PAM 配置。适用场景主服务器 辅助服务器Cockpit 的会话模型始终存在一个主服务器浏览器直接连接的、运行 Cockpit Web 服务cockpit-ws的机器。主服务器完成认证后用户可以从 Shell 界面的主机切换host switching功能连接其他服务器或者在登录页的 Connect to 字段中直接指定目标服务器不建立主会话。这两种方式下对辅助服务器的访问均通过 SSH 完成。因此基于密钥的认证解决的是从主服务器无密码 SSH 到辅助服务器这一核心问题主服务器侧的登录依然需要密码或 Kerberos 票据而辅助服务器侧的登录则完全依赖公钥。这一设计参考 doc/modules/guide/pages/authentication.adoc 中 Logging into a secondary server from the primary session 一节其命令行等价物就是先登录主服务器再ssh usersecondary。无密码认证带来的权限语义限制一个重要且容易被忽略的事实是以密钥认证方式登录的用户其认证过程不经过密码。这意味着Cockpit 标准的 reauthorization重新授权机制无法生效——用户无法通过再次输入密码来临时提升权限用户只能获得那些不需要密码的额外特权例如已配置为 NOPASSWD 的 sudo 规则或对 polkit 中无需认证即放行的动作。从源码结构看这一限制是设计使然密钥认证把密码这个高价值凭据完全排除在辅助服务器的认证链路之外系统只能依据既有授权规则无密码可用的授权来决定权限提升。在规划多主机管理策略时应对辅助服务器上无需密码的特权授予范围格外谨慎。完整工作流程登录 → ssh-agent → ssh-add → SSH 连接根据 doc/key-auth.md 的叙述密钥认证的整体流程如下为支持密钥认证Cockpit 在自己的 PAM 栈中加入pam_ssh_add.so用户在主服务器成功登录后立即启动一个新的ssh-agent随后执行ssh-add加载默认路径下的密钥即~/.ssh/下的默认私钥——ssh-add不带任何参数若加载的密钥被口令passphrase保护ssh-add会提示输入口令此时会自动填入用户登录主服务器时使用的密码当 Cockpit 尝试向某台新服务器建立 SSH 连接时运行中的ssh-agent会把已加载的公钥提供给远端服务器作为认证选项用户登出或会话被终止时对应的ssh-agent进程也会被同步终止避免密钥常驻系统。这条链路中ssh-agent 随会话生灭的设计保证了密钥不会在用户会话结束后仍然留在内存或 socket 中与常规交互式 SSH 环境中手动启动 agent 的做法相比更贴合 Web 会话的生命周期。源码级解析pam_ssh_add 的认证与会话模块pam_ssh_add是这一机制的核心实现源码位于 src/pam-ssh-add/pam-ssh-add.c 和 src/pam-ssh-add/pam-ssh-add.h对应的 man page 为 doc/modules/man/pages/pam_ssh_add.8.adoc。它提供两个 PAM 模块authentication 模块和 session 模块。Authentication 模块只存密码不做认证pam_sm_authenticate()的职责非常特殊它从 PAM 项中取出PAM_AUTHTOK即用户登录密码通过stash_password_for_session()用pam_set_data()存入会话数据键名为pam_ssh_add_authtok供后续 session 阶段使用它不执行任何实际认证而是返回PAM_CRED_INSUFFICIENT。man page 对此明确说明因为该模块本身不做认证所以在 PAM 配置中它必须与一个真正的认证模块如pam_unix.so搭配使用且通常标记为optional。返回PAM_CRED_INSUFFICIENT表示凭据信息不足、需要其它模块继续处理这恰好让真正负责认证的模块接管后续流程。Session 模块启动 agent 并加载密钥pam_sm_open_session()依次完成两步start_agent()以登录用户的身份启动ssh-agent解析其输出中的SSH_AUTH_SOCK与SSH_AGENT_PID两个环境变量源码中的agent_vars[]表写入 PAM 环境并记录 agent PID 与用户 UID 供登出时清理load_keys()读取之前暂存的密码调用pam_ssh_add_load()执行ssh-add。pam_ssh_add_load()的实现细节值得关注通过管道与ssh-add子进程交互读取其 stderr检测到输出包含 Enter passphrase 时把暂存的登录密码写入 stdinsrc/pam-ssh-add/pam-ssh-add.c检测到 Bad passphrase口令错误时只发送换行跳过该密钥并继续ssh-add以EXIT_STATUS 1退出时部分密钥加载失败模块并不视为致命错误而是记录 Failed adding some keys 后继续保证登录流程不被密钥问题阻断。子进程启动时通过setup_child()完成setuid/setgid降权、setsid()脱离终端、关闭多余文件描述符等加固步骤确保ssh-agent/ssh-add始终以目标用户身份运行src/pam-ssh-add/pam-ssh-add.c。登出清理session close 杀掉 agentpam_sm_close_session()在会话结束时执行清理先降权到该 agent 所属用户再向记录的SSH_AGENT_PID发送SIGTERM随后恢复 root 权限。源码注释表明以用户身份 kill 是为了防止误杀崩溃的 ssh-agent 以及 PID 重用带来的风险src/pam-ssh-add/pam-ssh-add.c。这与 doc/key-auth.md 所述用户登出或会话终止时 ssh-agent 同步终止完全对应。PAM 配置从示例到 Cockpit 实际栈man page doc/modules/man/pages/pam_ssh_add.8.adoc 给出了一个最小示例auth required pam_unix.so auth optional pam_ssh_add.so session optional pam_ssh_add.so注意示例中pam_ssh_add.so两处均为optional且前面必须有真正的认证模块。Cockpit 自身的 PAM 栈tools/cockpit.pam展示了它的真实落地方式auth required pam_sepermit.so auth substack password-auth auth include postlogin auth optional pam_ssh_add.so # List of users to deny access to Cockpit, by default root is included. account required pam_listfile.so itemuser sensedeny file/etc/cockpit/disallowed-users onerrsucceed account required pam_nologin.so account include password-auth password include password-auth session required pam_selinux.so close session required pam_loginuid.so session required pam_selinux.so open env_params session optional pam_keyinit.so force revoke session optional pam_ssh_add.so session include password-auth session include postlogin关键点解读pam_ssh_add.so在 auth 段中作为最后一个 optional 模块出现此时password-auth等真正的认证模块已完成密码校验pam_ssh_add只需顺势捕获PAM_AUTHTOK暂存session 段中pam_ssh_add.so置于pam_selinux.so open之后、pam_keyinit.so附近保证在用户会话环境建立的同时启动 agent该文件还展示了 Cockpit 的访问控制pam_listfile.so结合/etc/cockpit/disallowed-users拒绝特定用户默认包含 root。若你在部署中自行调整 PAM 栈务必保持真正认证模块在前、pam_ssh_add.so为 optional的顺序否则登录流程会出问题。该模块支持的唯一参数是debug开启后会将详细日志通过 syslogLOG_AUTHPRIV输出便于排查 agent 启动或密钥加载失败问题。模块构建方式见 src/pam-ssh-add/Makefile.am其单元测试使用 src/pam-ssh-add/mock-ssh-agent、src/pam-ssh-add/mock-ssh-add 等 mock 程序模拟 agent 与ssh-add行为。前端配合密钥的查看、创建与授权密钥认证不是纯后端机制Cockpit 的用户界面也提供了配套操作。在用户账户页面pkg/users模块中pkg/users/authorized-keys-panel.jsx 提供Authorized keys面板支持粘贴公钥内容并添加到~/.ssh/authorized_keysAdd public key 对话框pkg/users/authorized-keys-panel.jsx也支持删除已有密钥。底层封装在 pkg/users/authorized-keys.js它调用 pkg/users/ssh-list-public-keys.sh 读取并解析authorized_keys内容用正则^(\S)\s(\S)\s(.*)\((\S)\)$解析出密钥大小如 2048、指纹SHA256:...、注释与算法类型如 RSA通过 pkg/users/ssh-add-public-key.sh 将公钥追加写入~/.ssh/authorized_keys对密钥文件缺失、权限不足access-denied等场景都有明确的状态处理。这正好对应 doc/modules/guide/pages/authentication.adoc 中目标服务器需启用公钥认证且公钥必须存在于~/.ssh/authorized_keysCockpit 提供创建 SSH 密钥并授权的界面的描述。此外Cockpit 还提供界面将无法自动加载的密钥手动加入 agent即登录后补充ssh-add能力解决密钥不在默认路径或需要手动选择的场景。SSH 主机密钥host key与 known_hosts除了用户公钥SSH 主机密钥校验也属于密钥认证链路的一部分当 Cockpit 连接到一台未知的新服务器时会提示用户确认其 SSH host key用户确认后主机密钥会被写入~/.ssh/known_hosts后续连接不再重复提示见 doc/modules/guide/pages/authentication.adoc 的 SSH host keys 一节。这与命令行 SSH 的首次连接确认体验一致是对本主题在操作层面的自然补充。安全边界与建议信任边界从主会话切换主机时远端机器的 Cockpit 页面JavaScript会在主服务器上执行因此只应连接你信任的机器该多主机功能在部分发行版上默认关闭可通过cockpit.conf的AllowMultiHost选项启用。权限最小化由于密钥认证免密码reauthorization 机制失效应审查辅助服务器上免密 sudo/polkit 授权的范围避免权限面过大。密钥生命周期ssh-agent 随 Cockpit 会话启动与销毁登出即终止勿在系统层面为 Cockpit 用户单独常驻 agent以免绕过这一生命周期约束。口令保护私钥若有 passphrase加载时会复用登录密码若登录方式为 Kerberos 或证书等无密码形式pam_ssh_add将无法获得密码带口令的密钥则无法自动加载可通过界面手动加入 agent。延伸阅读认证总览doc/authentication.md、doc/modules/guide/pages/authentication.adocPAM 模块手册页doc/modules/man/pages/pam_ssh_add.8.adoc核心实现src/pam-ssh-add/pam-ssh-add.c、src/pam-ssh-add/pam-ssh-add.h实际 PAM 栈tools/cockpit.pam、tools/cockpit.suse.pam前端密钥管理pkg/users/authorized-keys.js、pkg/users/authorized-keys-panel.jsx赞分享后端运维【免费下载链接】cockpitCockpit is a web-based graphical interface for servers.项目地址https://gitcode.com/gh_mirrors/co/cockpit点击查看免费下载相关推荐Steam 四平台饰品价格监控实测从克隆到出数据的完整流程Steam 四平台饰品价格监控实测从克隆到出数据的完整流程 打开页面最先看到的是一个数字0.876当前挂刀指数——这个 Steam 饰品价格监控站一行后端网页爬虫libcurl CURLOPT_SSH_KNOWNHOSTS 详解基于 known_hosts 文件的 SSH 主机密钥校验libcurl CURLOPT_SSH_KNOWNHOSTS 详解基于 known_hosts 文件的 SSH 主机密钥校验 CURLOPT_SSH_KNOWCLI网络通信gliderlabs/ssh认证机制全解析密码、公钥、键盘交互三合一终极指南gliderlabs/ssh认证机制全解析密码、公钥、键盘交互三合一终极指南 想要快速构建功能强大的Go语言SSH服务器吗gliderlabs/ssh提供了网络通信认证鉴权创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表