システム実行可能ファイルが CacheDirectory からファイルを読み取ることができず、権限が拒否されました。

システム実行可能ファイルが CacheDirectory からファイルを読み取ることができず、権限が拒否されました。

5分ごとに実行されるGolangバイナリがあります。書き込み制限が必要なテキストファイルを作成して更新する必要があります。このバイナリを実行するために、systemdサービスとsystemdタイマーデバイスを作成しました。システムサービスはDynamicUserを使用します。アクセス制限を実装するために、CacheDirectorysystemdはディレクティブを使用して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()
}

ファイルアップデータ、サービス

[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アクセスに関するすべての詳細が含まれます。特にステップ2:道を歩くそして許可する節:

プロセスに現在のルックアップディレクトリの検索権限がない場合、EACCESエラー(「許可拒否」)を返します。

使用されている3つのうち、最初のものは読み取り権限を決定し、2番目は書き込み権限を決定します。ついに一般ファイルの場合は、実行権限またはディレクトリ検索権限

関連情報