审计账页把策略、TLS 与部署证据分列,提醒每项证据都有范围。

审计公共边缘的信任

检查安全策略、经过验证的 TLS 身份、签发限制与部署信任,并明确每项检查的边界。

八月 6, 2026 · 2 分钟 · XB Field Notes
可信所有者或控制台提供的参考指纹,与当前观察到的服务器主机指纹一起进入安装前比较。严格检查下,已知且匹配的密钥通过主机身份检查;未知或变化的密钥被拒绝。

SSH 主机密钥是部署记录的一部分

记录期望的指纹,使用斟酌过的 StrictHostKeyChecking 策略,并把变化当作事故来对待。

七月 28, 2026 · 1 分钟 · XB Field Notes
指纹式密钥符号分支连接负责人、账号与操作、退役,表示访问清单而非安全徽章。

SSH 密钥卫生,主要是限制密钥能干什么

SSH 密钥卫生首先要回答:哪份凭据授予什么访问,谁负责,以及如何结束这份授权。密钥注释方便维护清单,却不是经过认证的所有者记录,更不是授权规则。应把指纹与负责人、目标账号、允许操作和移除计划对应起来。生成现代密钥只是开始,不能用一条生成命令代替完整的访问生命周期管理。 限定服务端权限 authorized_keys 中的公钥通常用于授权访问某个账号,同时还受服务器其他控制约束。自动化任务应结合权限有限的账号和经过选择的选项。强制命令能限制执行的操作,from 可以限制来源地址,但二者都不会自动把进程关在某个工作目录,也不会让一个会拼接不可信命令的包装脚本变得安全。 restrict 禁用转发、伪终端分配和 ~/.ssh/rc,但显式搭配选项可以重新启用个别功能;它本身并不禁止 shell 或命令执行。因此,无人值守任务通常还需要谨慎实现的强制命令。no-agent-forwarding 只禁止代理转发,不能证明密钥没有普通 shell 权限。principals 对可信证书颁发机构条目有专门含义,并不是加在任意普通公钥前面就能形成通用身份约束。 还要审阅最终生效的服务端配置和其他授权来源。AuthorizedKeysCommand、证书颁发机构、账号权限和 Match 规则,都会让结果超出单个文件的内容。清单工具看到选项名时应报告观察事实,不能直接给出“已限制,所以安全”的结论。来源限制也取决于服务器实际看到的地址,包括代理、跳板机或地址转换后的来源,不能只按客户端想象的拓扑解释。 区分密钥类型与签名算法 RSA 公钥行仍使用 ssh-rsa 类型标签,即使认证时采用 rsa-sha2-256 或 rsa-sha2-512 签名。OpenSSH 8.8 默认禁用的是使用 SHA-1 的 ssh-rsa 签名方案,而不是所有 RSA 密钥。应检查密钥长度与实际支持的签名算法,不能只凭一行的第一个词就把所有 RSA 条目判成过时。DSA、弱参数和不受支持的配置,需要各自的迁移计划。 新凭据应选择当前环境支持的算法和合适的保护。口令可以保护加密私钥文件,避免文件被复制后立刻就能使用;硬件密钥则提供不同的边界。它们都不能代替安全工作站、受控代理访问和服务端权限限制。无法交互输入口令的自动化,需要明确的凭据保管和更新设计,不能简单地把“没有提示”当成设计完成。 坏掉的样子 只追加新公钥的轮换,会让旧凭据继续得到授权。应从所有相关来源移除退役条目,验证替代凭据,并单独处理现有会话。普通裸公钥不会自动携带到期机制;需要通过支持的服务端选项、SSH 证书或明确的生命周期操作执行过期。在注释里写一个日期不会产生任何强制效果,负责人离职也不会自动让那一行失效。 权限数字需要准确解释。私钥应限制为所有者访问,常见模式是 0600;私有目录常见模式是 0700。authorized_keys 的公钥内容并不是秘密,在所有权和写保护满足检查时,0644 也可能被服务器接受。采用更严格的 0600 策略合理,却不能声称每个其他模式都证明已经泄露。ACL、父目录和平台规则仍需分别核对,简单的模式检查并不涵盖全部访问路径。 ...

七月 6, 2026 · 2 分钟 · XB Field Notes
报文经过输入链优先级 0 的接受后,仍到达优先级 10 的终止丢弃。

防火墙策略必须匹配报文路径、地址族和链顺序

