Sockets de dominio Unix para usuarios no root

Sockets de dominio Unix para usuarios no root

Trabajo en la aplicación que utiliza socket de dominio Unix para IPC. La forma común, como yo sé, es colocar el archivo socket dentro /var/run. Trabajo con Ubuntu 18.04 y veo que var/runhay un enlace simbólico para /run. Lamentablemente, la carpeta rootsolo es accesible para:

  ls -Al /
  drwxr-xr-x  27 root root        800 Apr 12 17:39 run

Entonces, solo el root tiene acceso de escritura para esta carpeta y eso hace imposible el uso de sockets de dominio Unix para usuarios normales.

En primer lugar, no puedo entender por qué. ¿Y cómo utilizar sockets de dominio Unix para usuarios no root? Puedo usar la carpeta de inicio, por supuesto, pero prefiero usar algún método correcto y común.

Respuesta1

No hay nada de malo en crear el socket en un archivo de puntos o un directorio de puntos en el directorio de inicio del usuario, si el usuario no es algún tipo de usuario especial del sistema. El único problema sería con el directorio de inicio compartido entre varias máquinas a través de nfs, pero eso podría solucionarse fácilmente incluyendo el nombre de host en el nombre del socket.


En Linux/Ubuntu también puedes usar"abstracto"Sockets de dominio Unix, que no utilizan ninguna ruta ni inodo en el sistema de archivos. Los sockets Unix abstractos son aquellos cuya dirección/ruta comienza con un byte NUL:

abstracto: una dirección de socket abstracta se distingue (de un socket de nombre de ruta) por el hecho de que sun_path[0]es un byte nulo ( \0).

La dirección del socket en este espacio de nombres viene dada por los bytes adicionales que sun_pathestán cubiertos por la longitud especificada de la estructura de direcciones. (Los bytes nulos en el nombre no tienen un significado especial). El nombre no tiene conexión con las rutas de acceso del sistema de archivos. Cuando se devuelve la dirección de un socket abstracto, el valor devuelto addrlen es mayor que sizeof(sa_family_t)(es decir, mayor que 2) y el nombre del socket está contenido en los primeros (addrlen - sizeof(sa_family_t))bytes de sun_path.

Cuando se muestran o ingresan por el usuario, los bytes NUL en una dirección abstracta de socket Unix generalmente se reemplazan con @s. Muchos programas se equivocan terriblemente, ya que no escapan @a los regulares de ninguna manera y/o asumen que solo el primer byte podría ser NUL.

A diferencia de las rutas de sockets Unix normales, los nombres abstractos de sockets Unix tienen una semántica diferente, ya que cualquiera puede vincularse a ellos (si el nombre aún no está en uso) y cualquiera puede conectarse a ellos.

En lugar de depender del permiso de archivo/directorio para restringir quién puede conectarse a su socket y asumir que, por ejemplo. solo root puede crear sockets dentro de algún directorio, debe verificar la credencial del par getsockopt(SO_PEERCRED)(para obtener el uid/pid de quién conectó o vinculó al par), o el SCM_CREDENTIALSmensaje auxiliar (para obtener el uid/pid de quién envió un mensaje a través del enchufe).

Esto (reemplazando las comprobaciones habituales de permisos de archivos) es también el único uso sensato de SO_PEERCRED/ SCM_CREDENTIALSen mi humilde opinión.

Respuesta2

El socket de su dominio Unix no debe ir directamente a /run, debe crear una carpeta dentro /run, por ejemplo /run/my-ipccon los derechos apropiados para su usuario y luego escribir en esa carpeta.

La carpeta debe recrearse al arrancar. La respuesta aceptada paraesta preguntaexplica un par de alternativas.

información relacionada