如何通过脚本编辑/ etc / sudoers?


116

我需要编辑 /etc/sudoers从脚本中,才能从白名单中添加/删除内容。

假设我有一个适用于普通文件的命令,我该如何将其应用于/etc/sudoers

我可以复制和修改它,然后visudo用修改后的副本替换原件吗?通过提供我自己的脚本$EDITOR

还是可以只使用相同的锁和cp

问题不仅仅是潜在的问题,而不仅仅是找到有效的方法。

Answers:


146

旧线程,但是如何:

echo 'foobar ALL=(ALL:ALL) ALL' | sudo EDITOR='tee -a' visudo

10
这是一个很好的答案。整个子shell应该以root身份执行,例如echo "$USER ALL=NOPASSWD:/usr/bin/rsync" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/rsync')
simon

3
这个答案很棒!我将它用于debian软件包中的postinst skripts。谢谢!由于这始终是根,因此它变得简短易用:echo "$CONFIGLINE" | (EDITOR="tee -a" visudo)
BorisDäppen16年

3
我只想指出@BorisDäppen的答案的一个主要细微差别:-a标记为EDITOR="tee":它将在文件后追加行,而不仅仅是覆盖第一行。起初我没有发现不同之处,也无法确定添加方式。我希望我能通过直接指出来找到一些人;-)
Jean-Philippe Murray

3
有人可以解释一下我的工作原理,不是EDITOR ='tee -a'之后需要的分号。我知道这会破坏命令。EDITOR是一个shell变量,而visudo是另一个命令,因此在这里,我们在同一命令行中传递EDITOR和visudo。这真的如何工作?
Sagar

1
我试过这个x =“ something” echo $ x。这对我不起作用。
萨加尔

43

为此,使用visudo和自定义编辑器。这解决了Brian的解决方案中的所有比赛条件和“ hack”问题。

#!/bin/sh
if [ -z "$1" ]; then
  echo "Starting up visudo with this script as first parameter"
  export EDITOR=$0 && sudo -E visudo
else
  echo "Changing sudoers"
  echo "# Dummy change to sudoers" >> $1
fi

该脚本会将“#Dummy change to sudoers”添加到sudoers的末尾。没有黑客,没有比赛条件。

带注释的版本说明了其实际工作方式:

if [ -z "$1" ]; then

  # When you run the script, you will run this block since $1 is empty.

  echo "Starting up visudo with this script as first parameter"

  # We first set this script as the EDITOR and then starts visudo.
  # Visudo will now start and use THIS SCRIPT as its editor
  export EDITOR=$0 && sudo -E visudo
else

  # When visudo starts this script, it will provide the name of the sudoers 
  # file as the first parameter and $1 will be non-empty. Because of that, 
  # visudo will run this block.

  echo "Changing sudoers"

  # We change the sudoers file and then exit  
  echo "# Dummy change to sudoers" >> $1
fi

5
这要求sudo已使用进行编译--enable-env-editor,否则,如果它是一小套已知值之一,则只会使用尊重编辑器变量。
Caleb 2012年

它对我有用(Ubuntu 12.04),但我不知道它是如何工作的。有人可以解释如何正确使用它以及它如何实际工作吗?谢谢
MountainX

请注意,在12.04精确版上,这似乎对我不起作用。我创建了一个bash脚本,为其添加了+ x权限,并使用以下输出执行了该文件:visudo:无法运行/ tmp / edit_sudoers:Exec格式错误visudo:/etc/sudoers.tmp不变
Jose Diaz-Gonzalez

尽管我只是以root用户身份登录并sudo -E从第一个命令中删除了该命令,但是这对我来说非常有用。
merlin2011'4

我真的很喜欢这个答案,但是它对我没有用。我认为我的sudo没有使用必要的标志进行编译。
Mnebuerquo '16

30

您应该对临时文件进行编辑,然后使用visudo -c -f sudoers.temp确认更改是否有效,然后将其复制到/ etc / sudoers的顶部

#!/bin/sh
if [ -f "/etc/sudoers.tmp" ]; then
    exit 1
fi
touch /etc/sudoers.tmp
edit_sudoers /tmp/sudoers.new
visudo -c -f /tmp/sudoers.new
if [ "$?" -eq "0" ]; then
    cp /tmp/sudoers.new /etc/sudoers
fi
rm /etc/sudoers.tmp

您似乎正在将sudoers.tmp用作锁定文件,不确定如何确认更改是否有效。我们不应该检查visudo的退出状态以确保没有错误吗?
converter42

