
Я использую systemd для монтирования общего ресурса Windows с помощью Kerberos. Чтобы это сработало, я сначала запускаю kinit
файл .service для создания кэша учетных данных Kerberos (ccache). .service запускается от имени root, поскольку ccache должен принадлежать root ( journalctl -xe
мне это помогло), поскольку mount.cifs требует root. .mount (и .automount) используют ccache для выполнения монтирования Kerberos. Когда я создаю ccache в интерактивном режиме, это работает хорошо. Однако при запуске внутри сервисного модуля ccache быстро удаляется, и (автоматическое) монтирование завершается ошибкой. Неважно, сохраняю ли я его в /tmp или /run/user/0.
- Почему файлы в /tmp или /run автоматически удаляются?
- Какое предпочтительное расположение для этих файлов ccache? Есть ли
PrivateTmp
лучшее решение? Если да, то как мне сослаться на этот частный каталог tmp внутри файла службы? Я пробовал%T/krb5cc_root.ccache
, но systemctl выдает ошибку. Есть лиJoinsNamespaceOf
способ использовать тот же частный tmp в файле монтирования?
Я использую systemd 219 на linux CentOS 7. Ниже мой юнит .service. Заранее спасибо!
[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
решение1
Почему файлы в /tmp или /run автоматически удаляются?
Потому что ваша службазапускает «демон», который немедленно завершает работу, тем самым помечая службу как «остановленную» в течение нескольких секунд после запуска, что приводит к kdestroy
запуску метода ExecStop=.
Вариант 2: Измените определение .service, чтобы сообщить systemd, что этодолжно бытьзадача, которая немедленно завершается, используя следующие параметры:
[Service] Type=oneshot RemainAfterExit=yes
Режим
Type=oneshot
дополнительно полезен, поскольку заставит systemd ждать полного завершения ExecStart=, прежде чем служба будет помечена как «активная», избегая необходимости добавлять произвольныйsleep 2
. Другими словами, он позволяет вам использовать его,After=kinit.service
не беспокоясь о том, что другие вещи начнутся «слишком рано».Вариант 1: Заменить kinit на
k5start
демон изhttps://www.eyrie.org/~eagle/software/kstart/. Это настоящий демон – долгосрочный процесс – и он будет отслеживаться как таковой. Он также будет обрабатывать периодическое обновление.Если вы используете k5start с
-b
опцией («Отсоединить при запуске») и соответствующим образом измените режим .serviceType=forking
, вы также получите такое же поведение «задержка до успешного завершения».
(Есть также третий вариант, позволяющий gssproxy
обрабатывать все билеты, но cifs.upcall в CentOS пока его не поддерживает. Для других целей, помимо монтирования файловых систем, KRB5_CLIENT_KTNAME
можно разрешить самой программе получать билеты из keytab по мере необходимости, но в данном случае это не сработает.)
Какое предпочтительное место для этих файлов ccache?
Лично я бы остановился на /tmp/krb5cc_*
или /run/user/<uid>/krb5cc_*
. (Это единственные места, которые проверяет NFS rpc.gssd.)
Для SMB cifs.upcall будет искать системное расположение по умолчанию для UID, который выполняет монтирование (т. е. то, что определено в krb5.conf), что обычно происходит, /tmp/krb5cc_0
когда это делает systemd. (Хотя cifs.upcall может извлечь KRB5CCNAME из среды вызывающего, это не поможет при задействовании автомонтирования, поскольку cifs.upcall будет видеть только systemd или autofsd в качестве вызывающего.)
Является ли PrivateTmp лучшим решением?
PrivateTmp не поможет, потому что ваш файл удаляет не внешняя задача, а сама служба.