
Estoy trabajando en una aplicación web LAMP y hay un proceso programado en algún lugar que sigue creando una carpeta llamada shop
en la raíz del sitio. Cada vez que esto aparece, causa conflictos con las reglas de reescritura en la aplicación, lo cual no es bueno.
Hasta que encuentre el script infractor, ¿hay alguna manera de evitar que shop
se cree cualquier carpeta llamada en la raíz? Sé que puedo cambiar los permisos de una carpeta para evitar que se cambie su contenido, pero no he encontrado una manera de evitar que se cree una carpeta con un nombre determinado.
Respuesta1
No puede, dado que el usuario que crea el directorio tiene permiso suficiente para escribir en el directorio principal.
En su lugar, puede aprovechar la inotify
familia de llamadas al sistema proporcionadas por el kernel de Linux, para observar la creación (y opcionalmente mv
-ing) del directorio shop
en el directorio dado, si se crea (u opcionalmente mv
-ed), rm
el directorio.
El programa de espacio de usuario que necesita en este caso es inotifywait
(viene con inotify-tools
, instálelo primero si es necesario).
Suponiendo que el directorio shop
residiría en /foo/bar
el directorio, establezcamos un monitoreo para /foo/bar/shop
la creación y, rm
al instante, si se crea:
inotifywait -qme create /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
inotifywait -qme create /foo/bar
vigila/foo/bar
el directorio para cualquier archivo/directorio que pueda crearse, es decir, vigila cualquiercreate
eventoSi se crea,
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
verifica si el archivo es un directorio y el nombre esshop
(/,ISDIR shop$/
), de ser así,rm
el directorio (system("rm -r -- /foo/bar/shop")
)
Debe ejecutar el comando como usuario que tiene permiso de escritura en el directorio /foo/bar
para eliminarlo shop
del directorio.
Si también desea monitorear mv
las operaciones de -ing, agregue también observar el moved_to
evento:
inotifywait -qme create,moved_to /foo/bar | \
awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
Solo para tener en cuenta, si está buscando un archivo, no un directorio, llamado 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") }'
Respuesta2
Para responder literalmente a la pregunta de cómo prevenir unacarpetade un determinado nombre a crear.
touch shop
No puede crear un directorio si existe un archivo con un nombre idéntico
mkdir: cannot create directory ‘shop’: File exists
Respuesta3
¿Qué pasa con el secuestro mkdir
de syscall con 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
Tenga en cuenta que dentro de este controlador puede registrar el PID del proceso que desea crear este directorio:
$ 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
Debe colocar esto en ~/.bashrc
la raíz (o en quien esté ejecutando su aplicación) para asegurarse de que se use:
export LD_PRELOAD=/path/to/test.so
Respuesta4
Cree un enlace simbólico que apunte a una ubicación inexistente dentro de un directorio inexistente. Esto tiene algunas implicaciones divertidas:
$ 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
- mkdir, link y otros fallarán con
EEXIST
(El archivo existe). - Intentar abrir la ruta para leer, escribir o agregar fallará con
ENOENT
(No existe tal archivo o directorio) - El uso de stat(2) (no lstat(2) o stat(1)) en la ubicación también falla con
ENOENT
. Por supuesto, lstat devolverá la información sobre el enlace simbólico.
Esto tiene dos ventajas sobre algunas de las otras soluciones propuestas aquí: (a) no necesita ejecutar un servicio que rastree la creación del directorio y (b) el nombre parece no existir para la mayoría de los comandos.
Tendrás que intentarlo, pero sospecho que cualesquiera que sean las reglas de reescritura que tengas, no usan lstat u otros comandos sin desreferencia, lo que las hace fallar.