《卓伊凡·网络安全研究室》:
什么是核心转储、为什么危险、为什么必须限制、形象比喻、以及详细的安全处理步骤。
未对核心转储做限制,为什么可能导致严重信息泄露?
很多人做服务器安全的时候,会盯着端口、盯着弱密码、盯着防火墙、盯着漏洞修复,但却经常忽略一个非常关键的点:核心转储(Core Dump)没有做限制。
这个问题看起来不显眼,甚至很多人都没听过,但我要告诉大家,这东西一旦处理不好,真的可能把系统里的敏感信息直接“倒”出来。
它不是小问题。
它属于那种平时你感觉不到,一旦出事就容易出大事的安全项。
今天这篇文章,我就以卓伊凡的口吻,把这个问题彻底讲透。
一、什么是核心转储?
所谓核心转储,英文叫 Core Dump,本质上就是:
当一个程序异常崩溃的时候,操作系统把这个程序当时的内存状态、寄存器状态、调用栈、变量内容等信息,保存成一个文件。
你可以把它理解成程序“临死前”的一张完整快照。
也就是说,一个程序崩溃了,系统为了方便开发人员排查问题,会把它崩溃那一刻脑子里装着的东西,尽可能原样保存下来。
这里面通常会包含:
- 程序当时运行到哪一行
- 调用了哪些函数
- 当前线程状态
- 内存里的部分变量值
- 堆栈信息
- 打开的部分资源状态
- 甚至可能包含账号、口令、密钥、Token、数据库连接信息等敏感内容
这就是核心转储。
它的原始作用并不是坏的,恰恰相反,它本来是用来排障和调试的。
程序崩了,开发人员就可以拿着核心转储文件,用 gdb 之类的工具去分析,到底崩在哪里,为什么崩,哪个变量有问题,哪个调用链出错了。
所以你要明白一点:
核心转储本身不是漏洞,但核心转储如果不受限制,就会变成安全风险。
二、用一个比喻讲清楚核心转储到底是什么
很多人第一次听这个概念会觉得很抽象,我给大家打个非常形象的比喻。
假设一个程序正在运行,你可以把它理解成一个人在办公室里工作。
那核心转储,就像这个人突然晕倒之后,现场被完整拍下来的一张“事故现场全景照片”。
这张照片里,不只是拍到了他倒下这件事本身,更关键的是:
- 桌面上摊开的合同
- 抽屉里没锁的文件
- 电脑屏幕上没关的聊天记录
- 记事本里的账号密码
- 客户资料
- 财务数据
- 正在处理但还没保存的敏感内容
全都被一起拍进去了。
这就是核心转储最危险的地方。
它原本是为了方便你排查:“这个人为什么倒下了?”
但如果这张“事故现场全景照片”被不该看到的人拿到了,那就不只是排查事故了,而是把整个办公室的秘密顺手泄露了。
所以为什么核心转储要限制?
因为你不能为了查一次故障,就把整个办公室的机密都一起公开。
三、核心转储为什么会造成信息泄露?
这一点是重中之重。
因为核心转储保存的是内存现场,而现代程序运行时,很多敏感信息恰恰就存在内存里。
比如:
- 用户登录后的会话信息
- 后台管理 Token
- 数据库账号密码
- Redis 连接密码
- API Key
- 第三方平台密钥
- JWT 内容
- 支付接口参数
- 用户手机号、身份证号、邮箱
- 程序临时解密后的敏感数据
- 程序运行中的缓存对象
注意,这些东西平时不一定会写进日志,但非常可能在内存里存在。
这就意味着,一旦程序崩溃并生成核心转储文件,这些敏感信息有概率被一起保存进去。
所以很多人误以为核心转储只是个“报错文件”,这是错误的。
日志通常记录的是“发生了什么”,而核心转储记录的是“当时内存里有什么”。
这两个东西的敏感级别完全不是一个量级。
说得再直白一点:
日志像事故说明书,核心转储像把事故现场连同保险柜钥匙一起打包。
四、为什么生产环境尤其必须限制?
开发测试环境和生产环境,安全要求根本不是一回事。
在开发环境里,程序崩了,保留核心转储可能是为了方便开发人员快速定位问题,这个可以理解。
但在生产环境里,系统承载的是真实业务、真实用户、真实数据,这时候核心转储的风险会被放大很多倍。
你可以把生产环境理解成一家正在营业的银行。
程序崩溃之后,如果只是看监控,那是正常排查;
但核心转储这种东西,更像是系统出事以后,自动把下面这些东西一起打包扔出来:
- 金库结构
- 客户名单
- 柜员操作记录
- 内部密码纸条
- 门禁流程
- 部分交易过程中的敏感数据
那这就不是“方便排查”了,
这叫为了查问题,把自己老底全掀开。
尤其是以下场景,更必须严格控制:
- 金融系统
- 支付系统
- 电商后台
- CRM系统
- 会员系统
- 企业ERP
- SaaS平台
- API 网关
- 认证鉴权中心
- 数据分析平台
- 存在大量个人信息处理的系统
这些系统一旦泄露,不只是技术问题,还可能涉及合规、赔偿、业务中断、品牌信誉损失。
五、为什么“未对核心转储做限制”会被判定为安全风险?
因为从安全角度看,这属于典型的敏感信息暴露面未收敛。
如果系统默认允许生成核心转储,那么一旦服务崩溃,就可能在磁盘上留下核心转储文件。
而这些文件如果再出现以下问题,风险会更大:
- 文件权限过宽,普通用户可读
- 核心文件保存在 Web 可访问目录
- 核心文件长期未清理
- 运维人员不知道其敏感性,随意传输
- 被备份到不安全位置
- 被上传到工单、IM群、第三方平台
- 容器、宿主机、共享目录中被其他进程获取
到这一步,它已经不是“程序崩溃副产物”了,
它已经变成了一个高敏感数据文件。
所以安全检查里看到“未对核心转储做限制,可能会出现信息泄露”,这个判断是完全合理的。
六、安全上应该怎么处理?详细步骤讲清楚
下面我给大家讲最重要的部分:如何安全处理核心转储。
不是一刀切地说“全部关掉”就完事,而是要根据环境来做。
第一步:明确原则——生产环境默认禁用
最稳妥的原则就是:
生产环境默认禁止生成核心转储。
因为生产环境的第一目标是安全和稳定,不是调试便利。
Linux 临时关闭核心转储,可以执行:
ulimit -c 0
这个命令的意思是:
把当前 shell 会话及其子进程允许生成的 core 文件大小设置为 0,也就是不允许生成。
但注意,这通常只是当前会话临时生效,重启或新会话后可能失效。
第二步:做永久限制
方法 1:修改 /etc/security/limits.conf
编辑文件:
vim /etc/security/limits.conf
加入:
* soft core 0 * hard core 0
含义是:
soft core 0:软限制,默认不允许生成 corehard core 0:硬限制,用户也不能轻易突破这个限制
保存后,重新登录生效。
如果只针对特定用户,也可以写成:
nginx soft core 0 nginx hard core 0
第三步:检查 systemd 服务是否仍允许生成
很多服务是通过 systemd 启动的,这种场景下还要看 systemd 配置。
先检查默认限制:
systemctl show | grep DefaultLimitCORE
如果发现不是 0,就要修改 systemd 全局配置:
编辑:
vim /etc/systemd/system.conf vim /etc/systemd/user.conf
加入或修改:
DefaultLimitCORE=0
然后执行:
systemctl daemon-reexec
这样可以让 systemd 管理的服务默认也禁止生成 core 文件。
如果是某个特定服务,还可以在服务单元里加:
[Service] LimitCORE=0
然后重载并重启服务:
systemctl daemon-reload systemctl restart 服务名
第四步:检查内核核心转储输出规则
Linux 内核通过这个参数控制 core 文件命名与处理方式:
cat /proc/sys/kernel/core_pattern
有的系统会把 core 文件直接写在当前目录,有的会交给专门程序处理。
如果你的原则是禁用核心转储,那除了 ulimit 和 limits.conf,也要检查这里,确保没有异常输出逻辑。
可以临时设置:
echo '|/bin/false' > /proc/sys/kernel/core_pattern
更规范的是写入 sysctl 配置:
编辑:
vim /etc/sysctl.conf
加入:
kernel.core_pattern=|/bin/false
然后执行:
sysctl -p
这样即使有进程尝试生成 core,也不会正常落盘。
第五步:如果业务必须保留核心转储,必须做隔离
有些高复杂业务、底层服务、研发调试环境,确实需要核心转储来分析问题。
这种情况下不是不能保留,而是必须受控保留。
必须做到下面几点:
1. 单独目录存放
不要让 core 文件散落在业务目录、Web目录、共享目录。
比如指定到安全目录:
kernel.core_pattern=/var/lib/coredump/core.%e.%p.%t
并提前创建目录:
mkdir -p /var/lib/coredump chmod 700 /var/lib/coredump chown root:root /var/lib/coredump
2. 严格权限控制
只有授权管理员、运维、安全负责人可访问。
原则上不能让普通业务账号、Web服务账号、开发测试随意读取。
3. 禁止通过公网路径访问
绝不能放在 Nginx/Apache 可访问目录下。
不能位于 /var/www/html、站点根目录、静态目录、下载目录等位置。
4. 设置保留周期
核心转储分析完成后应立即删除,不能长期堆积。
5. 纳入审计
谁访问过、谁拷贝过、谁分析过、何时删除,都应该有审计记录。
第六步:已有核心转储文件要立即排查和清理
如果服务器之前没有做限制,现在要立刻排查。
查找常见 core 文件:
find / -type f \( -name "core" -o -name "core.*" \) 2>/dev/null
如果找到了,不要上来就直接乱删,正确做法是:
1. 先确认文件来源
确认是哪个进程生成的,是否仍需要保留用于故障分析。
2. 判断敏感性
核心转储默认按高敏感文件处理。
3. 检查权限
查看是否存在权限过宽问题:
ls -l 文件名
如果权限不安全,应先限制:
chmod 600 文件名 chown root:root 文件名
4. 如无保留价值,安全删除
分析确认无保留需求后,及时删除。
rm -f 文件名
如果对极高敏感系统要求更高,还可以采用覆盖擦除方式,但要结合实际存储介质和文件系统机制来判断。
第七步:排查程序本身是否容易把敏感信息留在内存中
这一步很多人忽略,但其实很关键。
你光把 core 禁了还不够,最好还要反思:
为什么程序内存里会长期存在这么多敏感信息?
例如:
- 明文密码是否长期驻留内存
- Token 是否无必要缓存过久
- 密钥使用后是否及时清理
- 认证信息是否被无意义复制多份
- 错误处理是否导致敏感上下文堆积
安全做得更深一层,不是只处理“文件”,而是减少“敏感内容进入核心转储的机会”。
第八步:建立制度,不是只改一次配置
真正专业的安全处理,从来不是改一条命令完事。
要纳入标准化流程:
- 新服务器上线时检查 core 限制
- 服务部署前检查 systemd 配置
- 安全基线中加入 core dump 检查项
- 运维巡检中检查异常 core 文件
- 故障分析完成后立即清理
- 核心文件传输必须走审批和加密流程
这才叫真正的安全闭环。
七、推荐的处理策略
我给大家一个非常实用的建议:
开发环境
可以按需开启,但要控制范围,用完即删。
测试环境
默认关闭,特殊排障临时开启,排查完成立即关闭。
生产环境
原则上禁止生成。
确有必要时,必须走审批、单独目录、权限隔离、定期清理、全程审计。
这个策略,是比较稳的。
八、卓伊凡最后给大家说句大实话
很多安全问题,可怕的地方不在于“它很复杂”,而在于“它平时不显眼,所以大家不当回事”。
核心转储就是典型。
程序一崩,系统顺手把自己的“脑子内容”吐出来了。
这个东西放在开发手里,叫排障工具;
放在黑客手里,那就叫情报宝库。
所以我一直讲,真正懂安全的人,不只是盯着有没有人打你,
更要盯着你自己有没有无意间把家底亮出去。
未对核心转储做限制,本质上就是:
系统出了事,可能顺手把内部敏感信息一起交了出去。
这就是为什么它必须限制,必须重视,必须纳入安全基线。