【问题标题】:sudo: effective uid is not 0 when running under tomcat servicesudo:在tomcat服务下运行时有效uid不为0
【发布时间】:2019-10-01 04:16:03
【问题描述】:

我有一个小型 java web 应用程序 (grails),部署在 tomcat 8 下,我想使用 sudo 在本地服务器上执行脚本。在常规的 debian/ubuntu 服务器上,我所要做的就是使用 visudo 允许 tomcat 用户在没有密码的情况下在该特定脚本上执行 sudo,并且一切都按预期工作。当我尝试在 raspberry pi(型号 3b+,raspbian 10 - buster)上安装相同的 war 文件,从 SD 卡启动时,脚本的执行总是失败并出现错误“sudo:有效 uid 不是 0,是 /usr /bin/sudo 在设置了“nosuid”选项的文件系统或没有 root 权限的 NFS 文件系统上。

为了解决这个问题,我编写了另一个执行相同功能的小型可执行 jar(即尝试使用 sudo 启动脚本)。当以“pi”和“tomcat8”用户的身份交互(bash)登录时,此测试程序按预期工作(我必须为 tomcat8 用户设置一个 shell 才能获得交互式登录)。然后我使用 strace 尝试诊断问题。我可以从中收集到的是 getuid() 在 tomcat8 服务下运行时尝试启动 sudo 时返回 111 (tomcat8),但在 bash 中运行时将返回 0。

我还编写了一个小型 c 程序,它简单地调用 getuid() 并打印结果。如果我以交互方式在 tomcat8 用户下运行它(即 sudo su tomcat8),当我不使用 sudo 运行它时它会打印“111”,而当我使用 sudo 运行它时会打印“0”。当我尝试从 web 应用程序(使用进程构建器)启动该程序时,当命令在没有 sudo 的情况下运行时,我得到“111”,但是当命令带有前缀时,我得到“有效 uid 不是 0 ...”错误使用 sudo。

我检查了挂载,有许多挂载具有“nosuid”属性,但不是 /usr/bin 所在的根“/”目录,并且 /usr/bin/sudo 看起来有正确的权限:

pi@raspberrypi:~/dev $ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 147560 Jan 13  2019 /usr/bin/sudo

无奈之下,我尝试了其他一些方法来看看它们可能会产生什么效果: * 将tomcat8用户添加到adm、sudo等组 * 尝试重新挂载没有 nosuid 属性的其他挂载,尽管我无法重新挂载大约 6 个左右,因为挂载在使用中。

这些似乎都没有任何效果。

所以在我看来,tomcat8 用户在 bash 中可以使用 sudo,但在作为守护进程运行时不能。谁能给我一些关于这里发生了什么的想法?有没有办法诊断或跟踪操作系统如何确定有效的uid?

其他可能很重要的事情: 我通过 apt 安装了 openjdk-8-jdk 和 tomcat8,即使 raspbian 使用 systemd,tomcat8 也是通过 init.d 脚本启动的。不确定这是否会导致 uid 问题。

如果是 SD 卡有一些带有 nosuid 属性的挂载导致问题,为什么交互运行时它不会失败?

【问题讨论】:

  • 了解我可以通过哪些方式改进这篇文章以避免被否决票会很有用。
  • 这个问题问得很好,你展示了你为找出问题所采取的步骤。所有这些步骤都导致了完全错误的方向(您在询问时并不知道)并且读者获得了很多信息,但这些信息都没有增加问题。这使得读者很难评估您是否描述了他们遇到的相同问题,因此可能是反对票。我建议(现在回想起来)您将问题缩短到第一段,因为问题的其余部分不再有任何帮助。

标签: java linux raspberry-pi


【解决方案1】:

原来这是守护进程启动方式的问题,可能是由于 Debian 10 启动守护进程的方式发生了变化。我删除了 tomcat init.d 脚本,并将其替换为 systemd 单元文件,并包含以下属性:

[Service]
...
NoNewPrivileges=false
AmbientCapabilities=CAP_SETGID CAP_SETUID
SecureBits=keep-caps

这允许守护进程实际成功调用 setUid(0)。

【讨论】:

  • 看起来NoNewPrivileges=false 解决了这个问题(至少对我来说,在 Ubuntu 20 LTS 上是这样)。它是 systemd 沙盒模型的一部分,它在某个时候被引入到各种 Linux 发行版中,并且另外限制了 Tomcat。 NoNewPrivileges=false 允许子进程在文件系统上设置了setuid 位时在不同的用户下执行。显然sudo程序是通过这种方式在root下执行的,如果不允许的话,sudo会在Tomcat用户下启动,然后就不能再给脚本更多权限了。
猜你喜欢
  • 2013-09-07
  • 2016-11-13
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多