/etc/sudoers.tmp是visudo在交互模式下检查的锁定文件。visudo -c -f如果存在错误,则返回1,因此检查返回代码。
Brian C. Lane

我担心使用sudoers.tmp,因为它看起来像使用visudo的内部接口,即黑客一样。它是标准的,这意味着保证总是被用作锁的sudoers.tmp吗?还是他们将来有改变这种自由的自由?
n-alexander

2
需要使用锁文件而不是测试/触摸
n-alexander

2
手册页说它使用/tmp/sudoers.tmp,因此目前是标准。当然,将来可能会改变。是的,你是对的,有比赛条件。
Brian C. Lane


11

visudo应该是用于编辑的人机界面/etc/sudoers。您可以通过直接替换文件来实现相同目的,但是您必须注意并发编辑和语法验证。注意r--r-----权限。


9

如果您sudo允许在中添加条目/etc/sudoers.d,则可以通过@ dragon788使用以下答案:

https://superuser.com/a/1027257/26022

基本上,visudo在将文件复制到之前/etc/sudoers.d,您通常会先进行验证。因此,可以确保不会破坏sudo任何人。

visudo -c -q -f filename

这种检查,并返回成功(0),如果它是有效的,所以你可以使用它if&&和其他脚本布尔运算。验证后,只需将其复制到中即可/etc/sudoers.d使用。确保其归root所有,不可被其他人写入。


5

设置自定义编辑器。基本上,它将是一个接受文件名的脚本(在本例中为/etc/sudoers.tmp),然后对其进行修改并将其保存在适当的位置。这样您就可以写出该文件了。完成后,退出脚本,而visudo将为您修改实际的sudoers文件。

sudo EDITOR=/path/to/my_dummy_editor.sh visudo

我是否正确说明dummy_editor.sh需要包含的所有内容都是这样的?#!/bin/sh; echo "# my changes to sudoers" >> $1; exit 0它似乎为我工作。
2013年

4

许多答案都与sudo一起用于yonks,但直到现在都不需要自动化安装配置。我混合使用了上面的一些答案,将配置行写入/etc/sudoers.d包含位置,因此我不必修改主sudoers文件,然后检查该文件的语法,下面是简单的示例:

将您的行写到sudoers包含文件中:

sudo bash -c 'echo "your_user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/99_sudo_include_file'

检查您的sudoers包含文件是否通过了visudo语法检查:

sudo visudo -cf /etc/sudoers.d/99_sudo_include_file

只需省略星号,那不应该在那里^^
Sonata

它并返回成功(0)–得到它
Oleg

2

只是在上面的答案中添加了一个其他选项,如果竞争条件不是主要问题,则可以使用以下命令来避免将修改后的文件手动复制到 /etc/sudoers

sudo EDITOR="cp /tmp/sudoers.new" visudo

这将确保通过权限更新验证并正确安装了新文件。

请注意,如果是在一个错误/tmp/sudoers.new的文件,然后visudo会提示用户输入所以它是可取的,以检查它visudo -c -f /tmp/sudoers.new第一。


1

我认为最直接的解决方案是:

创建一个脚本addsudoers.sh

#!/bin/sh

while [ -n "$1" ]; do
    echo "$1    ALL=(ALL:ALL) ALL" >> /etc/sudoers;
    shift # shift all parameters
done

并与您要添加为的用户一起调用它:

root prompt> ./addsudoers.sh user1 user2

有关完整说明,请参见以下答案: 通过shell脚本将用户添加到sudoers

问候!


0

尝试回声它。但是,您必须在子外壳中运行它。例:

sudo sh -c "echo \"group ALL=(user) NOPASSWD: ALL\" >> /etc/sudoers"


-2

根据其他人在这里发布的内容,这对我有用。当我使用其他人的脚本时,它将为我打开visudo,但不会进行编辑。进行此编辑后,我需要允许所有用户(包括标准用户)安装适用于Safari / Firefox的Java 7u17。

#!/usr/bin/env bash
rm /etc/sudoers.new
cp /etc/sudoers /etc/sudoers.new
echo "%everyone   ALL = NOPASSWD: /usr/sbin/installer -pkg /Volumes/Java 7 Update 17/Java 7 Update 17.pkg -target /" >> /etc/sudoers.new
cp /etc/sudoers.new /etc/sudoers

这会将%everyone blah blah添加到sudoers文件的底部。我必须像这样运行脚本。

sudo sh sudoersedit.sh

祝你好运:D

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.