'echo“默认侮辱”>> /etc/sudoers' 安全吗?

'echo“默认侮辱”>> /etc/sudoers' 安全吗?

这安全吗?

echo "Defaults    insults" >> /etc/sudoers

如果是,我可以这样做吗?

echo "## First line" >> /etc/sudoers
echo "### Second line" >> /etc/sudoers
echo "Defaults    insults" >> /etc/sudoers
echo "### Totally the last line" >> /etc/sudoers

有没有更好的方法来做到这一点visudo

我正在制作一个 bash 脚本,这部分需要打开和关闭侮辱。

答案1

至少有 3 种方式可能造成危险:

  1. 如果/etc/sudoers不以换行符结尾(其中sudovisudo允许),例如,如果它以非终止#includedir /etc/sudoers.d行结尾,则您的命令将使其:

    #includedir /etc/sudoers.dDefaults insults
    

    这会破坏它并使其sudo无法使用。

  2. echo可能无法写入完整的字符串,例如文件系统已满。例如,它可能只能写Defaults in。这又会破坏你的sudoers文件。
  3. 在具有多个管理员的计算机上,如果两者都尝试/etc/sudoers同时修改,则他们写入的数据可能会交错。

visudo避免了这些问题,因为它允许您编辑临时文件 ( /etc/sudoers.tmp),检测文件是否被修改(不幸的是,如果文件被修改则不会)成功地修改,因为它似乎没有检查编辑器的退出状态),检查语法,并执行rename(原子操作)将新文件移动到位。因此,它将要么成功更新文件(前提是您的编辑器在无法写入新文件的情况下也保持文件不变),要么如果不能或语法无效则失败。

visudo还可以防止多人sudoers同时编辑文件。

现在,visudo以自动方式可靠地使用也很棘手。这样做有几个问题:

  • visudo您可以使用环境变量指定编辑器命令VISUAL(优先于EDITOR),但前提是该env_editor选项尚未禁用。
  • 我的版本visudo至少在某些条件下编辑/etc/sudoers它包含的所有文件($VISUAL为所有文件运行)。所以你必须确保你$VISUAL只修改/etc/sudoers.
  • 如上所示,它不检查编辑器的退出状态。因此,您需要确保编辑器保存的文件已成功写入或根本没有修改。
  • 如果出现问题,它会提示用户。

解决所有这些问题有点棘手。您可以这样做:

NEW_TEXT='Defaults insults' \
  CODE='
    if [ "$2" = /etc/sudoers.tmp ]; then
      printf >&2 "Editing %s\n" "$2"
      umask 077
      {
        cat /etc/sudoers.tmp && printf "\n%s\n" "$NEW_TEXT"
      } > /etc/sudoers.tmp.tmp &&
        mv -f /etc/sudoers.tmp.tmp /etc/sudoers.tmp
    else
      printf >&2 "Skipping %s\n" "$2"
    fi' \
  VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

env_editor如果未设置则不起作用。

在 GNU 系统上,更好的替代方法是使用which ,如果无法编写较新的版本,sed -i则应保持不变:sudoers.tmp

添加insults

SED_CODE='
  /^[[:blank:]]*Defaults.*insults/,${
    /^[[:blank:]]*Default/s/!*\(insults\)/\1/g
    $q
  }
  $a\Defaults insults' \
CODE='
  if [ "$2" = /etc/sudoers.tmp ]; then
    printf >&2 "Editing %s\n" "$2"
    sed -i -- "$SED_CODE" "$2"
  else
    printf >&2 "Skipping %s\n" "$2"
  fi' \
VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

消除侮辱:

SED_CODE='
  /^[[:blank:]]*Defaults.*insults/,${
    /^[[:blank:]]*Defaults/s/!*\(insults\)/!\1/g
    $q
  }
  $a\Defaults !insults' \
CODE='
  if [ "$2" = /etc/sudoers.tmp ]; then
    printf >&2 "Editing %s\n" "$2"
    sed -i -- "$SED_CODE" "$2"
  else
    printf >&2 "Skipping %s\n" "$2"
  fi' \
VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

答案2

我查了一下,似乎很久以前includedir就可以提供支持sudo(据我所知大约是 2001 年),所以 RHEL 5 应该支持它。在 sudoers 中查找包含指令:

sudo grep '#includedir' /etc/sudoers

如果您得到结果,那么理想情况下您应该在该目录中添加和删除文件,通常是/etc/sudoers.d.在 shell 脚本中可能很难确定该路径。

无论如何,假设sudoers.d,您最多应该0600在该目录中添加具有权限的文件。就像是:

sudo sh -c '
  umask 0177;
  filename="/etc/sudoers.d/$1";
  echo 'Defaults insults' > "$filename";
  visudo -cf "$filename" || rm "$filename"
' _ 99-insults

99-insults其中要创建的文件的名称在哪里sudoers.d。)然后删除设置就像这样简单:

sudo rm /etc/sudoers.d/99-insults

事实上,这就是sh -c命令的最后一部分的作用 - 如果检查失败,则删除此文件visudo,这样您就不会留下损坏的sudoers.


您可以使用tee -aEDITOR

$ sudo VISUAL='tee -a' visudo <<<"Defaults insults"
Defaults insults
$ sudo tail /etc/sudoers
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
Defaults insults

我不知道 EL5 是否sudo支持includedir,但如果支持,请在其中创建新文件visudo -f

相关内容