RHEL8下systemctl启动Tomcat无法加载外部目录应用问题
故障原因
这个问题和你设置的777普通文件权限没有关系,本质是RHEL 8默认的两层安全机制限制导致的:
- systemd服务沙箱限制
网上通用的Tomcat systemd服务配置模板,基本都会默认开启ProtectSystem=strict/full、ProtectHome=yes这类沙箱加固参数:- 开了
ProtectSystem之后,整个系统文件系统会被挂载为只读,只有Tomcat自己的安装目录、日志目录、临时目录默认有读写权限 - 开了
ProtectHome=yes会直接禁止服务进程访问/home、/root、/run/user下面的所有路径
你手动进目录执行./startup.sh启动,是直接在shell里拉起进程,不会加载systemd的沙箱规则,自然不受这个限制。
- 开了
- SELinux强制访问控制限制
RHEL 8默认开着SELinux强制模式,通过systemd启动的Tomcat进程跑在tomcat_t这个受限安全域里,默认只能访问打了tomcat_var_lib_t、tomcat_log_t这类Tomcat专属安全标签的文件。/home目录下的文件默认标签是user_home_t,就算权限开到777,SELinux照样会拦Tomcat的访问请求。
你用root手动跑启动脚本的时候,shell本身是跑在unconfined_t无限制域下的,拉起来的Tomcat进程也会继承这个域,不受SELinux的定向策略限制,所以能正常读外部路径的文件。
额外提一句:你现在的上下文配置文件名叫
hrmix.xml,和要部署的上下文路径/hrmis拼写对不上,这个问题也会导致上下文加载失败,建议先把文件名改成hrmis.xml。
排查步骤
- 先临时关SELinux测试:执行
setenforce 0之后重启Tomcat,如果应用能正常启动,就是SELinux的拦截问题;如果还是起不来,优先查systemd沙箱配置。 - 检查服务的沙箱配置:执行
systemctl cat tomcat.service看实际加载的服务参数,确认有没有ProtectSystem、ProtectHome、ReadOnlyPaths这类加固配置。
修复方案
处理systemd沙箱限制
编辑Tomcat的systemd服务配置文件(一般存放在/etc/systemd/system/tomcat.service),在[Service]段加下面两行配置:
# 关闭/home目录的访问拦截 ProtectHome=no # 把应用目录加到服务允许读写的路径白名单 ReadWritePaths=/home/hrmis/develop/HRMIS2_DEV/
存好之后依次执行下面的命令重载配置、重启服务:
systemctl daemon-reload systemctl restart tomcat.service
处理SELinux限制(生产环境推荐,别直接永久关SELinux)
执行下面两条命令给应用目录打上Tomcat可访问的安全上下文标签,重启后也永久生效:
semanage fcontext -a -t tomcat_var_lib_t "/home/hrmis/develop/HRMIS2_DEV/WebRoot(/.*)?" restorecon -Rv /home/hrmis/develop/HRMIS2_DEV/WebRoot
执行完重启Tomcat服务就正常了。
内容的提问来源于stack exchange,提问作者edmondtt
相关产品推荐
相关产品推荐

