[Linux][systemd][自分用メモ] SystemdのExecStartPreでアクセス許可の問題が発生する。

AIX、UNIX、Linux
https://unix.stackexchange.com/questions/348450/confused-by-execstartpre-entries-in-systemd-unit-file

現在、自宅の検証環境はARMボードを使用しているのですが、動作させているArmbian OSは/var/logがzramに格納されているため再起動を行った際に/var/logの書き戻しの際になぜかパーミッションが変わってしまい、サービスそのものの起動に失敗することがあります。

そのため、systemd unitファイルのExecStartPreで起動前にパーミッションを変更しておこうとしたところOperation not permittedとなり失敗することを確認しました。

何じゃらほいと思って調べてみました。

問題のlog

$ sudo systemctl status zabbix-agent.service
● zabbix-agent.service - Zabbix Agent
   Loaded: loaded (/etc/systemd/system/zabbix-agent.service; enabled; vendor preset: enabled) 
   Active: failed (Result: exit-code) since Thu 2020-02-06 08:43:45 JST; 1s ago
  Process: 1742 ExecStartPre=/bin/chown -R zabbix:zabbix /var/log/zabbix (code=exited, status=1/FAILURE)
Feb 06 08:43:45 k8s-work2 systemd[1]: Starting Zabbix Agent...
Feb 06 08:43:45 k8s-work2 chown[1742]: /bin/chown: changing ownership of '/var/log/zabbix/zabbix_agentd.log.old': Operation not permitted
Feb 06 08:43:45 k8s-work2 chown[1742]: /bin/chown: changing ownership of '/var/log/zabbix/zabbix_agentd.log': Operation not permitted
Feb 06 08:43:45 k8s-work2 chown[1742]: /bin/chown: changing ownership of '/var/log/zabbix': Operation not permitted        
Feb 06 08:43:45 k8s-work2 systemd[1]: zabbix-agent.service: Control process exited, code=exited status=1                   
Feb 06 08:43:45 k8s-work2 systemd[1]: zabbix-agent.service: Failed with result 'exit-code'. 
Feb 06 08:43:45 k8s-work2 systemd[1]: Failed to start Zabbix Agent.  

Systemd Unitファイルは以下のようになっています。

# /etc/systemd/system/zabbix-agent.service
[Unit]
Description=Zabbix Agent
After=syslog.target
After=network.target
[Service]
Environment="CONFFILE=/etc/zabbix/zabbix_agentd.conf"
Type=simple
PIDFile=/var/run/zabbix/zabbix_agentd.pid
KillMode=mixed
ExecStart=/usr/local/sbin/zabbix_agentd -f -c $CONFFILE
User=zabbix
[Install]
WantedBy=multi-user.target

manによると

systemd.service(5) - Linux manual page
PermissionsStartOnly=
    Takes a boolean argument. If true, the permission-related execution options, as configured with User= and
    similar options (see systemd.exec(5) for more information), are only applied to the process started with
    ExecStart=, and not to the various other ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, and
    ExecStopPost= commands. If false, the setting is applied to all configured commands the same way. Defaults to
    false.

最初はPermissionsStartOnly=で解決かなーと思っていたのですが、systemdのgithubレポジトリを確認してみると、どうやら2018年の段階(v240?)でdeprecatedになっているらしく、

man: let's deprecate PermissionsStartOnly= by poettering · Pull Request #10802 · systemd/systemd
The concept is redundant and predates the special chars that do the same in ExecStar=. Let's settle on advertising just ...

The concept is redundant and predates the special chars that do the same in ExecStar=. Let’s settle on advertising just the latter, and hide PermissionsStartOnly= from the docs (even if we continue supporting it).

https://github.com/systemd/systemd/pull/10802

Ubuntu 18.04を使用している限りでは問題なさそうですが、githubの方を確認すると現在のものでは隠して(消して?)いこうと書かされています。そのことから将来的なことを考えるとExecStart=に解説があるように“+”を付与するか、 LogsDirectory= パラメータを使用するのが良さそうです。

systemd.exec

解決方法

“+”を付与する場合

# /etc/systemd/system/zabbix-agent.service
[Unit]
Description=Zabbix Agent
After=syslog.target
After=network.target
[Service]
Environment="CONFFILE=/etc/zabbix/zabbix_agentd.conf"
Type=simple
PIDFile=/var/run/zabbix/zabbix_agentd.pid
KillMode=mixed
ExecStart=/usr/local/sbin/zabbix_agentd -f -c $CONFFILE
ExecStartPre=+/bin/chown -R zabbix:zabbix /var/log/zabbix
User=zabbix
[Install]
WantedBy=multi-user.target
systemd.service

If the executable path is prefixed with “+” then the process is executed with full privileges. In this mode privilege restrictions configured with User=, Group=, CapabilityBoundingSet= or the various file system namespacing options (such as PrivateDevices=, PrivateTmp=) are not applied to the invoked command line (but still affect any other ExecStart=, ExecStop=, … lines).

https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=

LogsDirectoryを使用する場合

# /etc/systemd/system/zabbix-agent.service
[Unit]
Description=Zabbix Agent
After=syslog.target
After=network.target
[Service]
Environment="CONFFILE=/etc/zabbix/zabbix_agentd.conf"
Type=simple
PIDFile=/var/run/zabbix/zabbix_agentd.pid
KillMode=mixed
ExecStart=/usr/local/sbin/zabbix_agentd -f -c $CONFFILE
ExecStartPre=/bin/chown -R zabbix:zabbix /var/log/zabbix
LogsDirectory=zabbix
LogsDirectoryMode=0755
User=zabbix
[Install]
WantedBy=multi-user.target
systemd.exec

実行可能パスの先頭に「+」が付いている場合、プロセスは完全な特権で実行されます。

In case of RuntimeDirectory= the innermost subdirectories are removed when the unit is stopped. It is possible to preserve the specified directories in this case if RuntimeDirectoryPreserve= is configured to restart or yes (see below). The directories specified with StateDirectory=, CacheDirectory=, LogsDirectory=, ConfigurationDirectory= are not removed when the unit is stopped.

Except in case of ConfigurationDirectory=, the innermost specified directories will be owned by the user and group specified in User= and Group=. If the specified directories already exist and their owning user or group do not match the configured ones, all files and directories below the specified directories as well as the directories themselves will have their file ownership recursively changed to match what is configured. As an optimization, if the specified directories are already owned by the right user and group, files and directories below of them are left as-is, even if they do not match what is requested. The innermost specified directories will have their access mode adjusted to the what is specified in RuntimeDirectoryMode=, StateDirectoryMode=, CacheDirectoryMode=, LogsDirectoryMode= and ConfigurationDirectoryMode=.

These options imply BindPaths= for the specified paths. When combined with RootDirectory= or RootImage= these paths always reside on the host and are mounted from there into the unit’s file system namespace.

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RuntimeDirectory=

参考情報

この記事を書いた人

kometchtech

うつ病を患いながら、IT業界の末席にいるおっさんエンジニア。科学計算をしたことがないのに、HPC分野にお邪魔している。興味のある分野で学習したことをblogにまとめつつ、うつ病の経過症状のメモも置いておく日々。じつはRouterboard User Group JPの中の人でもある。 Amazon欲しいものリスト / Arm板を恵んでくれる人募集中

kometchtechをフォローする
タイトルとURLをコピーしました