
私のホームディレクトリにスクリプトがあります。他のユーザーまたはグループが特定のスクリプトを実行するときは、私がログインしたかのように実行され、自分のIDを持つすべての権限を持つ権限を付与する必要があります。 sudoまたはsuを使用してsudoersに設定したり、パスワードを入力したくない。
答え1
sudoを使用すると、権限をきめ細かく分割できます。ユーザーにスクリプトだけを実行し、他の操作を実行しないように権限を付与するには、/ etc / sudoersに次の行を追加します。
user ALL=(yourusername) NOPASSWD: /path/to/your/script
次に、代わりに次を実行します。
sudo -u yourusername /path/to/your/script
答え2
sudoを使う最も簡単な方法です。ただし、これを設定するにはシステム管理者の協力が必要です。
特別な権限なしでこれを実行するには、次のものを使用できます。ユーザーIDの設定実行可能ですが、呼び出し元が意図したよりも多くの操作を実行することを許可しないように注意する必要があります。
ほとんどのUnixバリアントはsetuidシェルスクリプトを無効にします。;例えば、Linuxでは、カーネルは常にスクリプトのsetuidビットを無視します。したがって、ネイティブコードのラッパーが必要です。
ラッパーは、ユーザーがコードを実行するために呼び出すことができるすべてを削除します。たとえば、ホワイトリスト環境変数は、安全でないことが知られている項目(たとえばTERM
)をそのままにしておく必要があります。
これは、環境変数のみを保存するsetuidラッパーの提案ですTERM
。私はそれをレビューしていないか、実際にテストしていないとフィードバックを歓迎します。
/* Compilation command:
c99 -DTARGET='"/absolute/path/to/script"' -o setuid-wrapper setuid-wrapper.c
*/
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
void die(const char *argv0, const char *obj, const char *msg) {
if (msg == NULL) msg = strerror(errno);
fprintf(stderr, "%s: %s: %s\n", argv0, obj, msg);
exit(127);
}
int env_want(const char *entry) {
size_t n;
for (n = 0; entry[n]; n++) {
if (entry[n] == '=') {
break;
} else if (!(isalnum(entry[n]) || entry[n] == '_')) {
return 0;
}
}
if ((n == 7 && !strncmp(entry, "DISPLAY", n)) ||
(n == 10 && !strncmp(entry, "XAUTHORITY", n))) {
return 1;
}
if ((n == 4 && !strncmp(entry, "LANG", n)) ||
(n >= 3 && !strncmp(entry, "LC_", 3)) ||
(n == 2 && !strncmp(entry, "TZ", n))) {
return !strpbrk(entry, "/%");
}
return 0;
}
int main(int argc, char *argv[], char **environ) {
size_t i, j;
const char *program_name = argv[0];
if (program_name == NULL) program_name = "setuid-wrapper";
/* Drop privileges */
if (setgid(getegid())) die(program_name, "setgid", NULL);
/*if (setgroups(0, NULL)) die(program_name, "setgroups", NULL);*/
if (setuid(geteuid())) die(program_name, "setuid", NULL);
/* Sanitize the environment */
for (i = j = 0; environ[i]; i++) {
if (env_want(environ[i])) {
environ[j] = environ[i];
j++;
}
}
environ[j] = NULL;
/* Execute the command */
execle(TARGET, TARGET, NULL, environ);
die(program_name, TARGET, NULL);
}
セカンダリグループはルートでない限り削除できないため、ターゲットプログラムは呼び出し元のセカンダリグループで実行されます。
別の方法は、サーバー(Webサーバーなど)を実行し、そのサーバーからスクリプトを呼び出すことです。 CGIスクリプトをサポートする小規模なHTTPサーバーがたくさんあります。このアプローチの最大の利点は、サーバーがクライアントではなくターゲット(コードが実行されるセキュリティコンテキストの当事者)が選択されたコンテキストで実行されるため、セキュリティがより簡単であることです。
このアプローチの変形は、以下を通過することです。ヒューズファイルシステム例えばスクリプトファイルシステムallow_other
マウントオプションを含むスクリプトを含むディレクトリ。これを行うには、user_allow_other
でオプションを設定する必要があります/etc/fuse.conf
。