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