这安全吗?
echo "Defaults insults" >> /etc/sudoers
Run Code Online (Sandbox Code Playgroud)
如果是,我可以这样做吗?
echo "## First line" >> /etc/sudoers
echo "### Second line" >> /etc/sudoers
echo "Defaults insults" >> /etc/sudoers
echo "### Totally the last line" >> /etc/sudoers
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来做到这一点visudo?
我正在制作一个 bash 脚本,这一点需要打开和关闭侮辱。
Sté*_*las 13
至少有 3 种方式可能是危险的:
如果/etc/sudoers不以换行符(whichsudo和visudoallow)结尾,例如,如果它以非终止#includedir /etc/sudoers.d行结尾,则您的命令将使其:
#includedir /etc/sudoers.dDefaults insults
Run Code Online (Sandbox Code Playgroud)
这将破坏它并使其sudo无法使用。
echo可能无法写入完整的字符串,例如,如果文件系统已满。例如,它可能只能写Defaults in. 这又会破坏你的sudoers文件。/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
Run Code Online (Sandbox Code Playgroud)
如果env_editor未设置,则不起作用。
在 GNU 系统上,更好的选择是使用sed -iwhichsudoers.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
Run Code Online (Sandbox Code Playgroud)
去除侮辱:
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
Run Code Online (Sandbox Code Playgroud)
我查了一下,似乎includedir支持可以sudo追溯到很长一段路(据我所知,大约为 2001 年),因此 RHEL 5 应该支持它。在您的 sudoers 中查找包含指令:
sudo grep '#includedir' /etc/sudoers
Run Code Online (Sandbox Code Playgroud)
如果得到结果,那么理想情况下您应该在该目录中添加和删除文件,通常是/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
Run Code Online (Sandbox Code Playgroud)
(99-insults要在sudoers.d.中创建的文件名在哪里。)然后删除设置就像这样简单:
sudo rm /etc/sudoers.d/99-insults
Run Code Online (Sandbox Code Playgroud)
事实上,这就是sh -c命令的最后一部分所做的 - 如果visudo检查失败,则删除此文件,这样您就不会留下损坏的sudoers.
您可以tee -a用作EDITOR:
$ 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
Run Code Online (Sandbox Code Playgroud)
我不知道 EL5sudo是否includedir支持,但如果支持visudo -f,请在其中创建新文件。
| 归档时间: |
|
| 查看次数: |
3568 次 |
| 最近记录: |