ソフトウェアの自動起動登録で地味に嵌ったのでメモ。
実施環境:
[root@testhost ~]# uname -a
Linux testhost 4.18.0-331.el8.x86_64 #1 SMP Thu Aug 19 16:49:03 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@testhost ~]# echo $SHELL
/bin/bash
事象
最近のLinuxでは、サービス管理は systemd で行われるのが主流です。
そこで、以下のようにして自作のサービスを登録してみます。
[root@testhost ~]# ls -l /usr/lib/systemd/system/test.service
-rw-r--r--. 1 root root 131 Aug 25 21:51 /usr/lib/systemd/system/test.service
[root@testhost ~]# cat /usr/lib/systemd/system/test.service
[Unit]
Description = TEST
[Service]
ExecStart = /usr/local/test/test.sh
Type = simple
[Install]
WantedBy = default.target
[root@testhost ~]# ls -ld /usr/local/test
drwxrwxrwx. 2 root root 21 Aug 25 21:48 /usr/local/test
[root@testhost ~]# ls -l /usr/local/test/test.sh
-rwxrwxrwx. 1 root root 54 Aug 25 21:48 /usr/local/test/test.sh
[root@testhost ~]# cat /usr/local/test/test.sh
#!/bin/bash
while true
do
sleep 10
done
exit 0
設定ファイルを読み込み、早速起動! ... と思いきや、なぜか上手くいきません。
[root@testhost ~]# systemctl daemon-reload
[root@testhost ~]# systemctl start test.service
[root@testhost ~]# systemctl status test.service
• test.service - TEST
Loaded: loaded (/usr/lib/systemd/system/test.service: disabled: vendor preset: disabled)
Active: failed (Result: exitcode) since Wed 2021-08-25 21:57:22 EDT; 6s ago
Process: 2518 ExecStart=/usr/local/test/test.sh (code=exited, status=203/EXEC)
Main PID: 2518 (code=exited, status=203/EXEC)
Aug 25 21:57:22 testhost systemd[1]: started TEST.
Aug 25 21:57:22 testhost systemd[1]: test.service: Main process exited. code=exited status=203/EXEC
Aug 25 21:57:22 testhost systemd[1]: test.service: Failed with result 'exit-code'.
ステータスの日時で mesasges ログを確認してみると、「Permission denied」、すなわち起動コマンドに権限が足りていないようです。
[root@testhost ~]# grep "Aug 25 21:57:22" /var/log/messages
Aug 25 21:57:22 testhost systemd[1]: started TEST.
Aug 25 21:57:22 testhost systemd[2518]: test.service: Failed to execute command: Permission denied
Aug 25 21:57:22 testhost systemd[2518]: test.service: Failed at step EXEC spawing /usr/local/test/test.sh: Permission denied
Aug 25 21:57:22 testhost systemd[1]: test.service: Main process exited. code=exited status=203/EXEC
Aug 25 21:57:22 testhost systemd[1]: test.service: Failed with result 'exit-code'.
Aug 25 21:57:22 testhost dbus-daemon[936]: [system] Activating service name='org.fedoraproject.Setroubleshootd' requested by ':1.21' (uid=0 pid=901 comm="/usr/sbin/sedispatch " label="system_u:system_r:auditd_t:s0") (using servicehelper)
あれっ、でも上で確認した通りパーミッションは 777 のはずでは...?
原因
答えは、「 SELinux のパーミッションが足りない」でした。
ホームディレクトリで作成したものを /usr に移動したため、 SELinux のパーミッションがホームディレクトリ向けとなっていたのが原因です。
[root@testhost ~]# ls -dZ /usr/local/test
unconfined_u:object_r:admin_home_t:s0 /usr/local/test
[root@testhost ~]# ls -Z /usr/local/test/test.sh
unconfined_u:object_r:admin_home_t:s0 /usr/local/test/test.sh
解決方法
「 SELinux 自体を停止する」でもよいのですが、今回は SELinux を動かしたままなんとかしたいです。
そこで、 restorecon コマンドを使って SELinux のパーミッションを更新します。
[root@testhost ~]# restorecon -R /usr/local/test
[root@testhost ~]# ls -dZ /usr/local/test
unconfined_u:object_r:usr_t:s0 /usr/local/test
[root@testhost ~]# ls -Z /usr/local/test/test.sh
unconfined_u:object_r:usr_t:s0 /usr/local/test/test.sh
更新できたので、もう一度起動してみます。
[root@testhost ~]# systemctl start test.service
[root@testhost ~]# systemctl status test.service
• test.service - TEST
Loaded: loaded (/usr/lib/systemd/system/test.service: disabled: vendor preset: disabled)
Active: active (running) since Wed 2021-08-25 22:12:24 EDT; 6s ago
Main PID: 2727 (test.sh)
Tasks: 2 (limit: 3355442)
Memory: 588.0K
CGroup: /system.slice/test.service
├─2727 /bin/bash /usr/local/test/test.sh
└─2728 sleep 10
Aug 25 22:12:24 testhost systemd[1]: Started TEST.
[root@testhost ~]#
今度は上手くいきました。
パーミッションが足りているのに権限不足で怒られたら、 SELinux のパーミッションも確認してみようというお話でした。