系统运行时环境变量本身不能被“锁定”为只读状态,但可通过权限控制、加载机制干预和运行时防护三类手段实质性阻断未授权修改:收紧/etc/profile等全局配置文件属主与权限;在/etc/profile中校验profile.d脚本并显式设置readonly path;禁用用户级覆盖路径;启用selinux/apparmor限制/proc/[pid]/environ访问;高敏感信息改用密钥管理工具注入。

系统运行时环境变量本身不能被“锁定”为只读状态,但可以通过权限控制、加载机制干预和运行时防护三类手段,实质性阻断未授权修改,实现等效加固。
收紧全局配置文件的属主与权限
环境变量的源头才是关键。Linux下真正影响所有用户的全局变量来自 /etc/profile、/etc/profile.d/*.sh 和 /etc/environment。这些文件若被普通用户写入,就等于开放了后门。
- 把
/etc/profile.d/下所有脚本设为 root:root 所有,权限严格限制为644:sudo chown root:root /etc/profile.d/*.sh && sudo chmod 644 /etc/profile.d/*.sh - 检查
/etc/environment是否存在且权限为644,内容仅含简单键值对,不含执行逻辑 - 在
/etc/profile开头加入校验段:若检测到/etc/profile.d/中有非 root 属主或非644权限的文件,直接exit 1中断加载
阻断用户级覆盖路径
很多加固失败,是因为用户在 ~/.bashrc 或 ~/.profile 中重新 export 了 PATH、JAVA_HOME 等关键变量,覆盖了系统设定。
- 在
/etc/profile末尾显式声明并立即readonly关键变量,例如:export PATH="/usr/local/bin:/usr/bin:/bin"<br>readonly PATH
- 注意:
readonly对子进程无效,所以必须配合路径本身不可写——检查/usr/local/bin等目录是否被普通用户拥有,否则仍可植入同名恶意程序 - 禁用用户通过 shell 配置文件篡改:在
/etc/profile中设置unset BASH_ENV ENV,防止非登录 shell 加载用户自定义脚本
加固运行时内存与进程环境
即使变量在启动时正确加载,运行中也可能被恶意进程篡改或窃取。
- 启用 SELinux 或 AppArmor,限制非授权进程读取
/proc/[pid]/environ(该文件以 null 分隔明文暴露所有环境变量) - 对高敏感服务(如数据库连接、API 密钥),避免通过环境变量传参;改用密钥管理工具(HashiCorp Vault、AWS Secrets Manager)按需注入
- 若必须用环境变量,启动前用
set -o pipefail+exec -a启动服务,并在容器或 systemd service 中配置EnvironmentFile=指向加密或权限受限的文件 - 定期扫描可疑进程:用
cat /proc/[1-9]*/cmdline 2>/dev/null | tr '\0' '\n' | grep -i 'password\|key\|token'查找命令行泄露
适配特殊场景的加固补充
不同运行环境有其独特风险点,需针对性处理:
-
sudo 场景:默认不继承 PATH,但若
/etc/sudoers中配置了env_keep += "PATH",必须同步加固该变量的来源与目标路径权限 -
systemd 服务:绕过
/etc/profile是常态,应统一使用Environment=或EnvironmentFile=显式声明,禁用PassEnvironment= -
容器环境:基础镜像中不要硬编码敏感变量;使用 Docker secrets 或 Kubernetes Secret 挂载,避免
ENV指令写死密钥 - 嵌入式 U-Boot:环境变量存储在 Flash 明文区是重大隐患,应启用 AES 加密存储,并将解密密钥存于 eFuse 或安全启动链可信区域











