在 Systemd 中使用自动用户和运行时凭据

在传统的 Linux 运维中,如果需要使某个服务以非特权用户运行,一般会为其创建一个专门的用户,并配置 User 和 Group 字段。

在 Systemd 中,对于不需要精细控制权限的情况,则有更加简便的方法。

.service 服务单元配置文件中的 [Service] 部分,可以下面的配置项来启用这一功能:

1
2
3
4
5
[Service]
DynamicUser=yes
PrivateTmp=yes
PrivateUsers=yes
PrivateDevices=yes

如此,即无需在 [Service] 部分配置 User 和 Group 字段,Systemd 会自动为该服务创建一个临时用户,并在服务停止后删除该用户。

加载运行时凭据

出于安全考量,对于一些凭据或配置文件,我们会需要将权限设置为 400,即仅允许所有者读取。

在过往专门建立用户的情况下,可以将文件的所有者设置为该用户,来让应用程序读取。但是在 Systemd 中,使用 DynamicUser 时,服务的用户在服务启动时才会创建,因此无法在服务启动前设置文件的所有者。

如果应用程序支持指定配置文件路径,可以在服务单元中使用 LoadCredential 选项来加载运行时凭据。

1
2
3
[Service]
LoadCredential=config.yaml:/opt/apisvc/config.yaml
ExecStart=/opt/apisvc/apisvc -config ${CREDENTIALS_DIRECTORY}/config.yaml

完整的例子

下面是一个完整的例子,假设我们有一个名为 apisvc 的服务,配置文件为 /opt/apisvc/config.yaml,并且我们希望将其以非特权用户运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=API Service
After=network.target

[Service]
Type=simple
Restart=always
WorkingDirectory=/opt/apisvc
EnvironmentFile=-/opt/apisvc/env
LoadCredential=config.yaml:/opt/apisvc/config.yaml
ExecStart=/opt/apisvc/apisvc $APISVC_OPTS -config ${CREDENTIALS_DIRECTORY}/config.yaml
DynamicUser=yes
PrivateTmp=yes
PrivateUsers=yes
PrivateDevices=yes

[Install]
WantedBy=multi-user.target