Posso impedir que uma pasta com um determinado nome seja criada?

16

Estou trabalhando em um aplicativo da Web LAMP e há um processo agendado em algum lugar que continua criando uma pasta chamada shopna raiz do site. Toda vez que isso aparece, causa conflitos com regras de reescrita no aplicativo, nada bom.

Até encontrar o script incorreto, existe uma maneira de impedir que qualquer pasta chamada shopseja criada na raiz? Sei que posso alterar as permissões em uma pasta para impedir que seu conteúdo seja alterado, mas não encontrei uma maneira de impedir que uma pasta com um determinado nome seja criada.

Andrew
fonte
4
Para descobrir o que está criando, você pode ativar a auditoria .
Andrew Henle

Respostas:

30

Você não pode, dado que o usuário que cria o diretório tem permissão suficiente para gravar no diretório pai.

Em vez disso, você pode alavancar a inotifyfamília de chamadas do sistema fornecidas pelo kernel Linux, para observar a criação (e opcionalmente mv-ing) do diretório shopno diretório especificado, se criado (ou opcionalmente mv) rmo diretório.

O programa userspace necessário neste caso é inotifywait(vem com inotify-tools, instale-o primeiro, se necessário).


Supondo que o diretório shopresidisse no /foo/bardiretório, vamos definir um monitoramento para a /foo/bar/shopcriação e, rminstantaneamente, se criado:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/barobserva o /foo/bardiretório de qualquer arquivo / diretório que possa ser criado, ou seja, observe qualquer createevento

  • Se criado, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'verifica se o arquivo é um diretório e se o nome é shop( /,ISDIR shop$/); se for, rmo diretório ( system("rm -r -- /foo/bar/shop"))

Você precisa executar o comando como um usuário que tenha permissão de gravação no diretório /foo/barpara remoção do shopdiretório.


Se você deseja monitorar mvtambém as operações de gravação, adicione watch for moved_toevent também:

inotifywait -qme create,moved_to /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'

Apenas para observar, se você estiver procurando por um arquivo, não um diretório, chamado 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") }'
heemail
fonte
2
Além disso, se você está usando inotifywaitpara fazer isso também é possível que o gatilho pode também ser capaz de capturar o processo comps -ef
roaima
30

Responder literalmente com base na questão de impedir que uma pasta com um determinado nome seja criada.

touch shop

Você não pode criar um diretório se um arquivo com um nome idêntico existir

mkdir: cannot create directory ‘shop’: File exists

Miati
fonte
6
Isso * pode não ser suficiente. O mkdir pode não fazê-lo, mas pode ser feito. É uma boa primeira tentativa embora.
coteyr
9
Nos sistemas Linux, use chattr +i shoppara torná-lo imutável. Até que o sinalizador imutável seja removido, ele não pode nem ser renomeado / excluído.
R .. GitHub Pare de ajudar o gelo
11
Este é um truque pouco inteligente, não muito bem para a minha situação, mas uma idéia inteligente para certas circunstâncias 👍
Andrew
11
@R .. interessante. Eu esperava rename(2)ainda funcionar, já que o nome não faz parte do inode, mas não funciona. Pesquisa rápida na Internet não revela o porquê. Alguma dica?
Domen #
@domen: Porque isso faz parte do objetivo do atributo "imutável". Eu suspeito que é preciso um trabalho extra não trivial no nível de implementação para impedir que renamefuncione.
R .. GitHub Pare de ajudar o gelo
4

Que tal seqüestrar mkdirsyscall com 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

Observe que dentro deste manipulador você pode registrar o PID do processo que deseja criar este diretório:

$ 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

Você precisa colocá-lo no ~/.bashrcroot (ou em quem estiver executando seu aplicativo) para garantir que isso seja usado:

export LD_PRELOAD=/path/to/test.so
Nykakin
fonte
2
isso não deve ter um voto negativo, é uma solução e uma boa solução
cat
4
Está usando uma bomba nuclear para abrir uma lata de feijão. Mas hey, pelo menos eles vão ser cozido ...
Leveza raças com Monica
2
@cat: eu discordo. LD_PRELOADhacks como esse estão sempre sempre errados e, a menos que você saiba o que está fazendo, eles podem prejudicar o programa em que são carregados, quebrando propriedades como a segurança de sinal assíncrono da função que você está substituindo.
R .. GitHub Pare de ajudar o gelo
11
Além disso, eu acho que fopendeve ter "a", em vez de "w", por isso pode preservar registros anterior
gato
2
Isso também não funcionará se um código incorreto chamar o syscall diretamente, não através da libc. Ou se o código incorreto estiver vinculado estaticamente.
Domen #
3

(Teria comentado a resposta de Miati, mas não me lembro da minha conta antiga e não tenho reputação suficiente nessa nova ...)

Você pode bloquear a criação criando um arquivo e alterando os atributos do arquivo.

$ sudo touch shop
$ sudo chattr +i shop

Qualquer tentativa de fazer qualquer coisa com esse arquivo será bloqueada - mesmo que o usuário se torne root.

$ 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
N. Clements
fonte
2
Se você souber o nome / endereço de e-mail da sua conta antiga, você pode solicitar um merge conta a partir do formulário de contacto ligados na parte inferior de cada página .
Wizzwizz4
Além disso, por que não nos dizer como isso está relacionado à outra resposta, e não por que você decidiu postar?
jpaugh
2

Crie um link simbólico apontando para um local inexistente dentro de um diretório inexistente. Isso tem algumas implicações 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
  1. mkdir, link e outros irão falhar com EEXIST(o arquivo existe).
  2. Tentar abrir o caminho para leitura, gravação ou anexação falhará com ENOENT(Nenhum arquivo ou diretório desse tipo)
  3. O uso de stat (2) (não lstat (2) ou stat (1)) no local também falha com ENOENT. É claro que o lstat retornará as informações sobre o link simbólico.

Isso tem duas vantagens sobre algumas das outras soluções propostas aqui: (a) você não precisa de um serviço em execução que rastreie a criação do diretório e (b) o nome parece não existir para a maioria dos comandos.

Você terá que tentar, mas suspeito que, independentemente das regras de reescrita que você possui, elas não usam lstat ou outros comandos que não fazem referência à referência, fazendo com que falhem.

Jonas Schäfer
fonte