十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

银河麒麟 V10 / 统信 UOS 深度适配(内核参数到 seccomp)

银河麒麟 V10 / 统信 UOS 深度适配(内核参数到 seccomp) 第 2 章 银河麒麟 V10 / 统信 UOS 深度适配内核参数到 seccomp2.1 国产 OS 和 CentOS 的核心差异踩坑地图差异点CentOS 7/8麒麟 V10统信 UOSPHP 项目影响SELinux 默认策略permissiveenforcingenforcingNginx 反向代理到 PHP-FPM 被拦内核安全模块无kylinsecdeepin-security共享内存/信号量创建失败systemd 版本219-239239241PrivateTmptrue在老配置上无效防火墙前端firewalldfirewalldufw端口放行命令不同最大打开文件数10241024更严1024Swoole 高并发报too many open files/tmp清理策略10 天3 天1 天session 文件被意外删掉2.2 首次启动三步走否则 PHP-FPM 根本起不来步骤 1关掉或放宽 SELinux测试环境可直接关生产要写策略# 查看当前状态getenforce# 若显示 Enforcing则会拦截 Nginx → PHP-FPM 的 socket 通信# 临时关闭重启后失效用于排查是不是 SELinux 的锅sudosetenforce0# 永久关闭测试环境sudosed-is/^SELINUXenforcing/SELINUXdisabled//etc/selinux/config# 改完要重启sudo reboot# 生产环境保持 enforcing但给 Nginx 和 PHP-FPM 开白名单sudosetsebool-Phttpd_can_network_connect1sudosemanage fcontext-a-thttpd_sys_rw_content_t/var/www(/.*)?sudorestorecon-Rv/var/www大白话SELinux 是个白名单防火墙默认Nginx 不许访问 PHP-FPM 的 socket。你要么关掉它测试环境偷懒要么告诉它这俩是一家的放行。步骤 2提升文件描述符上限Swoole/Workerman 必做# 查看当前限制ulimit-n# 输出 1024 说明太低万人在线的长连接服务会被打爆# 临时提升当前 shell 生效ulimit-n65535# 永久提升写入 /etc/security/limits.conf对所有用户生效sudotee-a/etc/security/limits.conf/dev/nullEOF * soft nofile 65535 * hard nofile 65535 EOF# systemd 服务还要在 service 文件里单独写sudosed-i/\[Service\]/a LimitNOFILE65535/etc/systemd/system/php-fpm.servicesudosystemctl daemon-reloadsudosystemctl restart php-fpm验证是否生效# 查看 PHP-FPM 主进程的实际限制sudocat/proc/$(pgrep-ophp-fpm)/limits|grepopen files# 期望Max open files 65535 65535 files步骤 3调整内核共享内存参数opcache/apcu/shmop 必需# 查看当前值sysctlkernel.shmmax# 共享内存单块最大字节数sysctlkernel.shmall# 共享内存总页数# 临时调整sudosysctl-wkernel.shmmax2147483648# 2GBsudosysctl-wkernel.shmall524288# 2GB / 4KB(页大小) 524288# 永久生效sudotee-a/etc/sysctl.conf/dev/nullEOF kernel.shmmax 2147483648 kernel.shmall 524288 net.core.somaxconn 8192 net.ipv4.tcp_max_syn_backlog 8192 net.ipv4.ip_local_port_range 1024 65535 EOFsudosysctl-p为什么要改OPcache 默认占 128MB 共享内存apcu 再来 64MB如果你还跑了个 Swoole Table又是共享内存内核默认的配额不够就报Failed to create SysV shared memory segment。2.3 麒麟 kylinsec 安全模块的专属坑麒麟 V10 有个自研的kylinsec内核模块会在进程间通信IPC时做额外审计。两种表现PHP-FPM 子进程向 master 发信号reload 配置时被拦截日志里报Operation not permittedsem_get()/shm_attach()这些 SysV IPC 函数返回 falseerror_get_last()里写Permission denied。解决方案 1把 PHP-FPM 进程加入受信任组推荐# 查看当前哪些组受信任sudokylinsec-config --list-trusted-groups# 通常有 root、kylinsec-admin# 把 www 用户加入可信组需要 kylinsec-admin 权限sudousermod-aGkylinsec-admin www# 重启 PHP-FPMsudosystemctl restart php-fpm解决方案 2针对 IPC 操作放宽策略临时排查用# 查看 kylinsec 拦截日志sudojournalctl-ukylinsec|grepphp-fpm# 如果确认是误报可以添加白名单规则具体语法见麒麟官方文档sudokylinsec-config --add-ruleallow ipc from uidwww2.4 统信 UOS 的包管理差异apt 不是 yum统信 UOS 基于 Debian装依赖的命令和麒麟完全不同# 更新软件源初次使用必做否则找不到包sudoaptupdate# 装编译依赖对应前面第 1 章的 yum install 命令sudoaptinstall-ybuild-essential autoconf pkg-config\libxml2-dev libssl-dev libsqlite3-dev\libcurl4-openssl-dev libpng-dev libjpeg-dev\libfreetype6-dev libonig-dev libzip-dev\libsystemd-dev libreadline-dev libicu-dev# 查已装软件包版本调试时用dpkg-l|greplibsslapt-cachepolicy libssl-dev统信 UOS 上 OpenSSL 版本陷阱自带的是 OpenSSL 1.1.1不是 3.x编译 PHP 8.2 时如果遇到undefined reference to OPENSSL_init_ssl就是版本不匹配。解决办法从源码装 OpenSSL 3.0.x然后./configure --with-openssl/usr/local/ssl3。2.5 seccomp 沙箱策略政务系统测评会查大白话seccomp 是 Linux 内核的系统调用过滤器等保测评时要求进程只能调用业务必需的系统调用其他一律禁止。PHP-FPM 在 seccomp 严格模式下会因为「调了不该调的系统调用」而崩溃。现象PHP-FPM 起来一会儿就自动退出dmesg 里报[12345.678] audit: type1326 audit(...): auid... uidwww ... syscall56 (clone) commphp-fpm exe/usr/local/php8/sbin/php-fpm sig31 archc00000b7 ... res0这说明clone系统调用用来创建子进程的被 seccomp 拦了。解决步骤需要等保测评专家配合第一步采集 PHP-FPM 实际需要的系统调用清单# 在测试环境先关掉 seccomp用 strace 跟踪 PHP-FPM 启动和运行时的系统调用sudostrace-ff-o/tmp/php-fpm-trace\-etraceopen,openat,read,write,close,stat,fstat,lseek,mmap,mprotect,munmap,brk,clone,execve,wait4,socket,connect,bind,listen,accept,sendto,recvfrom,setsockopt,getsockopt,fcntl,ioctl,select,poll,epoll_create,epoll_ctl,epoll_wait,futex,set_robust_list,rt_sigaction,rt_sigprocmask,prctl,arch_prctl\/usr/local/php8/sbin/php-fpm--nodaemonize--fpm-config /usr/local/php8/etc/php-fpm.conf# 让它跑 5 分钟期间访问几个真实页面然后停掉sleep300sudopkill-INTphp-fpm# 汇总所有用到的系统调用grep-h(/tmp/php-fpm-trace.*|cut-d(-f1|sort-u/tmp/php-syscalls.txt第二步把清单交给安全团队写成 seccomp 白名单策略下面是一个示例模板JSON 格式给 systemd 的SystemCallFilter用{defaultAction:SCMP_ACT_ERRNO,syscalls:[{names:[read,write,open,openat,close,stat,fstat,lstat,lseek],action:SCMP_ACT_ALLOW},{names:[mmap,munmap,mprotect,brk],action:SCMP_ACT_ALLOW},{names:[clone,fork,vfork,execve,wait4,exit,exit_group],action:SCMP_ACT_ALLOW},{names:[socket,connect,bind,listen,accept,accept4,sendto,recvfrom,setsockopt,getsockopt],action:SCMP_ACT_ALLOW},{names:[fcntl,ioctl,select,poll,epoll_create,epoll_create1,epoll_ctl,epoll_wait],action:SCMP_ACT_ALLOW},{names:[futex,set_robust_list,get_robust_list],action:SCMP_ACT_ALLOW},{names:[rt_sigaction,rt_sigprocmask,rt_sigreturn,sigaltstack],action:SCMP_ACT_ALLOW},{names:[prctl,arch_prctl,set_tid_address,set_thread_area],action:SCMP_ACT_ALLOW},{names:[getpid,getppid,getuid,geteuid,getgid,getegid],action:SCMP_ACT_ALLOW},{names:[getcwd,chdir,fchdir],action:SCMP_ACT_ALLOW},{names:[sendfile,splice,tee],action:SCMP_ACT_ALLOW}]}第三步在 systemd service 文件里启用麒麟/统信上 systemd 都支持sudotee/etc/systemd/system/php-fpm.service/dev/nullEOF [Unit] DescriptionPHP 8.3 FastCGI Process Manager Afternetwork.target [Service] Typenotify ExecStart/usr/local/php8/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php8/etc/php-fpm.conf ExecReload/bin/kill -USR2 $MAINPID Userwww Groupwww Restarton-failure # seccomp 白名单等保测评要求 SystemCallFiltersystem-service network-io ipc basic-io SystemCallFilter~privileged resources obsolete # 其他加固选项 PrivateTmptrue NoNewPrivilegestrue ProtectSystemstrict ProtectHometrue ReadWritePaths/var/www /tmp /var/log/php-fpm [Install] WantedBymulti-user.target EOFsudosystemctl daemon-reloadsudosystemctl restart php-fpm大白话SystemCallFiltersystem-service是 systemd 预定义的一组Web 服务常用系统调用~privileged表示禁止特权操作如 reboot、mount。这样既满足等保要求最小权限原则又不会把 PHP-FPM 卡死。2.6 防火墙放行麒麟用 firewalld统信用 ufw麒麟 V10firewalld# 查看当前开放端口sudofirewall-cmd --list-all# 放行 80 和 443Nginxsudofirewall-cmd--permanent--add-servicehttpsudofirewall-cmd--permanent--add-servicehttpssudofirewall-cmd--reload# 如果 PHP-FPM 走网络 socket不推荐但某些架构这么用sudofirewall-cmd--permanent--add-port9000/tcpsudofirewall-cmd--reload统信 UOSufw# 启用防火墙初次使用可能是关闭状态sudoufwenable# 放行端口sudoufw allow80/tcpsudoufw allow443/tcpsudoufw allow9000/tcp# 若 PHP-FPM 走 TCP socket# 查看规则sudoufw status numbered2.7 一键检查脚本部署前必跑把下面这个脚本存为/usr/local/bin/check-php-env.sh部署前跑一遍能提前发现 90% 的配置问题。sudotee/usr/local/bin/check-php-env.sh/dev/nullEOF #!/bin/bash # 用途检查麒麟/统信环境下 PHP-FPM 的运行前置条件 RED\033[0;31m; GREEN\033[0;32m; NC\033[0m FAIL0 check() { if eval $2; then echo -e ${GREEN}✓${NC} $1 else echo -e ${RED}✗${NC} $1 FAIL1 fi } echo 系统环境检查 check SELinux 已关闭或设为 permissive \ [ $(getenforce 2/dev/null) ! Enforcing ] check 文件描述符上限 65535 \ [ $(ulimit -n) -ge 65535 ] check 共享内存配额 2GB \ [ $(sysctl -n kernel.shmmax 2/dev/null || echo 0) -ge 2147483648 ] check net.core.somaxconn 4096 \ [ $(sysctl -n net.core.somaxconn 2/dev/null || echo 0) -ge 4096 ] echo -e \n PHP-FPM 服务检查 check php-fpm.service 已启用 \ systemctl is-enabled php-fpm.service /dev/null check php-fpm 进程存在 \ pgrep php-fpm /dev/null check php-fpm 监听端口/socket 正常 \ ss -lntp | grep -q php-fpm || ss -lnx | grep -q php-fpm echo -e \n PHP 配置检查 PHP/usr/local/php8/bin/php check OPcache 已启用 \ $PHP -r exit(ini_get(\opcache.enable\)?0:1); 2/dev/null check 内存上限 256M \ $PHP -r exit(ini_get(\memory_limit\)256?0:1); 2/dev/null check 扩展 redis 已加载 \ $PHP -m 2/dev/null | grep -q redis check 扩展 swoole 已加载 \ $PHP -m 2/dev/null | grep -q swoole [ $FAIL -eq 0 ] echo -e \n${GREEN}所有检查通过${NC} || echo -e \n${RED}部分检查失败请修复后重试${NC} exit $FAIL EOFsudochmodx /usr/local/bin/check-php-env.sh check-php-env.sh
返回列表