所有者をに変更するnobody
ことはもちろんあなたの目的に役立ちます。以下に、ユーザーには見えない専用のヘルパープログラムを使用してこれを行う1つの方法を説明します。
解決策: setuidプログラムを使用して、スクリプトが常に同じユーザーとして実行されるようにすることができます。セキュリティ上の理由から、シェルスクリプトをsetuidにすることはおそらく許可されていませんが、Cで簡単なランチャープログラムを作成することはできます。
#include <stdio.h>
#include <unistd.h>
#define PROG "./daemon.sh"
int main(int argc, char** argv)
{
char action[32];
if (argc < 2) {
fprintf(stderr, "Usage: %s { --start | --stop }n", argv[0]);
return 0;
}
snprintf(action, sizeof(action), "%s-the-real-thing", argv[1]);
return execl(PROG, PROG, action, (char *)0);
}
ここでは、スクリプトに名前が付けられdaemon.sh
ており、スクリプトを実行するのと同じディレクトリにあると想定しています。フルパスを使用することも、必要に応じて他の明白な方法で変更することもできます。
次のようにsetuidをコンパイルして作成します(ここで名前launcher.c
を想定し、として実行することにしましたnobody
):
$ gcc -Wall launcher.c -o launcher
$ sudo chown nobody launcher
$ sudo chmod u+s launcher
シェルスクリプトデーモンプログラムを少し変更する必要があります。
#!/bin/sh
prog=$(basename $0)
start()
{
i=0
while :; do
i=$(expr $i + 1)
echo "Daemon working like a mad horse... ($i)"
sleep 1
done
}
stop()
{
pids=$(ps axu | grep "$prog.*--start" | grep -v grep | awk '{print $2}')
echo "Killing [$pids]"
[ -n "$pids" ] && exec /bin/kill -KILL $pids
}
case "$1" in
--start|--stop) exec ./launcher $1;;
--start-the-real-thing) start;;
--stop-the-real-thing) stop;;
*) echo "Bad argument \"$1\"";;
esac
ここでstart
関数は、関数を呼び出してプログラムを強制終了するまで、すべての興味深いファンクが実行される場所stop
です。kill
これをどこからでも実行するには明らかな変更が必要です。既存のロジックがより洗練されていることを願っています。
使用法は以前のようです:
./daemon.sh --start
./daemon.sh --stop
説明:上記は、./launcher --start
または./launcher --stop
、それぞれ実行されます。これにより、有効なユーザーがnobody
(またはプログラムをsetuidするために選択したもの)に変更され、またはいずれ./daemon.sh --start-the-real-thing
か./daemon.sh --stop-the-real-thing
を実行して、目的の元のアクションを実行します。
単純なランチャープログラムでは名前付きスクリプトの実行しか許可されていないため、セキュリティの制御は簡単です(念のため、ランチャープログラムがargv[1]
実際に--start
またはであるかどうかを確認して--stop
から、正確に2つのコマンドラインの組み合わせをとして実行できます)。