小心 selinux 对应用的影响
nginx 向云原生演进,All in OpenNJet!
1.背景
最近有客户报告在试用 NJet 时,有环境完全启动不起来,启动时就会产生 core,而相同的配置在其他环境没有问题。 具体现象如下:
这种现象比较奇怪,肯定是和该机器的某个系统设置有关。因此开发人员进行了远程调试。
2. 问题定位
2.1 定位代码
gdb 调试,显示 njet 在调用 tcc 中的函数时,调用失败,而此时函数指针也是正常的值。同时如果在配置中去掉 tcc 调用,NJet 也可以正常启动,因此可以初步定位 core 跟 tcc 代码有关。
更进一步分析,发现 core 出现在 tcc 内部的 mp_protect. 而查看的 dmesg 信息 errno 15 也明确了这一点(参考附录 errno 的解释)
更进一步的分析,可以看到 audit 日志明确了根本原因。
audit 的日志明确是设置“execheap” 操作被阻止了。也就是 mp_protect 执行失败,导致了 core
2.2 根源分析
NJet 为了兼顾高性能及灵活性,选择了 tcc JIT 框架,从而可以利用 c 语言脚本来实现业务逻辑,广泛应用在 stream 处理中的协议识别,协议解析等多处模块。在启动阶段,tcc 会把 c 语言脚本编译产生可执行到代码,并加载到内存中。因为加载到的代码会被作为函数执行,因此 tcc 需要对该段代码所在的区域利用 mp_protect 修改为可执行模式。但 selinux 模式中,该操作被阻止了。
3. 解决方案
3.1 尝试验证
关闭 selinux 规则: setenforce 0
可以解决
设置相关权限 setsebool -P allow_execheap 1
可以解决
3.2 最终解决方案
尽管 3.1 中的两种方案能够解决问题,但存在负面影响(影响了系统安全设置,有可能违反企业的安全规则)。仔细阅读 tcc 代码,tcc 有编译选项–with-selinux , 因此在编译 tcc 时,需要开启该选项,应对 selinux 的情况
4. 其他信息
本方案适用于 centos 及其变种
SELinux 是 Linux 内核的安全子系统,通过严格的访问控制机制增强系统安全性。一般情况下,建议开启 SELinux 来限制进程的权限,防止恶意程序通过提权等方式对系统进行攻击;然而,由于 SELinux 的严格访问控制机制,可能会导致一些应用程序或服务无法启动,请参考如下链接,查看,关闭/启用 SELinux https://help.aliyun.com/zh/ecs/use-cases/enable-or-disable-selinux
getsebool -a 可以用于查询具体的 SELinux 控制的属性状态,并利用 setsebool 进行设置变更
附录 1 core 后 error 的解释
The RIP value is the instruction pointer register value, the RSP is the stack pointer register value. The error value is a bit mask of page fault error code bits (from arch/x86/mm/fault.c):
bit 0 == 0: no page found 1: protection fault
bit 1 == 0: read access 1: write access
bit 2 == 0: kernel-mode access 1: user-mode access
bit 3 == 1: use of reserved bit detected
bit 4 == 1: fault was an instruction fetch
Here’s error bit definition:
enum x86_pf_error_code {PF_PROT = 1 <<0,PF_WRITE = 1 <<1,PF_USER = 1 <<2,PF_RSVD = 1 <<3,PF_INSTR = 1 <<4,};
The error code 15 is 1111 bit. Finally, we can know the meaning of 1111 as follows:
01111^^^^^||||+—>bit 0|||+—->bit 1||+—–>bit 2|+——>bit 3+——->bit 4
This message indicates that the application triggers protection fault because that process tried to write access to a reserved section of memory in user-mode.
NJet 应用引擎通过内核重构实现了独特的运行时 动态配置加载 能力,是 新一代高性能 Web 应用引擎 。NJet 拥有高性能数据面处理能力,将集群、高可用、主动健康检查、声明式 API 等多种辅助功能,通过 NJet 独特的副驾驶 CoPilot 服务框架调度,从而方便功能扩展,隔离管理 / 控制功能对数据面的影响,NJet 应用引擎性能超过 CNCF 推荐 Envoy 应用引擎的三倍。
版权声明: 本文为 InfoQ 作者【通明湖】的原创文章。
原文链接:【http://xie.infoq.cn/article/4a7659249348a0099fff24b6b】。文章转载请联系作者。
评论