
Estoy usando systemd para montar un recurso compartido de Windows usando Kerberos. Para que esto funcione, primero ejecuto kinit
un archivo .service para crear una caché de credenciales Kerberos (ccache). El .service se ejecuta como root ya que el ccache debe ser propiedad de root ( journalctl -xe
me ayudó con eso), ya que mount.cifs requiere root. .mount (y .automount) utilizan el ccache para realizar el montaje Kerberizado. Cuando creo el ccache de forma interactiva, esto funciona bien. Sin embargo, cuando se ejecuta dentro de la unidad de servicio, el ccache se elimina rápidamente y el montaje (automático) falla. No importa si lo guardo en /tmp o /run/user/0.
- ¿Por qué los archivos en /tmp o /run se eliminan automáticamente?
- ¿Cuál es la ubicación preferida para estos archivos ccache? ¿Es
PrivateTmp
una mejor solución? Si es así, ¿cómo hago referencia a ese directorio tmp privado dentro del archivo de servicio? Lo intenté%T/krb5cc_root.ccache
, pero systemctl genera un error. ¿JoinsNamespaceOf
La forma es utilizar el mismo tmp privado en el archivo de montaje?
Estoy usando systemd 219 en Linux CentOS 7. A continuación se muestra mi unidad .service. ¡Gracias de antemano!
[Unit]
Description=Kinit keytab for /mnt/windows_staging
After=network.target
Requires=network.target
[Service]
Restart=always
RestartSec=30
PrivateTmp=yes
User=root
Group=users
ExecStartPre=-/bin/mkdir -p /mnt/windows_staging
ExecStartPre=-/bin/mkdir -p /run/user/0
Environment=KRB5_KTNAME=/home/albertjan@domain/myproject/etc/keytabs/albertjan.keytab
Environment=KRB5CCNAME=/run/user/0/krb5cc_root.ccache
ExecStart=/bin/kinit albertjan -kt ${KRB5_KTNAME} -c ${KRB5CCNAME}
ExecStartPost=/bin/sleep 2
ExecStop=-/bin/kdestroy -c ${KRB5CCNAME}
[Install]
WantedBy=multi-user.target
Respuesta1
¿Por qué los archivos en /tmp o /run se eliminan automáticamente?
Porque tu servicioinicia un "demonio" que sale inmediatamente, por lo tanto, marca el servicio como "detenido" a los pocos segundos de iniciarse, lo que provoca que kdestroy
se ejecute from ExecStop=.
Opción 2: cambiar la definición de .service para indicarle a systemd que esto esse supone que esuna tarea que sale inmediatamente, usando estas opciones:
[Service] Type=oneshot RemainAfterExit=yes
El
Type=oneshot
modo es adicionalmente útil porque hará que systemd espere a que ExecStart= se complete por completo antes de que el servicio se marque como "activo", evitando la necesidad de agregar el archivosleep 2
. En otras palabras, te permite usarloAfter=kinit.service
sin preocuparte de que otras cosas comiencen "demasiado pronto".Opción 1: Reemplazar kinit con el
k5start
demonio dehttps://www.eyrie.org/~eagle/software/kstart/. Se trata de un verdadero demonio (un proceso de larga duración) y como tal será objeto de seguimiento. También se encargará de la renovación periódica.Si usa k5start con la
-b
opción ("Desconectar al inicio") y cambia el .service alType=forking
modo correspondiente, también obtendrá el mismo comportamiento de "retraso hasta el éxito".
(También hay una tercera opción que permite gssproxy
manejar todos los tickets, pero cifs.upcall en CentOS aún no lo admite. Para otros usos además del montaje de sistemas de archivos, KRB5_CLIENT_KTNAME
permitiría que el programa adquiera tickets desde keytab según sea necesario, pero no funcionará en este caso.)
¿Cuál es la ubicación preferida para estos archivos ccache?
Personalmente me quedaría con /tmp/krb5cc_*
o /run/user/<uid>/krb5cc_*
. (Esas son las únicas ubicaciones que NFS rpc.gssd comprueba).
Para SMB, cifs.upcall buscará en la ubicación predeterminada del sistema el UID que realiza el montaje (es decir, lo que esté definido en krb5.conf), que suele ser /tmp/krb5cc_0
cuando systemd lo hace. (Aunque cifs.upcall puede eliminar KRB5CCNAME del entorno del invocador, eso no ayuda con los montajes automáticos involucrados, ya que cifs.upcall solo vería systemd o autofsd como la persona que llama).
¿Es PrivateTmp una mejor solución?
PrivateTmp no ayudará, porque no es una tarea externa la que elimina su archivo, es el servicio mismo el que lo hace.