Estou procurando um local seguro para colocar soquetes de domínio Unix que serão usados para controlar um REPL.
No Linux, eu usaria o /run/user/$UID
, que atende a todos os requisitos, exceto portabilidade. Preciso que o programa que os trata seja portátil.
Uma opção é usar um diretório abaixo, ~
mas isso apresenta um problema diferente: o diretório inicial do usuário pode estar em um diretório muito profundo para ser capaz de vincular um soquete de domínio Unix, devido ao limite no comprimento do caminho.
Colocar o soquete em um diretório /tmp
é portátil, mas estou preocupado com as condições de corrida ao remover o diretório. Também estou preocupado se /tmp
é possível ter o sticky bit definido em todas as plataformas (ou seja, para que os usuários não possam excluir ou renomear os arquivos temporários de outros usuários). Estou assumindo que /tmp
é pegajoso, no entanto, pois de outra forma muitos, muitos aplicativos (todos os scripts que usam mkstemp
) são inseguros.
Meu plano atual é que o servidor crie um diretório temporário /tmp
e que os clientes verifiquem a propriedade do diretório que o contém antes de usar o soquete. Isso é adequado para segurança?
Responder1
Ode direitopadrãoa localização dos arquivos temporários é fornecida na variável de ambiente TMPDIR
.
Esta variável deverá representar um caminho de um diretório disponibilizado para programas que necessitam de um local para criar arquivos temporários.
Na verdade, muitos sistemas não definem TMPDIR
. Ode fatoo local padrão para arquivos temporários é /tmp
. Portanto, verifique TMPDIR
e, se não estiver definido, use /tmp
. Em um script de shell, você pode usar ${TMPDIR:-/tmp}
ou, se achar mais conveniente,
if [ -z "$TMPDIR" ]; then TMPDIR=/tmp; fi
ou para lidar comset -u
: "${TMPDIR:=/tmp}"
Você pode assumir que este local é gravável, mas pode ser legível e gravável mundialmente, então:
- Ao criar um arquivo normal, certifique-se sempre de não substituir um arquivo existente, que pode não pertencer a você. Não use um redirecionamento de shell para isso. Não é seguro testar a propriedade separadamente porque um adversário pode mover links simbólicos enquanto o seu programa está em execução para enganar as verificações. Além disso, você não pode confiar na inexistência de um nome específico; para evitar que um programa simultâneo crie uma negação de serviço criando um arquivo com o mesmo nome antes de você, use um nome aleatório. Você pode usar o
mktemp
utilitário (difundido, presente no GNU, BusyBox, BSD, mas não no POSIX) ou amkstemp
função da biblioteca C. Sob o capô,open
oucreat
deve ser chamado com aO_EXCL
bandeira. - Você pode criar um diretório com
mkdir
. Isso é seguro contra roubo de propriedade, porque não reutiliza um arquivo existente, mas está sujeito à mesma negação de serviço que os arquivos normais, portanto, você deve usar um nome aleatório.mktemp -d
é uma ótima maneira de fazer isso. - Você pode criar um soquete (não existe um utilitário shell padrão para isso). Assim como o caso do diretório, é seguro contra fraudes de propriedade, mas não contra negação de serviço.
O Linux respeita permissões em soquetes nomeados, mas existem variantes do Unix que não o fazem. É por isso que os soquetes/tmp
geralmente são criados em subdiretórios.
Os programas que criam um subdiretório de /tmp
(ou $TMPDIR
se definido) e criam um soquete nomeado incluem servidores X11, ssh-agent, gpg-agent, KDE, emacs,… (são apenas os que existem na máquina onde estou postando isso ). Como você pode ver, você estará em boa companhia.