[unix] 특정 이름의 폴더가 생성되는 것을 막을 수 있습니까?

LAMP 웹 앱에서 작업 중이며 shop사이트의 루트에 있는 폴더를 계속 만드는 예약 프로세스 가 있습니다. 이것이 나타날 때마다 앱의 다시 쓰기 규칙과 충돌이 발생하지만 좋지 않습니다.

문제가있는 스크립트를 찾을 때까지 shop루트에 폴더 가 만들어 지지 않도록하는 방법이 있습니까? 폴더의 내용이 변경되지 않도록 폴더에 대한 권한을 변경할 수 있지만 특정 이름의 폴더가 생성되는 것을 방지하는 방법을 찾지 못했습니다.



답변

디렉토리를 작성하는 사용자에게 상위 디렉토리에 쓸 수있는 충분한 권한이 있으면 부여 할 수 없습니다.

대신 inotifyLinux 커널이 제공하는 시스템 호출 제품군을 활용하여 디렉토리가 작성되거나 선택적으로 -ed 인 경우 지정된 디렉토리에서 mv디렉토리 의 작성 (및 선택적으로 -ing) 을 감시 할 수 있습니다.shopmvrm

이 경우 필요한 사용자 공간 프로그램은 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하려면 디렉토리에 대한 쓰기 권한이있는 사용자로 명령을 실행해야합니다 .


mv-ing 조작도 모니터하려면 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") }'


답변

특정 이름 의 폴더 를 만들 수 없다는 문제에 따라 문자 그대로 대답 합니다 .

touch shop

동일한 이름의 파일이 존재하면 디렉토리를 만들 수 없습니다

mkdir: cannot create directory ‘shop’: File exists


답변

mkdirsyscall을 하이재킹하는 것은 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


답변

(Miati의 답변에 대해 언급했지만 내 오래된 계정을 기억할 수 없으며이 새로운 계정에 대한 명성이 충분하지 않습니다 …)

파일을 작성한 다음 파일 속성을 변경하여 작성을 차단할 수 있습니다.

$ sudo touch shop
$ sudo chattr +i shop

그런 다음 사용자가 루트가 되더라도 해당 파일로 작업을 시도하면 차단됩니다.

$ rm shop
rm: remove write-protected regular empty file ‘shop’? y
rm: cannot remove ‘shop’: Operation not permitted
$ sudo rm shop
rm: cannot remove ‘shop’: Operation not permitted


답변

존재하지 않는 디렉토리 내부에 존재하지 않는 위치를 가리키는 심볼릭 링크를 만듭니다. 여기에는 몇 가지 재미있는 의미가 있습니다.

$ 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
  1. mkdir, 링크 및 기타가 실패합니다 EEXIST (파일이 존재 함).
  2. 읽기, 쓰기 또는 추가를위한 경로를 열려고하면 실패합니다. ENOENT (파일 또는 디렉토리가 없음).
  3. 위치에서 stat (2) (lstat (2) 또는 stat (1) 아님)를 사용하면로 실패합니다 ENOENT. lstat는 물론 심볼릭 링크에 대한 정보를 반환합니다.

여기에 제안 된 다른 솔루션 중 일부에 비해 두 가지 장점이 있습니다. (a) 디렉토리 생성을 추적하는 서비스가 필요하지 않으며 (b) 이름이 대부분의 명령에 존재하지 않는 것 같습니다.

당신은 그것을 쏴야 할 것이지만, 나는 당신이 가진 다시 쓰기 규칙이 lstat 나 다른 비 참조 명령을 사용하지 않아서 실패한다고 생각합니다.


답변