Systemd 可执行文件无法从 CacheDirectory 读取文件且权限被拒绝

Systemd 可执行文件无法从 CacheDirectory 读取文件且权限被拒绝

我有一个每 5 分钟运行一次的 Golang 二进制文件。它应该创建和更新需要写入限制的文本文件。为了运行这个二进制文件,我创建了一个 systemd 服务和一个 systemd 计时器单元。 Systemd 服务使用 DynamicUser。为了实现访问限制,我CacheDirectory在 systemd 中使用指令,以便只有 DynamicUser 可以写入该文件,并且它仅在用户存在时存在。还设置CacheDirectoryMode=644为仅允许具有写入权限的所有者。

当 systemd 服务运行时,它失败并显示 failed to read output file: lstat /var/cache/monitor/output_file.txt: permission denied>

问题:尽管服务单元将创建动态用户并运行创建/更新/读取文件的可执行文件,但为什么在 systemd 服务运行时尝试读取文件时该可执行文件本身会被拒绝?

file-monitor.go 编译生成 /usr/local/bin/file-monitor 二进制文件

package main

import (
    "fmt"
    "os"
)

function foo() {
    var outputFile = os.Getenv("CACHE_DIRECTORY") + "/output_file.txt"
    
    outputFileBytes, err := os.ReadFile(outputFile)
    if err != nil {
        return fmt.Errorf("failed to read output file %s: %v\n", outputFile, err)
    }
}

function main() {
    foo()
}

文件更新程序.service

[Unit]
Description="description"
After=file-updater.service

[Service]
DynamicUser=yes
User=monitor
Group=monitor

CacheDirectory=monitor
CacheDirectoryMode=644

ExecStart=/usr/local/bin/file-monitor <arg1>

Type=oneshot

[Install]
WantedBy=multi-user.target

答案1

CacheDirectoryMode=644

这允许读取目录列表。不与此目录列表中的文件交互:需要 eXecute 位来进一步遍历路径并访问目录中的文件。这使得用户具有写权限监视器也无用。

将该参数修改为:

CacheDirectoryMode=755

这是默认值(即:您可以删除此参数)。现在允许访问此目录中的文件,以便用户读取或写入监视器

该行为链接自系统的文档(RuntimeDirectoryMode=、StateDirectoryMode=、CacheDirectoryMode=、LogsDirectoryMode=、ConfigurationDirectoryMode=)到手册path_resolution(7)其中包括有关基本 Unix 访问的所有详细信息,尤其是第二步:沿着小路行走并在允许段落:

如果进程没有当前查找目录的搜索权限,返回 EACCES 错误(“权限被拒绝”)。

使用的三位中,第一位决定读权限,第二位决定写权限,并且最后对于普通文件,执行权限,或者目录的搜索权限

相关内容