Estoy buscando un lugar seguro para colocar sockets de dominio Unix que se utilizarán para controlar un REPL.
En Linux, usaría /run/user/$UID
, que cumple con todos los requisitos excepto la portabilidad. Necesito que el programa que los maneja sea portable.
Una opción es usar un directorio debajo, ~
pero eso genera un problema diferente: el directorio de inicio del usuario puede estar en un directorio demasiado profundo para poder vincular un socket de dominio Unix, debido al límite en la longitud de la ruta.
Colocar el socket en un directorio /tmp
es portátil, pero me preocupan las condiciones de carrera al eliminar el directorio. También me preocupa si /tmp
se puede confiar en que el bit adhesivo esté configurado en todas las plataformas (es decir, que los usuarios no puedan eliminar ni cambiar el nombre de los archivos temporales de otros usuarios). Sin embargo, supongo que /tmp
ES pegajoso, ya que de lo contrario muchas, muchas aplicaciones (cada script que usa mkstemp
) son inseguros.
Mi plan actual es que el servidor cree un directorio temporal en /tmp
y que los clientes verifiquen la propiedad del directorio que lo contiene antes de usar el socket. ¿Es esto adecuado para la seguridad?
Respuesta1
Elde jureestándarLa ubicación de los archivos temporales se proporciona en la variable de entorno TMPDIR
.
Esta variable representará un nombre de ruta de un directorio disponible para programas que necesitan un lugar para crear archivos temporales.
De hecho, muchos sistemas no lo definen TMPDIR
. Elde factoLa ubicación estándar para archivos temporales es /tmp
. Así que verifique TMPDIR
y, si no está configurado, use /tmp
. En un script de shell, puede utilizar ${TMPDIR:-/tmp}
, o si lo encuentra más conveniente,
if [ -z "$TMPDIR" ]; then TMPDIR=/tmp; fi
o para hacer frente aset -u
: "${TMPDIR:=/tmp}"
Puede suponer que se puede escribir en esta ubicación, pero puede ser legible y escribible en todo el mundo, por lo que:
- Cuando crea un archivo normal, asegúrese siempre de no sobrescribir un archivo existente, que podría no pertenecerle. No utilice una redirección de shell para esto. No es seguro probar la propiedad por separado porque un adversario puede mover enlaces simbólicos mientras el programa se ejecuta para engañar las comprobaciones. Además, no puede confiar en que un nombre en particular no exista; Para evitar que un programa concurrente cree una denegación de servicio al crear un archivo con el mismo nombre justo antes que usted, utilice un nombre aleatorio. Puede utilizar la
mktemp
utilidad (generalizada, presente en GNU, BusyBox, BSD, pero no en POSIX) o lamkstemp
función de biblioteca C. Debajo del capó,open
ocreat
hay que llamarlo con laO_EXCL
bandera. - Puedes crear un directorio con
mkdir
. Esto es seguro contra el robo de propiedad, porque no reutilizará un archivo existente, pero es propenso a la misma denegación de servicio que los archivos normales, por lo que debe usar un nombre aleatorio.mktemp -d
es una buena manera de hacer esto. - Puede crear un socket (no existe una utilidad de shell estándar para eso). Al igual que en el caso del directorio, es seguro contra engaños de propiedad pero no contra denegación de servicio.
Linux respeta los permisos en sockets con nombre, pero hay variantes de Unix que no lo hacen. Es por eso que los sockets/tmp
generalmente se crean en subdirectorios.
Los programas que crean un subdirectorio de /tmp
(o $TMPDIR
si está configurado) y crean un socket con nombre allí incluyen servidores X11, ssh-agent, gpg-agent, KDE, emacs,... (esos son solo los que existen en la máquina donde estoy publicando esto ). Como puedes ver, estarás en buena compañía.