修正する

修正する

コマンドラインの次の行は、私のユースケースを説明しています。

コマンドラインパラメータのワイルドカード文字は慎重に使用する必要があります。コマンドライン引数は単一の接続文字列で一致するため、ワイルドカード文字(「?」)または「*」は複数の単語と一致できます。たとえば、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

実際、これはシェルスクリプトなので、独自の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*

関連情報