更新

更新

命令行中的这些行解释了我的用例:

应谨慎使用命令行参数中的通配符。因为命令行参数作为单个连接字符串进行匹配,所以通配符(例如“?”)或 '*' 可以匹配多个单词。例如,当 sudoers 条目如下:

     %operator ALL = /bin/cat /var/log/messages*

 will allow command like:

     $ sudo cat /var/log/messages.1

 It will also allow:

     $ sudo cat /var/log/messages /etc/shadow

这可能不是我们想要的。

如何让操作员看到所有以 开头的文件/var/log/messages

文件名中不会出现空格。

我希望*像 PCRE 那样行事\S*

更新

由于sudo不支持正则表达式,我在这里创建了一个新问题:https://softwarerecs.stackexchange.com/questions/65887/sudo-alternative-which-supports-pcre

上面的例子来自man sudoers. “命令行参数中的通配符应谨慎使用”部分。

答案1

sudoers 语法没有提供出路,我可能建议编写一个包装器脚本(例如,忽略除第一个参数之外的所有内容,并使用realpath) 和朋友对其进行规范化),但无论如何它都没有用:

sudo cat /var/log/messages/../../../etc/shadow

在不知道您的实际用例的情况下,我只能对联机帮助页中的示例进行评论,为此我想说实际的解决方案是根本不使用 sudo,而是使用 ACL。使用 ACL 授予用户对目录中所有内容的访问权限,文件系统将负责限制他们的访问权限。

答案2

对于你的情况,我认为你能得到的最接近的是:

%operator ALL = /bin/cat /var/log/messages*, !/bin/cat /var/log/messages*\ *

首先,/bin/cat 仅当它具有任何以 开头的“参数字符串”时才允许/var/log/messages,然后如果它在任何点上有空格,则禁止相同的“参数字符串”。

这实际上禁止了 的多个参数cat,但是基于“整个字符串”的基础,它不允许的参数sudo cat /var/log/messages /var/log/messages.1与它不允许的参数一样多sudo cat /var/log/messages /etc/shadow。而且,它不允许合法的文件名有空格,例如假设的/var/log/messages-with-' '-space文件。

答案3

我的首选是自定义脚本,/usr/local/bin/cat-messages用于在外部执行验证sudoers

#!/bin/bash
#
args=()
prefix='/var/log/messages'

for arg in "$@"
do
    # Canonicalise
    real=$(readlink -f "$arg")

    # Check it is a real file matching the prefix
    if [[ "$real" =~ ^"$prefix" ]] && [[ -f "$real" ]]
    then
        args+=("$arg")
    else
        echo "WARNING: skipping $arg" >&2
    fi
done

cat "${args[@]}"

您可以将其添加到sudoers类似这样的行

%operator ALL = NOPASSWD: /usr/local/bin/cat-messages

并且(假设/usr/local/bin在你的中PATH)这样称呼它

sudo cat-messages /var/log/messages.1 /var/log/messages

实际上,由于它是一个 shell 脚本,因此您几乎可以让它使用 来调用自身sudo,从而使用户的生活变得更简单。 (这里不存在安全问题,因为sudo仍然只会考虑/usr/local/bin/cat-messages。)

#!/bin/bash
#
[[ $(id -u) != 0 ]] && exec sudo "$0" "$@"

args=()
prefix='/var/log/messages'
... as before ...

你可以像这样简单地调用这个变体

cat-messages /var/log/messages.1 /var/log/messages

或者

cat-messages /var/log/messages*

相关内容