内核地址为什么不能随便看
普通用户能读 dmesg 或 /proc/kallsyms 时,可以拿到内核地址、驱动名称、硬件型号等信息,这些内容会显著降低漏洞利用的门槛:知道内核版本与符号地址后,构造稳定利用的难度大幅下降。因此 CIS 基线要求把内核消息与内核符号可见性收敛起来,用 kernel.dmesg_restrict 与 kernel.kptr_restrict 两个参数控制。
基本信息
| 加固项 | 内核信息可见性收敛 |
|---|---|
| 适用平台 | Linux(RHEL/CentOS/Debian/Ubuntu) |
| 风险等级 | 中 |
| 基线 | kernel.dmesg_restrict=1;kernel.kptr_restrict=2 |
| 影响面 | 普通用户无法直接读 dmesg 与内核符号地址 |
典型使用场景
- 基线核查:同时检查两个参数,缺一不可
- 多租户主机加固:同机其它用户不可读内核信息
- 合规整改:等保对剩余信息保护与最小权限的要求
- 排障流程调整:收紧后把 sudo dmesg 与 journalctl -k 写进运维手册
- 安全评估:漏洞利用难度评估时确认信息暴露面已收敛
加固与验证
加固与验证
sysctl kernel.dmesg_restrict kernel.kptr_restrict
cat >> /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
EOF
sysctl --system
sudo -u nobody dmesg 2>&1 | head -2 # 预期:Operation not permitted
sudo -u nobody head -3 /proc/kallsyms # 预期:地址位全为 0参数取值读法
| 参数与取值 | 含义 | 正常与异常 |
|---|---|---|
| dmesg_restrict=0 | 任何用户可读内核环形缓冲区 | 默认偏宽松,需收紧 |
| dmesg_restrict=1 | 仅特权用户可读 | 基线要求值 |
| kptr_restrict=0 | 符号地址对所有人可见 | 信息暴露最大 |
| kptr_restrict=1 | 非特权用户看到 0 | 部分发行版默认值 |
| kptr_restrict=2 | 始终隐藏地址 | 基线要求值,需 CAP_SYSLOG |
dmesg_restrict=1 之后现场排障要用 sudo dmesg 或 journalctl -k:把这条写进运维手册,避免值班人员把它误判成系统故障。
kptr_restrict=2 时非 root 读 /proc/kallsyms 的地址全为 0,依赖地址分析的性能与调试工具需要 root 或 CAP_SYSLOG 权限。
落地要点
- 两个参数一起改,避免只收敛一半的信息暴露面
- 改前记录现值,作为变更前后的对照证据
- 把新的排障命令写进值班手册,减少现场误判为故障
- 监控采集改走 journal 接口或加权限白名单,避免采集中断
- 在镜像模板中预置参数,防止新机器回到默认值
kptr_restrict=2 时依赖符号地址的性能与调试工具需要显式提权运行:上线前确认监控与排障链路仍然可用。