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/run
hay un enlace simbólico para /run
. Lamentablemente, la carpeta root
solo 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_path
está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 devueltoaddrlen
es mayor quesizeof(sa_family_t)
(es decir, mayor que 2) y el nombre del socket está contenido en los primeros(addrlen - sizeof(sa_family_t))
bytes desun_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_CREDENTIALS
mensaje 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_CREDENTIALS
en 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-ipc
con 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.