私はLAMP Webアプリケーションを開発しており、どこかにshop
サイトルートにあるフォルダを作成し続けるスケジュールされたプロセスがあります。これが発生するたびにアプリケーションの書き換え規則と競合が発生しますが、これは悪いことです。
問題のスクリプトが見つかるまでルートディレクトリにというshop
フォルダが作成されないようにする方法はありますか?コンテンツが変更されないようにフォルダの権限を変更できることはわかっていますが、特定の名前のフォルダが作成されるのを防ぐ方法が見つかりませんでした。
答え1
ディレクトリを作成したユーザーには、親ディレクトリに書き込むための十分な権限があるため、そうすることはできません。
inotify
代わりに、Linuxカーネルが提供する一連のシステムコールを利用して、ディレクトリがすでにmv
作成されている場合(またはオプションで-ed)、指定されたディレクトリでディレクトリの作成(およびオプションで-ing)を監視できます。shop
mv
rm
この場合、必要なユーザースペースプログラムはinotifywait
(一緒に提供されます。inotify-tools
必要に応じて最初にインストールしてください)。
ディレクトリがディレクトリ内にshop
あると仮定し、生成監視を/foo/bar
設定し、生成直後にそれを見てみましょう。/foo/bar/shop
rm
inotifywait -qme create /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
inotifywait -qme create /foo/bar
/foo/bar
作成できるすべてのファイル/ディレクトリのディレクトリを監視します。つまり、すべてのcreate
イベントを監視します。作成された場合は、そのファイルが()
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
という名前のディレクトリであることを確認し、そうである場合はそのディレクトリ()を確認します。shop
/,ISDIR shop$/
rm
system("rm -r -- /foo/bar/shop")
ディレクトリから削除するには、ディレクトリへの書き込み権限を持つユーザーとしてコマンドを実行する必要があります/foo/bar
。shop
-ingジョブを監視するには、mv
イベント監視も追加しますmoved_to
。
inotifywait -qme create,moved_to /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
ディレクトリの代わりに名前付きファイルを探す場合は、次の点に注意してくださいshop
。
inotifywait -qme create /foo/bar | \
awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'
inotifywait -qme create,moved_to /foo/bar | \
awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'
答え2
予防の質問に文字通り答えてくださいフォルダ生成する特定の名前です。
touch shop
同じ名前のファイルがある場合は、ディレクトリを作成できません。
mkdir: cannot create directory ‘shop’: File exists
答え3
mkdir
以下を使ってシステムコールをハイジャックするのはどうですかLD_PRELOAD
?
$ ls
test.c
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) return 1;
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test test.c test.so
このハンドラでは、このディレクトリを作成するプロセスのPIDを記録できます。
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) {
FILE* fp = fopen("/tmp/log.txt", "w");
fprintf(fp, "PID of evil script: %d\n", (int)getpid());
fclose(fp);
}
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt
PID of evil script: 8706
~/.bashrc
使用するには、ルートディレクトリ(またはアプリケーションを実行している人)に配置する必要があります。
export LD_PRELOAD=/path/to/test.so
答え4
存在しないディレクトリの存在しない場所へのシンボリックリンクを作成します。ここにはいくつかの興味深い意味があります。
$ ln -s non-existent/foobar foo
$ ls -ln
total 0
lrwxrwxrwx 1 1000 1000 19 Okt 4 17:17 foo -> non-existent/foobar
$ mkdir foo
mkdir: cannot create directory ‘foo’: File exists
$ cat foo
cat: foo: No such file or directory
$ echo foo > foo
zsh: no such file or directory: foo
EEXIST
mkdir、リンク、その他のファイルは(ファイル付き)エラーのため失敗します。- 読み取り、書き込み、または追加のためにパスを開こうとすると失敗します
ENOENT
(ファイルまたはディレクトリなし)。 - その場所でstat(2)(lstat(2)またはstat(1)ではない)を使用すると、
ENOENT
lstatも失敗します。もちろん、シンボリックリンクに関する情報が返されます。
ここで提案されている他のソリューションに比べて2つの利点があります。 (a) ディレクトリ生成を追跡するサービスを実行する必要はありません。 (b) ほとんどのコマンドに名前が存在しないようです。
試してみる必要があります。ただし、書き換え規則が何であれ、lstatや他の非参照コマンドを使用しないため、失敗する可能性があります。