防火墙在网络栈的特定位置执行报文策略。一条有用规则因此不只包含端口,还要明确地址族、挂钩、方向、连接状态和相对其他规则的位置。nftables 基础链按指定优先级接入 Netfilter 挂钩。报文实际经过的路径,决定它会遇到哪些裁决,而不是运维文档中描述的先后顺序。审阅策略必须保留这些执行上下文。 坏掉的样子 规则位于错误挂钩时,预期流量可能完全不受影响。INPUT 处理交付给当前命名空间本地的流量,FORWARD 处理经过它转发的流量,OUTPUT 面向本地产生的流量。宿主的容器转发路径,不一定就是本地输入路径。假定宿主级规则保护所有附近服务之前,应先查清实际流量经过哪个命名空间和挂钩。 地址族和方向错误也容易被掩盖。允许服务 TCP 目的端口,不同于匹配通常临时分配的客户端来源端口。只覆盖 IPv4 的策略不会自动覆盖 IPv6;IPv6 通信还依赖邻居发现等 ICMPv6 功能,丢弃所有非 TCP 报文,可能让 TCP 端口明明被允许的连接仍然失败。端口规则不能脱离链路和协议所需控制流量解释。 nftables 的 accept 不一定是所有基础链中的最终裁决。同一挂钩上更晚优先级的另一条链,仍能丢弃报文;drop 则会结束其遍历。只审阅一个表或一条链,可能看到允许计数器增长,却无法解释客户端为何失败。应查看全部适用规则集及其挂钩优先级,不能把第一条可见 accept 当成系统已经最终放行的证明。 后续输入链可丢弃先前已接受的报文。端口结果是实验预期;当前集成仍待验证。 快速验证 将脚本保存为 check-firewall.py,只在获得授权、装有 Docker 的一次性虚拟机中执行 python3 check-firewall.py。历史文章报告使用 nftables 1.0.6 和 Python 3.11.16;保留验证文件中未找到原始集成日志,本轮没有重跑。需启用 Python 断言;清理仅尽力执行。两个命名空间通过一次性 veth 使用 IPv4 与 IPv6 通信。NET_ADMIN 和 SYS_ADMIN 是重要权限;规则限定在命名空间内,并不让容器变成可靠安全边界。设置失败时不要削弱宿主保护。镜像摘要也不会冻结 apt 仓库,指定版本的软件包以后可能无法取得: ...

七月 1, 2026 · 3 分钟 · XB Field Notes
服务边界拒绝多余写入,明确出口仍通往可写状态。

用实际拒绝结果验证 systemd 服务边界

服务加固应该把一种明确不需要的操作变为被拒绝的操作,同时保留应用必须完成的工作。systemd 为文件系统视图、命名空间、权限和其他资源提供执行设置,但这些是边界各不相同的独立控制。添加四条熟悉的指令,并不意味着所有可读文件、可接触进程、继承的文件描述符或允许的系统调用都会消失。判断依据应是配置的真实语义与进程的实际行为。 坏掉的样子 ProtectSystem=strict 让服务挂载命名空间内的大部分文件系统层级变为只读。只读不代表不可读取,而且该设置有文档明确的例外,例如还需要单独控制的接口文件系统。服务仍然可能泄露它能够读取的信息,也仍然可以破坏可写目录中的数据。因此应该先使用专用服务身份,列清必要访问,再选择对应限制,而不是把一个只读开关当成覆盖所有资源的隔离墙。 PrivateTmp=yes 给服务提供私有临时目录。如果应用原本依赖另一个服务通过普通 /tmp 交换文件,这项设置可能直接打断协作。PrivateNetwork=yes 创建拥有独立回环接口的网络命名空间,因此宿主回环上的监听器不再是里面的同一个端点。需要直接连接数据库或公共接口的程序,若没有有意安排所需连接,就不适合直接套用这一设置。应先查真实调用路径,不能假定网络隔离不会影响正常功能。 NoNewPrivileges=yes 阻止执行程序时通过设置用户身份的二进制文件、文件能力等机制取得新的特权,并不删除进程已经拥有的权限。同样,单独写一条 IPAddressAllow,不意味着其他地址全部被拒绝:地址过滤有允许与拒绝的优先关系,还依赖内核功能支持。选项名称不是完整安全策略,每项控制都需要按其契约理解,尤其不能把未验证的限制写成已经成立的保证。 不同 systemd 控制拒绝选定操作,同时保留受管理状态与临时写入。 快速验证 这个实验要求一次性 Linux 系统中的 root 身份、作为 PID 1 的 systemd、可用的挂载与网络命名空间、位于 /usr/bin/python3 的 Python 3.8 或更新版本,以及用户管理工具。保持 Python 断言启用;生成的 worker 必须能被服务账号读取。早期记录报告 Debian 12、systemd 252.39;这里没有复现该次运行。脚本创建唯一命名的账号、运行时单元、状态目录与文件。前后两阶段使用同一个非 root 工作负载: ...

六月 27, 2026 · 3 分钟 · XB Field Notes