抱歉,您必须有一个 tty 才能运行 sudo

抱歉,您必须有一个 tty 才能运行 sudo

我已经问过这个问题堆栈溢出,但我被要求将其发布在这里。所以我也这么做了。

我使用我的 Java 程序运行了这个命令-

sudo -u <username> -S pwd

我得到了这个输出-

command=sudo -u <username> -S pwd
exitCode=1
sudo: sorry, you must have a tty to run sudo

我尝试编辑 /etc/sudoers 但是它已经包含

<username>       ALL=(ALL)       NOPASSWD: ALL

然后,我了解到可以通过在 /etc/sudoers 中注释掉以下代码来实现

# Defaults requiretty

此外,默认情况下,当尝试以另一个用户身份执行命令时sudo,我们必须提供自己的密码。但这可以通过在 /etc/sudoers- 中进行以下更改来更改。

Defaults targetpw

我的问题是,是否可以在 java 中执行上述命令而不在任何地方进行任何更改,即使用默认设置

答案1

我不知道如何在 Java 中运行 shell 命令,但可以看一下 ssh 命令的 -t 选项

-t force pseudo-tty allocation.

当我需要通过 ssh 以 root 身份运行命令时,我就是这样做的(直接 root 登录被禁用,并且 sudo 需要 tty)

答案2

我的问题是,是否可以在 Java 中执行上述命令而不在任何地方进行任何更改,即使用默认设置?

sudo -u -S 密码

简短的回答是否定的,您需要更改设置才能让 sudo 执行与当前不同的操作。

sudo 可能不是适合此目的的工具。Sudo 的规则旨在帮助系统管理员配置一种提升权限的方法,这种方法很难被滥用来获取额外/非预期的权限。

如果你考虑一下 sudo 为你做了什么:

  1. 提示输入密码以验证身份
  2. 提升权限
  3. 然后可以选择以另一个用户身份获取权限
  4. 记录 sudo 使用来获取访问权限或运行命令

如果您希望 Java 以任意用户身份运行任意命令,而无需为这些用户或您自己的用户提供密码,那么您实际上是在替代 sudo。在这种情况下,您应该创建自己的规则来防止滥用。

基本上有两种方法可以做到这一点:

  1. 使用提升的权限运行你的 java,并小心地获取和归还你需要的权限(参见 setuid() seteuid() C 函数调用)。
  2. 在需要时运行外部程序来获取提升的权限

在#1的情况下,你的java程序正在执行sudo所做的事情,你应该实施自己的一套规则来防止滥用。

除了 sudo 之外,还有其他程序可以执行 #2。可以在以下位置找到一个例子https://code.google.com/archive/p/exec-wrapper/downloads

这个方便的 shell 脚本会创建一个 C 程序来运行另一个命令(通常是脚本)。然后,您将 C 程序编译为二进制文件,并将其标记为 setuid root,或者实际上可以将其设置为任何用户。(模式:4555 和所有者:root)

只要您使用允许的文件系统,运行二进制程序就会以拥有二进制程序本身的用户 ID 的身份运行配置的命令。

相关内容