如何在没有密码提示的情况下以root用户身份运行特定程序?


169

我需要在没有密码的情况下以sudo的身份运行某些东西,因此我使用了visudo并将其添加到我的sudoers文件中:

MYUSERNAME ALL = NOPASSWD: /path/to/my/program

然后我尝试了一下:

$ sudo /path/to/my/program
[sudo] password for MYUSERNAME: 

为什么要求输入密码?如何以root用户身份与非root用户一起运行/使用命令,而无需输入密码?

Answers:


91

您在sudoers文件中还有另一个与您的用户匹配的条目。该NOPASSWD规则必须位于该规则之后才能优先。

完成此操作后,sudo通常会提示除以外的所有命令输入密码/path/to/my/program,它将始终让您运行而无需输入密码。


6
如果使用的/path/to/my/program是python脚本,这是否仍然有效?
sadmicrowave 2014年

程序可以改为bash的别名(即.bashrc)吗?甚至是其中的shell脚本/usr/local/sbin?尝试。
Nikos Alexandris

Nikos-不,它不能是别名。它必须指向一条真实的道路。
Paul Hedderly

sudoers?哪里?希望使用您的答案(
Vasilii Suricov

@VasiliiSuricov:通常在中/etc,但是某些系统将其放在其他位置。如果找不到,请尝试man sudoers。该文件的本地位置应mansudo为该系统构建时替换到页面中。
沃伦·杨

135

如果中有多个匹配条目/etc/sudoers,则sudo使用最后一个。因此,如果您可以在带密码提示的情况下执行任何命令,并且希望能够在没有密码提示的情况下执行特定的命令,则最后需要例外。

myusername ALL = (ALL) ALL
myusername ALL = (root) NOPASSWD: /path/to/my/program

请注意,使用(root),以允许该程序以root用户而不是其他用户身份运行。(除非您已经考虑了潜在的影响,否则请不要授予超出所需最低权限的更多权限。)

对于未运行Ubuntu或已更改默认sudo配置的读者(请注意,Ubuntu的sudo默认是可以的):运行具有提升特权的shell脚本是有风险的,您需要从干净的环境开始(一旦shell启动,为时已晚(请参阅在shell脚本上允许setuid,因此您需要sudo来解决)。确保Defaults env_resetin /etc/sudoers或此选项是编译时的默认值(sudo sudo -V | grep env应包含Reset the environment to a default set of variables)。


3
ex从jhon到sudo su都无法通过-----> john ALL =(ALL)NOPASSWD:/ bin / su
bortunac 2014年

5
@adrian如果要允许任意命令作为root用户,请设置为john ALL=(ALL) NOPASSWD: all。通过没有意义su
Gilles 2014年

问题:为了安全起见,我是否应该更改外壳程序脚本的权限,以便只能由root用户对其进行修改和读取?我正在考虑攻击者修改脚本,该脚本无需授予密码即可授予所有权限,从而可以执行他/她想要的操作。显然,攻击者甚至无法读取sudoers文件来了解哪些脚本具有该特权,但是一旦他/她找到了存储它们的文件夹,便可以尝试使用我所有的自定义脚本,希望允许某些或类似的东西。 。
Jeffrey Lebowski

1
@JeffreyLebowski如果您有一个(直接或间接)运行脚本的sudo规则,那么至关重要的是只有root(或始终具有root特权的人)才能写入脚本文件,包含脚本文件的目录以及其父目录等。没关系,任何人都可以读取脚本文件(除非它包含密码或其他内容,但这不是一个好主意,如果有密码,则应将其保存在自己的文件中,否则存在意外泄漏的风险,例如通过将代码的该部分复制粘贴到此站点的问题中)。
吉尔斯(Gilles)

1
@alper否。很少需要重启。更改后sudoers,您无需执行任何特殊操作:sudo每次检查一次。
吉尔斯

24

警告:此答案被认为是不安全的。见下面的评论

完整的解决方案:以下步骤将帮助您实现所需的输出:

  1. 创建一个新的脚本文件(替换create_dir.sh为所需的脚本名称):

    vim ~/create_dir.sh
    

    该脚本将在用户的主目录中创建

  2. 添加只有a rootsudo用户才能执行的一些命令,例如在根目录级别创建文件夹:

    mkdir /abc
    

    注意:请勿添加sudo到这些命令。保存并退出(使用:wq!

  3. 使用以下命令为其分配执行权限:

    sudo chmod u+x create_dir.sh
    
  4. 进行更改,以便此脚本不需要密码。

    1. 打开sudoers文件:

      sudo visudo -f /etc/sudoers
      
    2. 在末尾添加以下行:

      ahmad ALL=(root) NOPASSWD: /home/ahmad/create_dir.sh
      

      替换ahmad为您的用户名。还要确保这是最后一行。保存并退出。

  5. 现在,在运行命令时,请在命令sudo之前添加:

    sudo ./create_dir.sh
    

    这将在脚本文件中运行命令,而无需输入密码。

请遵循此处提到的简单步骤http://step4wd.com/2013/09/14/run-root-commands-in-linux-ubuntu-without-password/


如果您在此处提供了相关步骤,并将链接用作更多详细信息的备份,那将更好。这样,即使该链接不再有效,您的答案仍会保留可能的价值。
Anthon 2013年

15
这个建议是不安全的。该sudo部分sudo chmod u+x create_dir.sh是不必要的,因为用户(大概)拥有其主目录的所有权。由于用户可以写入create_dir.sh,因此您已经有效地为该用户提供了免费的root shell。
Lekensteyn

1
@Lekensteyn这也意味着以用户身份运行的任何程序。也可以只允许用户使用sudo运行任何操作而无需输入密码。
pydsigner

2
我想念什么吗?我认为,整个过程chmod都是不必要的,因为您依赖于sudo提升特权。
G-Man

10

我认为您的语法有误。至少我使用以下对我有用的东西:

myusername ALL=(ALL) NOPASSWD: /path/to/executable

6
(ALL)部分是可选的,省去它具有完全相同的效果。拥有(root)虽然会更好,但是缺少它并不能解释问题。
吉尔斯

此命令的sudo +1,仅此而已!没有理由破坏整个系统……
Johan

3
@Johan:那已经是问题了。
吉尔斯(Gilles)

5

如果要避免使用sudo或不必更改sudoers配置文件,则可以使用:

sudo chown root:root path/to/command/COMMAND_NAME
sudo chmod 4775 path/to/command/COMMAND_NAME

这将使命令以root身份运行,而无需sudo。


哇,我以前从没听说过这种解决方案,真是令人费解
事情发生

为什么我需要滚动到这些内容的底部才能找到最佳答案?感谢您提供此简单的安全解决方案。
RyanNerd

5

如果您有像Manjaro这样的发行版,则必须首先处理覆盖/ etc / sudoers定义的文件,您可以将其删除或直接使用该文件来添加新配置。

该文件是:

sudo cat /etc/sudoers.d/10-installer

唯一的查看方式是在根特权下,如果没有该目录,您将无法列出该目录,该文件是Manjaro特有的,您可能会在其他目录中找到该配置的其他名称。

在您选择的文件中,您可以添加以下行以获得所需的配置:

忽略组的身份验证

%group ALL=(ALL) NOPASSWD: ALL

或忽略用户的身份验证

youruser ALL=(ALL) NOPASSWD: ALL

或忽略身份验证特定用户的可执行文件

youruser ALL=(ALL) NOPASSWD: /path/to/executable

快速说明:您正在打开无需身份验证即可使用SUDO的大门,这意味着您可以运行一切以修改系统中的所有内容,并负责任地使用它。


4

验证sudo是否没有别名。这样跑

/usr/bin/sudo /path/to/my/program

例如这样的shell别名:

alias sudo="sudo env PATH=$PATH"

可能会导致这种行为。


您是正确的,我的评论在这里混乱了,对此表示抱歉。不过,我很感兴趣-您如何期望别名会更改sudoerssudo 的处理。还是在谈论重定向sudo到总是打印此错误消息以获取密码的内容?这在这里不太可能……
彼得

2
我遇到了与OP相同的问题。原来是alias sudo="sudo env PATH=$PATH"我的身体造成的~/.bashrc。我提交的答案不仅是为自己解决问题,也只是盲目地从事我的业务,​​它是针对与此线程相关的任何其他人的可能解决方案。
Sepero 2014年

1
很好,但是当它不明显时(在这种情况下,至少对某些人来说不是),最好在答案中添加一个解释以提供一些背景信息,并防止人们盲目地使用魔咒。+2(-(-1)+ +1)。:)
彼得

2

执行脚本时,需要以身份运行sudo /path/to/my/script

编辑:根据您对另一个答案的评论,您想从一个图标运行它。您将需要创建一个.desktop使用sudo执行程序的文件,就像在终端上一样。

您也可以考虑使用gtk-sudo可视密码提示。

您可能应该考虑这样一种想法,即您不应该以超级用户身份运行事物,并且更远地更改系统以使您完全不需要超级用户权限将是一个更好的方法。


7
不要将shell脚本设为setuid。请参阅在shell脚本上允许setuid
吉尔(Gilles)

我考虑不提它,因为这是一个糟糕的选择。我只是删除了它,因为我担心这个提问者可能会使用该建议,即使警告它是一个坏建议!
卡莱布

2

这为我解决了这个问题(也尝试了一些其他答案,可能有帮助):

我正在调用的脚本位于/usr/bin,我没有写权限的目录中(尽管我通常可以在其中读取任何文件)。该脚本是+ x(可执行的权限),但是仍然无法正常工作。将该文件移动到主目录中的路径,而不是/usr/bin,我终于可以使用sudo调用它而无需输入密码。

我也对此有所怀疑(为以后的读者澄清):您需要以sudo身份运行脚本。类型sudo调用的脚本。不要sudo在脚本中实际需要root的命令中使用命令(在我的情况下,更改键盘背光)。也许这也可行,但是您不需要这样做,这似乎是一个更好的解决方案。


第二段回答了我的问题
艾哈迈德·扎法尔

@MuhammadAhmadZafar很高兴它有所帮助!
吕克(Luc)

3
sudo如果您具有适当的权限(在中设置sudoers)来运行有问题的命令而无需输入密码,那么实际上在脚本内部使用脚本是完全可以的。它使事情更加安全。
彼得2014年

可以真的将这个答案改写为逐步的“这是您的工作方式”,而不是与其他答案进行对话
Walrus the Cat

@WalrustheCat好点。重新阅读我的答案,我想我自己可能有些困惑。但是现在,我不记得确切的情况了,因此我无法真正编写出更好的文章。如果您弄清楚了,也许是几个答案的组合,一定要提交一个新答案!
卢克,

1

另一种可能是安装,配置,然后使用super命令以如下方式运行脚本:

super /path/to/your/script

如果你想运行一些二进制可执行文件(例如,您已经汇编成ELF一些C源代码的二进制) -其不是一个脚本-为根,你可能会考虑将它的setuid(实际上/bin/login/usr/bin/sudo/bin/susuper都使用这种技术)。但是,请非常小心,您可能会打开一个巨大的安全漏洞

具体来说,您的程序应该是偏执的编码(因此,在“执行”之前,请检查所有参数以及环境和外部条件,并假设可能存在敌对用户),然后可以小心使用seteuid(2)和朋友(另请参见setreuid(2)) (另请参阅功能(7)凭据(7)execve(2) ...)

安装这样的二进制文件时,将使用chmod u+s(阅读chmod(1))。

但是要非常小心

在编码之前,请阅读有关setuid的许多知识,包括Advanced Linux Programming

注意,脚本或任何shebang编辑的东西都不能设置为uid。但是您可以(用C语言)编写一个小的setuid-binary包装它。


0

理想情况下,如果要自定义可以通过哪些命令运行,sudo则应在单独的文件下进行这些更改,/etc/sudoers.d/而不是sudoers直接编辑该文件。您还应该始终使用visudo来编辑文件。你不应该授予NOPASSWDALL命令。

例: sudo visudo -f /etc/sudoers.d/mynotriskycommand

插入您的线路授予权限: myuser ALL= NOPASSWD: /path/to/your/program

然后保存并退出,visudo如果您有任何语法错误,则会警告您。

您可以运行sudo -l查看已被授予用户的权限,如果在输出中的NOPASSWD任何%groupyouarein ALL=(ALL) ALL命令之前出现任何特定于用户的命令,系统将提示您输入密码。

如果您发现自己创建了许多此类sudoers.d文件,则可能需要创建按用户命名的文件,以便于查看。请记住,文件名和文件中规则的顺序非常重要,无论是允许的数量还是更少的数量,最后一个加载的都将获胜。

您可以使用00-99或aa / bb / cc前缀来控制文件名的顺序,但是请记住,如果您有任何不带数字前缀的文件,它们将在编号文件后加载,覆盖设置。这是因为,根据语言设置的不同,shell会先使用“数字排序”,然后再按“升序”排序时使用大写和小写形式。

尝试运行printf '%s\n' {{0..99},{A-Z},{a-z}} | sortprintf '%s\n' {{0..99},{A-Z},{a-z}} | LANG=C sort查看您当前使用的语言是否打印AaBbCc等,ABC然后abc确定要使用的最佳“最后”字母前缀是什么。


0

要允许任何用户以sudo身份执行程序而无需询问密码,您可以添加以下行

%sudo ALL=(root) NOPASSWD: /path/to/your/program

/etc/sudoers

请注意,%sudo完成了。


尽管这是完成sudo规则的一种方法,但它无法回答有关为何在此规则上设置NOPASSWD标志仍会导致出现密码提示的问题。有关为什么会发生的想法,请参见已接受的答案。
杰夫·谢勒

0

以下是仅当命令具有一组特定选项(部分选项为变量)时才希望运行不带密码的命令的情况。AFAIK不可能在sudoers声明中使用变量或值范围,即可以允许显式访问command option1但不能command option2使用:

user_name ALL=(root) /usr/bin/command option1

但是,如果结构是command option1 value1value1可以在哪里变化,则您需要为的每个可能值都有明确的sudoers行value1。Shell脚本提供了一种解决方法。

该答案的灵感来自艾哈迈德·扎法尔(M. Ahmad Zafar)的答案,并在那里解决了安全问题。

  1. 创建一个shell脚本,在不调用的情况下调用该命令sudo
  2. 将脚本保存在具有root权限的文件夹中(例如/usr/local/bin/),将文件设置为root拥有(例如chown root:wheel /usr/local/bin/script_name),而其他用户则没有写访问权限(例如chmod 755 /usr/local/bin/script_name)。
  3. 使用visudo将异常添加到sudoers中:

    user_name ALL=(root) NOPASSWD: /usr/local/bin/script_name

  4. 运行您的脚本sudo script_name

例如,我想更改macOS上的显示睡眠超时。使用以下命令完成此操作:

sudo pmset displaysleep time_in_minutes

我认为更改睡眠超时是一种无辜的举动,它不能证明输入密码的麻烦,但pmset可以做很多事情,我想将这些其他事情保留在sudo密码后面。

所以我在下面有以下脚本/usr/local/bin/ds

#!/bin/bash
if [ $# -eq 0 ]; then
        echo 'To set displaysleep time, run "sudo ds [sleep_time_in_minutes]"'
else
        if [[ $1 =~ ^([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$ ]]; then
                pmset displaysleep $1 
        else
                echo 'Time must be 0..180, where 0 = never, 1..180 = number of minutes'
        fi
fi

sudoers文件末尾,我有以下几行:

user_name ALL=(root) NOPASSWD: /usr/local/bin/ds

要将超时设置为3分钟,我从普通用户帐户运行脚本user_name

sudo ds 3

PS我的大部分脚本是输入验证,这不是必需的,因此以下内容也可以工作:

#!/bin/bash
pmset displaysleep $1 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.