中文 | English
linux-temp-admin 创建可通过 SSH 登录的 Linux 账号,并可授予 NOPASSWD sudo。本文件说明它提供的安全保证、明确不解决的问题和失败时的处理方式。漏洞报告方式见 SECURITY.md。
本工具假定以下基础仍可信:
- Linux 内核、本地 root、文件系统和系统账号数据库;
- OpenSSH、sudo、systemd 或
at及系统账号管理命令; - 邮件投递服务,以及被管理员允许修改受信系统邮箱目录项的本地身份;
- 安装时明确选择的下载信任链;
- 操作者用于交付邀请的私密通信渠道。
它重点防止自身造成的命令注入、路径穿越、符号链接覆盖、TOCTOU、误删账号、UID/PID 复用误判、不完整回滚、残留用户名授权和未验签升级。
已经取得 root 的攻击者可以修改程序、内核、账号数据库、审计日志或登记状态,本工具不能在同一主机上对抗 root。底层操作系统、OpenSSH、sudo、包管理器的漏洞也不由本工具修复。
- 默认生成 SSH key;私钥只在成功创建后输出一次,服务器不保存;
- stdout 不是 TTY 时默认拒绝输出私钥或密码,必须显式使用
--allow-non-tty-private-key-output; - 邀请包本身就是秘密,只能通过可信私聊交付;
--password-login会生成只显示一次的随机密码,但密码可在账号有效期内被网络暴力尝试,是较弱的授权方式;- 公钥账号使用不会匹配有效密码、也不会触发 Alpine/OpenSSH 整账号锁定判断的 shadow 值禁用密码认证。
--sudo 写入账号专属 NOPASSWD sudoers,基本等同完整 root 权限。可信协作者取得 root 后可以创建 cron、systemd unit、SUID 文件、新账号或其他持久化。撤销会删除本工具管理的账号、授权和自动撤销任务;为防止用户名/UID 复用继承延迟工作,还会删除目标账号的个人 crontab 以及该 UID 的全部 at/batch 任务。它不会猜测或清理对方以 root 创建的系统级 cron、systemd unit、SUID 文件、新账号或其他外部对象。
因此“临时账号”限制的是本工具管理的入口寿命,不是 root 行为的沙箱。不要把 sudo 邀请发给不可信对象。
创建前会运行等价于 sshd -T -C user=<新账号> 的有效配置兼容性检查,展开 Include、Match 和发行版加密策略。只有检查未发现已知阻碍或无法判断的规则时,邀请才会显示“已对照 sshd 有效配置验证”;无法完整判断时显示 UNVERIFIED,未解决的配置检查阻碍则会拒绝创建。
这个结论只说明计划凭据与检查到的 sshd 有效配置兼容,不是端到端 SSH 登录测试,也不能证明网络、防火墙、PAM、SELinux 或运行中 sshd 进程的全部状态。交付邀请前仍应按实际连接路径测试登录。
未来账号在创建前尚无 NSS 用户组,OpenSSH 因此无法可靠求值 Match Group。若检查未发现其他已知阻碍、唯一的不确定项是未来用户组,工具才会先创建没有密码或公钥凭据的待定账号,再按真实用户组重新运行有效配置检查;只有后置检查通过后才写入凭据。已知阻碍仍按正常拒绝或显式修复流程处理,不会被延后判断掩盖。依赖来源地址、目标端口等连接属性的 Match 仍无法由用户组消除:公钥邀请会明确显示 UNVERIFIED,密码邀请则失败关闭。
--fix-sshd 只写账号作用域 drop-in,并以 Match all 恢复后续配置作用域。写入前后分别通过 sshd -t 和有效配置检查;能找到运行中的 sshd 时只请求 reload、不会 restart。若没有可通知的运行中 daemon,配置文件会保留供 socket 激活或下次启动读取,但邀请标记为 UNVERIFIED。其他授权失败会尝试删除文件并回滚;删除或恢复 reload 本身失败时会返回非零,并按下文的不完整回滚规则保留恢复见证。显式 DenyUsers 和 DenyGroups 不会被绕过。
每个新邀请都绑定:
- 在
useradd前持久化烧号并显式指定的同号 UID/GID; - 随机 128 位世代标识;
- 前四个 GECOS 子字段初始为空,并在第五个 trailing/other 字段写入精确的紧凑世代见证;
- 登记表中的对应记录。
自动撤销和普通 revoke 要求这些身份信息一致。以 <32hex> 表示 32 位小写十六进制世代,当前完成态和 pending 创建态的完整 GECOS 分别为 ,,,,lta-m=<32hex> 和 ,,,,lta-p=<32hex>。首字段特意不再写旧版完整标记,使不认识新格式的旧二进制失败关闭。受支持的 shadow/util-linux chfn 即使允许普通用户修改 full-name、room 或 phone,也没有覆盖第五字段的普通用户入口。撤销因此允许首四个 GECOS 子字段和非空 shell 在事务期间变化,但用户名、UID、GID、Home、第五字段见证和登记必须保持精确一致。账号被删除重建、UID 被复用、稳定字段或见证改变、登记损坏时会拒绝自动删除,而不是猜测同名账号仍是原对象;能够直接改写账号数据库或程序状态的本机 root 仍属于信任边界。
登记表旁的 root-only 高水位文件在每次 useradd 前先原子前进;即使后续创建或回滚失败,这个 UID/GID 也不会再由本工具分配。候选值高于当前本地 passwd/group 中普通账号范围内的全部 UID/GID,并限制在 login.defs 的 UID/GID 重叠范围内(/etc/login.defs 确认不存在时使用与 shadow 相同的内置 1000..60000 范围,因为 useradd 自身在这种主机上也退回编译期默认值;文件存在却无法读取、超限或不是普通文件仍然失败关闭,因为它可能正藏着一个更窄的配置范围);useradd -U -u ID -K GID_MIN=ID -K GID_MAX=ID 把账号和私有组固定为同一号码,返回后再核对完整 passwd 身份。v5 登记已经存在但高水位文件丢失或损坏时会失败关闭,不会根据现存账号重建并冒险复用已退休身份。这一保证只覆盖本工具、完整保留的状态目录和本地账号数据库;不可枚举的外部 NSS、另一个本机 root 手工指定号码或人工删除状态目录仍在信任边界内,不能表述为全系统绝对不复用。
账号数据库项使用 useradd -M -e 1970-01-01 -p '!' 创建,因此从出现起就处于过去日期过期且密码锁定的状态,并且不会复制可能含有本机认证材料的 /etc/skel。默认自动生成的用户名具有长随机后缀,并与从未由本工具复用的 UID/GID 配对;程序在账号仍无凭据、无 Home 且保持过期时执行两轮进程终止和 cron/at 清理,不再等待 65 秒。显式 --user 可能重用历史名称及 daemon 已缓存的同名任务,因此仍会清场、等待完整轮询周期并再次清场。只有复查和完整身份核对通过后,程序才通过固定 /home 目录描述符创建权限为 0700 的空 Home 并设置其属主。准备期间账号一直保持过去日期过期;密码或公钥、sshd/sudo 策略、登记和自动撤销任务均完成后,最后一次 chage 才写入请求的到期日或永久值并激活登录。
程序会在关键事务阶段重复核对 passwd 身份。邀请的正向创建阶段仍要求 useradd 后捕获的完整 passwd 快照逐字节不变,包括清理旧邮件、创建 Home、pending 转 managed、核对真实用户组和安装凭据前的检查;最终登录激活 helper 调用前发生的失败也按该完整快照回滚。激活 helper 一旦开始,程序就按“可能已经生效后才报错”处理;此后的失败回滚与普通撤销、删除一样,对当前第五字段见证账号要求用户名、UID、GID、Home 和精确的 lta-m=/lta-p= 世代见证不变,同时允许普通用户可并发修改的首四个 GECOS 子字段及非空 shell 变化,避免可能已登录的邀请对象用 chfn/chsh 循环阻断清权或终删。旧单首字段账号没有独立见证,在这些路径中仍要求完整 passwd 快照不变。完成 GECOS 身份标记和账号删除的路径还会在按用户名操作的 helper 返回后复核,以发现可观察到的同名替换。这些复核不能把 helper 变成原子的比较并交换。能够并发改写账号数据库的本机 root 仍属于信任边界。账号删除只调用不带 -r/-f 的 userdel --,不执行会读取 /etc/deluser.conf 并可能重新递归清理的发行版 deluser,也不接受编译期账号数据库语义不明的任意 BusyBox applet;shadow-utils 的 -f 还可能删除仍被其他账号用作主组的同名组,因此也被拒绝。
登记中的 SequentialID 证明本工具曾用同一个单调预留号码创建 UID 和私有 GID,只有该见证才授权账号消失后继续处理同名组。受控 Home/mail 清理前,程序会有界解析本地 group、passwd 以及存在时的 gshadow 数据库,要求同名组仍存在且 GID 精确匹配、/etc/group 密码字段明确禁用(x、* 或 ! 前缀)、gshadow 没有可用组密码、显式成员或管理员、没有其他本地账号把该 GID 用作主组,也没有其他本地组复用该 GID。空的 /etc/group 密码字段不是受信任的显式锁定占位符,而且不同账号工具对其语义说明并不一致,因此程序失败关闭。普通 userdel -- 后若这个已证明的组仍存在,程序还会通过本地 passwd 与 NSS 确认没有同名身份,才调用 groupdel --;随后重新检查账号和组都保持消失,groupdel 的报错不会仅凭最终缺失状态被隐藏。程序还会验证 /etc/subuid 与 /etc/subgid 中没有同名分配,但不会自行猜测并删除残留范围。数据库损坏、冲突或残留都失败关闭并保留恢复登记;账号已经消失时,旧版或非顺序登记不能把记录的 UID 猜成 GID,也不能授权删除同名组。
v2.9.3 及更早版本创建的世代绑定账号只有首字段标记。升级不会由 status 或 doctor 隐式改写 /etc/passwd:标记尚精确时仍按旧规则正常撤销,并显示 generation-bound-first-field-compat/诊断警告;应尽快撤销后用当前版本重新邀请。若旧账号此前已修改 full-name 并丢失这个唯一见证,程序无法在不冒同名/同 UID 替代账号误删风险的前提下自动认回,仍会保持 protected 并要求人工核查。
从旧登记格式迁移的固定标记账号显示为 legacy-unverified,不会被定时、批量清理或卸载自动删除。旧版 timer 使用的 --yes --force --confirm-force 不能获得这类账号的删除授权;当 UID/世代与未绑定登记精确匹配时,任务只能移除本工具的 sudoers/sshd 授权并取消自身,不能读取 passwd 删除策略、禁用或删除账号、修改登记。授权未全部移除时不主动取消任务,使 systemd 可按策略重试;已触发的 at 和旧一次性任务仍需人工处理。取消失败也返回非零,账号和登记始终保留。其他遗留任务会被报告为孤儿任务,并可由 linux-temp-admin cleanup-expired --compact 取消而不删除活账号或登记。人工核对后,必须在交互终端运行 linux-temp-admin revoke --force 并输入完整用户名确认。对于仍缺少 UID 列的 9 列 v2 登记,只有当前 UID 不低于 1000 且精确固定标记仍存在时,人工确认才补足恢复授权;清权前必须先通过正式 Init 迁移为 v5、创建 identity-sequence,并复核登记语义和完整 passwd 快照。迁移或复核失败时不清权、不禁用也不删除账号。非交互调用、低 UID、UID 0、保留名称及标记不匹配始终拒绝删除。
v2.9.2 之前的版本可能在 useradd 已成功、后续准备失败时留下仍活着的 pending 创建登记。这种登记本身不提供普通或无人值守删除权限;只有管理员人工核查后,在菜单选择该行或直接交互运行 linux-temp-admin revoke --user <名> --force 并输入完整用户名,才会进入恢复候选。程序还要求登记中的随机世代精确匹配 pending GECOS、登记 UID 为尚未写入的 0 或与当前 UID 一致、Home 为确定的受管路径、UID/GID 均为非 root 且 shell 非空。systemd 可用时会保留精确 pending 世代进入持久隔离;同步回退才在清理前把它降为不带世代的 UID-only DeletionStarted 见证。--yes、自动任务、卸载批量、非 TTY 及任何不匹配状态始终失败关闭并保留账号和登记。
root、UID 0 和保留名称始终不会删除。低 UID 账号只有在当前登记名称、UID/GID、确定的 Home、随机世代与兼容格式的精确 GECOS 世代见证完整绑定时,才能作为本工具创建的账号撤销;当前格式要求第五字段的 lta-m= 见证,v2.9.3 及更早的世代绑定账号只接受仍精确存在的旧首字段见证。未登记或旧身份格式的低 UID 账号即使使用 --force 也受保护。没有本工具精确见证的真实账号同样不会作为受管账号删除。
GECOS 标记回答两个方向相反的问题,程序因此使用两条不同的规则。阻断方向(卸载清单、doctor 报告)尽量宽松地识别标记:多认出一个账号只会让工作停下来。删除授权方向(未登记账号 + --force)要求标记处于权威位置:第五字段一旦带有任何值就以它为准,用户可写的 full-name 副本不能重新建立一个被第五字段否定的世代证据。因此形如“首字段是合法世代标记、第五字段却是别的内容”的账号可以阻断卸载,但不会因此获得删除授权。
个人 crontab 和 at/batch 任务不会因禁用登录、杀掉当前进程或普通 userdel -- 而可靠消失。新账号在获取密码、公钥或 sudo 授权前,以及旧账号释放用户名/UID 前,都会删除并复核同名个人 crontab,通过 atq 和 at -c 生成的 atrun uid= 头盘点全部任务,并删除目标 UID 的任务。每次调用 atrm 前都会重新读取同一 ID,并再次绑定预期 UID 或本工具的精确撤销命令;删除失败后也会复核目标是否仍存在或 ID 是否已被复用。本工具自己的自动撤销作业只在 atrun 头表明其属于 root 时才被识别;程序先在 64 KiB 上限内读取 owner 头,因此已确定属于非 root 的超大作业不会阻断自动任务清单,而 root 作业才会在更大的有界范围内读取完整正文。外部 at 接口没有原子的比较删除操作,所以重新读取到 atrm 之间仍有极短窗口;能在该窗口替换作业的本机 root 属于信任边界。部分安装的 at 工具、损坏/过大的队列输出、无法解析的所有者或存活文件都会 fail closed。
直接 spool 复核明确支持的 cron 目录是 /var/spool/cron/crontabs、/var/spool/cron 和 /var/spool/cron/tabs;at 目录是 /var/spool/cron/atjobs、/var/spool/at 和 /var/spool/atjobs。未使用这些常规布局的实现不在这项文件级复核范围内。新建的默认随机账号使用不会被本工具复用的 UID/GID,因而两轮即时清场之间无需释放身份或等待 daemon 轮询。显式复用用户名、无持久 systemd 的撤销回退和卸载终删仍同步保持禁用身份至少 65 秒;若进程清单无法可靠扫描,也会保守等待或保留账号,而不是跳过窗口。
正常 systemd 撤销不会在前台等待:它先删除并确认 sudo/sshd 授权,禁用账号登录,执行两轮进程终止与 cron/at 清理,再创建独立命名空间的持久化 quarantine timer,并把截止时间和 unit 原子登记为删除恢复状态。正常路径只在 timer 已启用且登记已确认持久化后报告访问已撤销。若登记 rename 已可见但其目录 sync 未能确认,程序只有在完整隔离行精确读回匹配时才保留 timer 和该行、报告撤权成功并显式警告持久性未知;若无法证明精确状态,则返回非零并保留 timer 与登记证据供人工恢复。此时 passwd 项继续占用用户名、UID 和 GID,账号过期锁定且无受管提权入口。截止时间按“当前时间加 65 秒”向上取整到整分钟,因此实际隔离至少 65 秒、不到 125 秒;到期服务再次复核身份、任务和进程后才清理 Home/mail 并运行 userdel。Persistent=true 让关机跨过截止时间后仍会补跑。timer 丢失或正文不匹配会由 doctor 单独报告,登记不会被 compact 丢弃。
撤销账号前会逐个检查该 UID 线程组中的所有存活线程;主线程已经是 zombie 但工作线程仍在运行的线程组不会被当成空进程。Linux pidfd 把信号绑定到检查过的线程组实例,避免 PID 复用后误杀无关进程,且打开 pidfd 后还会再次核对线程凭据。每轮 SIGKILL 后都会重新扫描该 UID,只有连续两次稳定的逐线程复扫都观察不到存活进程才会继续删除账号;任一 TGID/TID 在读取前消失会重置确认,扫描不可靠或达到有界重试次数都会 fail closed。Linux 5.3、pidfd_open 和 pidfd_send_signal 是安全撤销所需能力;doctor 会实测,invite 在能力不可用时拒绝创建账号。
/proc、pidfd、cron 和 at 检查是使用同一生命周期锁的重复有界快照,不是内核级原子冻结。它们会大幅缩小竞态窗口并在观察不可靠时保留禁用账号,但无法屏蔽不经该锁操作账号数据库或调度器的本机 root;后者仍在信任边界内。具有 sudo 的协作者另行创建的系统级 cron、systemd unit 或其他 root 持久化也不属于个人任务清理范围。
invite、revoke、cleanup、install、upgrade 和 uninstall 的受管状态提交共用 root 生命周期锁,账号、授权、登记、任务和二进制变更不会互相穿插。需要人工等待的确认、依赖安装、下载和验签尽量在锁外完成;取得锁后会重新核验即将提交的状态。
同名 invite 另持独占账号屏障,当前撤销持共享侧屏障。兼容旧任务的不带 UID/世代 linux-temp-admin revoke --yes 若发现独占屏障已被同名创建占用,会不作删除并以成功状态跳过,防止旧 systemd 任务在创建结束后重试并命中新世代;人工发出的同形非交互命令也会被跳过,必须在并发操作完成后运行 linux-temp-admin doctor 并重新撤销。这是安全优先的迁移边界,而不是已经删除账号的证明。已经载入、且在新版屏障生效前开始等待全局锁的旧二进制无法由新版进程锁完全追溯;创建流程还会扫描精确的 root-owned 旧撤销进程并拒绝用户名复用,但系统 helper 和 /proc 观察仍不是原子 compare-and-swap,本机 root 保持在信任边界内。
登记格式 v5 保存单调身份标志、quarantine 截止时间和独立终删 unit。正常 systemd 撤销在立即撤权后写入带精确 UID/世代的 DeletionStarted 隔离状态;传统同步路径则在受控的 mail/Home 清理和 userdel 之前写入删除见证。首次 Home 清理后、userdel 前还会再次复核任务、进程和稳定身份;旧单首字段账号则复核完整 passwd 快照。最终静默检查返回后,程序会重新确认 passwd 仍绑定同一身份,并再次按该 UID/GID 清理可能刚重建的 Home,然后才调用 userdel。精确世代账号保留 UID 与世代绑定;旧版、未登记及同步 pending 回滚只保留 UID 见证,避免一次已经授权的删除在账号消失后失去 mail spool 清扫依据,同时不把不完整身份变成无人值守删除权限。删除后的恢复允许核对 UID 所有者的常规 mail spool 清扫;仅有 SequentialID 见证才能授权清理经完整数据库形状检查证明的同名私有组。subuid/subgid 残留会失败关闭并保留恢复行,程序不会猜测删除范围,也不会按缺失账号的旧 Home 路径递归删除;每轮恢复前后还会同时确认本地 passwd 与 NSS 中没有同名身份。恢复行不能由普通登记更新、删除或 compact 覆盖,同名创建也必须等待恢复完成。活着的 UID-only 或世代不匹配账号只允许交互式 --force 人工恢复;旧自动任务会作为失效任务解除,避免无权完成恢复的无人值守命令持续重试。
创建失败会运行回滚栈,清理任务、sudoers、sshd 例外、登记和仍能确认身份的新账号。最终登录激活 helper 调用前要求创建时完整 passwd 快照;helper 一旦开始则因其可能已生效而改用上述第五字段稳定身份,防止可能已登录的账号持有者阻断回滚。旧单首字段身份始终要求完整 passwd 快照。若半创建账号的身份、授权清理或递归 Home 清理无法确认,工具会保留账号及登记供人工恢复,而不会按用户名猜测删除。任何回滚不完整都会明确报告并返回非零,不会把部分成功显示为成功。
新账号取得的 UID 若已有残留进程,或 /proc 扫描无法给出可靠结论,工具会保留没有密码或公钥凭据、已经过期且密码锁定、尚未创建 Home 的 pending 账号来占住该 UID,并保留登记供人工恢复;此时不会删除账号后立即把同一 UID 暴露给下一次分配。
撤销时如果用户名授权无法完全移除,会保留并尝试禁用账号,避免残留授权在用户名复用后重新生效。操作者应把任何回滚或撤销错误视为未解决的安全事件。
- 登记表、偏好和审计目录要求 root 所有及严格权限;
- 登记表严格验证 schema、字段、UID、世代、隔离状态和大小;单调 UID/GID 高水位文件也要求 root 所有、
0600、固定格式且与 v5 登记同时存在,其值不得低于仍存登记中的任何 UID,缺失、过低、损坏或不可读时 fail closed。v2/v3/v4 登记只有在序列先持久化后才能由变更发布成 v5;UID-only 删除也先推进序列再写入首次退休见证; - 安装、升级和状态写入使用同目录临时文件、元数据验证、原子替换和必要的 fsync;
- 新账号只能使用创建前不存在的确定路径
/home/<用户名>;/home必须由 root 管理,创建后的真实目录必须属于目标非 root UID/GID。撤销会在账号稳定身份仍可核对时清理该目录;旧单首字段账号仍要求完整 passwd 快照。Home 递归删除使用目录描述符;Home 根若为符号链接、属主不符或跨越活跃挂载边界会被拒绝,内部符号链接只删除链接本身而不跟随目标。遍历会在文件系统调用之间检查 100,000 个条目、128 层和两分钟的协作式预算,单次阻塞的文件系统调用不能由该期限中断; - 常规邮件清理只检查
/var/mail/<用户名>与/var/spool/mail/<用户名>这两个传统单文件 mbox 位置,允许二者互为符号链接,但解析结果不得逃出这两个目录。存在的系统邮箱目录必须是 root 所有的真实目录、不得带 setuid;若为 world-writable,则必须带 sticky bit。因而常见root:mail 2775/0775、现场root:mail 3777和 Arch Linuxroot:root 1777均可接受,而无 sticky 的0777/2777、包括mail:mail在内的非 root 属主及任何 setuid 目录都会失败关闭。目标 mailbox 必须是非符号链接普通文件且 UID 与捕获身份一致;删除并 fsync 父目录后还会复核它没有重建; - 创建会在
useradd前预检系统邮箱目录,并在账号已绑定具体 UID、仍过期锁定且没有凭据或 Home 时重新打开目录做同一校验与旧 mbox 清理。前置失败不会创建账号;若目录在 helper 之后变得不安全,流程会按上述激活边界使用已捕获的完整快照或第五字段稳定身份尝试回滚,不能确认清理时保留禁用账号和登记见证。邮件专用逻辑不搜索或遍历 Maildir,也不触碰宝塔/www/vmail;完整账号撤销时,位于受管 Home 内的 Maildir 仍随 Home 按上述规则清理; - sudoers、sshd 例外和自动任务使用受限、可预测的项目命名,只删除经过身份验证的受管对象。
不要手工编辑 /var/lib/linux-temp-admin/v2/registry.tsv。读不到登记状态不会被当作“没有账号”。
丢失序列的恢复是一个窄边界,而不是从现存状态自动重建历史。linux-temp-admin recover-identity-sequence --highest <N> 只接受格式有效且序列对象确实不存在的 v5 登记;它不会覆盖任何已有对象,也不修复损坏、不安全或过低的序列。root 操作者必须从可信历史独立确定本工具曾预留的最高 UID/GID,因为已删除账号和失败创建烧掉的号码无法由现存 passwd/group 或登记推导。命令要求真实 TTY 和逐字确认,先核对登记及本机观测下限,再在全局生命周期锁内重新规划;状态变化、卸载标记或 no-replace 竞争都会失败关闭。成功文件为 root:root、0600,目录项经过 fsync 和精确回读,并设置一次完整任务轮询周期的 safe-after,使下一次自动用户名创建在此窗口内仍执行同步任务清场。成功及锁内失败会记录 registry.identity-sequence.recover 审计事件。
默认随机用户名的邀请在即时任务清场后计算有效期,不再经历 65 秒前台等待;显式 --user 的同步名称复用防护完成后才计算有效期,所以安全等待不会缩短名义访问时长。目标只转换一次为向上取整到整分钟的绝对截止时间,取整最多多不到一分钟。邀请显示、chage -E 兜底日期、systemd timer 和 at 都由这一目标生成;at 使用绝对 UTC 分钟,不会因夏令时跳变而提前撤销。chage -E 仍只是更晚、按天粒度的锁定兜底。systemd 不可用,或其排程失败且任务已安全回滚时,才尝试 at;任一后端都无法成功排程,或者排程前截止时间已到时,邀请创建会回滚。调度器忙碌、主机停机和撤销重试都可能让实际删除延后,因此不再需要的访问应手动立即撤销。
撤销任务再次验证用户名、UID/GID、Home、精确的第五字段世代见证和登记行;当前格式账号的用户可写 GECOS/shell 字段不参与稳定身份比较,旧单首字段账号则保守核对完整 passwd 快照。身份不匹配、登记丢失或账号已重建时会安全跳过,交由管理员检查。systemd 撤销失败会限速重试;一次性后端失败需要 doctor 和人工处理。
官方安装器和默认官方升级使用内置 ed25519 公钥 keyring,把规范 SHA256SUMS、当前架构二进制、detached 签名、架构和版本作为同一套发行文件验证。官方镜像是首选完整来源;取得有效镜像索引后,只有传输故障才丢弃整套文件并从同一 GitHub tag 重新下载。索引本身传输失败时查询 GitHub Latest;manifest 语义、校验和、签名或候选版本失败立即停止。
自定义 upgrade --url 或 --url-file 会使用内置 keyring,根据 detached ed25519 签名验证管理员选定的二进制,但不下载 SHA256SUMS。本地 install 命令不联网,也不额外验签,只复制已经运行的 inode;管理员必须先独立信任该二进制。两种升级路径都不存在未验签回退。
从 v2.9.5 起,发行二进制在已签名字节中携带规范版本见证。普通自升级无需执行候选即可读取该见证,并先应用禁止降级策略;只有允许升级的候选随后才会进入受限时长和输出的版本探测,且输出必须同时匹配签名见证和选定发行版。非强制升级不会执行缺少该见证的历史签名二进制。管理员独立确认历史文件后,可使用 upgrade --force 进行有意恢复或降级;签名验证和受限版本探测仍不会跳过。
README 的便利入口把官方镜像返回的安装脚本直接交给 root shell。pipefail 能传播 curl 失败,但不能在执行前认证脚本,也不能撤回已经流入 shell 的部分字节。已经运行的安装器会验签二进制;首次脚本链路需要更高保证时,使用安装指南中的固定 commit、独立哈希和精确版本流程。
镜像被攻陷可能替换稳定安装脚本、manifest 或拒绝服务,因此会威胁新的便利安装。它不能伪造已安装客户端接受的 ed25519 二进制。当前 v1 发行私钥曾在联网维护主机上保存,不能声称从生成起就完全离线;后续轮换必须通过重叠版本迁移内置 keyring。
有效签名本身不提供首次安装的绝对防回滚:能够控制版本路由的一方可能重放一个仍由受信 key 签名的旧版本。需要防回滚时必须独立固定精确版本和审计记录。
特权操作会尽力以 JSON 行追加到 /var/log/linux-temp-admin/audit.log,记录时间、调用者、动作、目标和结果。文件和目录为 root 所有,单条记录和总大小都有上限。达到 64 MiB 或发生其他写入失败时,特权操作仍会继续并发出警告,因此该次操作可能没有审计记录;管理员必须归档、轮转或修复写入问题。若崩溃留下未完成的末行,下一次写入会先回退到最后一条完整 JSON 行。
审计日志用于本机追踪,不是防 root 篡改的远程不可变日志。卸载默认保留它,只有显式 --purge-audit 才删除。
- 邀请或撤销返回非零;
doctor报告孤儿授权、身份不匹配或缺失撤销任务;- registry 损坏、权限变化或安装路径不安全;
- checksum、signature、manifest 或 candidate version 失败;
- 私钥、密码、下载凭据或邀请包可能泄露。
这些情况不能因为“换另一个来源成功”或“账号看起来已经不能登录”而忽略。保留证据、撤销相关访问、修复根因并重新运行 linux-temp-admin doctor。