systemd 服务配置
systemd 的服务配置相关参数说明
服务文件位置
- /lib/systemd/system/caddy.service
示例配置
caddy.service
[Unit]
Description=Caddy Web Server
After=network.target
[Service]
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=true
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=default.target
参数说明
[Unit] 部分
Description
为服务提供一个简要说明。
Documentation
提供服务文档的链接。
Requires
列出在启动此服务之前必须启动的其他服务。
Wants
类似于 Requires,但不强制启动列出的服务。
BindsTo
强制性地将服务的运行状态与特定的另一个服务挂钩。
Before
该服务在列表中的其他服务之前启动。
After
该服务在列表中的其他服务之后启动。
PartOf
当列出的服务被重启或停止时,此服务也会相应地被重启或停止。
[Service] 部分
Type
Type详细说明
定义服务类型(simple, forking, oneshot, dbus, notify 或 idle)。
ExecStart
定义启动服务时执行的命令。
ExecStartPre 和 ExecStartPost
分别定义在主命令之前和之后要运行的命令。
ExecStop
定义停止服务时执行的命令。
ExecReload
定义重新加载服务配置时执行的命令。
Restart
定义服务在何种情况下应该自动重启(例如,always, on-failure, on-abort 等)。
RestartSec
定义自动重启之间等待的时间秒数。
TimeoutStartSec 和 TimeoutStopSec
分别定义服务启动或停止超时的秒数。
Environment
设置环境变量。Environment="KEY1=value1" "KEY2=value2" "KEY3=value3" 或者 设置多个 Environment
WorkingDirectory
设置服务启动时的工作目录。
User 和 Group
定义以哪个用户和用户组身份运行服务。
UMask
定义文件系统权限的掩码。默认的 umask 值通常是 0022,也就是新创建的文件默认权限为 644(666 减去 022),新目录默认权限为 755(777 减去 022)。
你可以设置 umask 为任何合法的八进制数,如 0002、0027 等。
ProtectSystem
ProtectSystem 选项配置服务对核心系统文件的写入权限。它旨在防止服务对系统的相关部分造成潜在的损害。
参数值:
- no(默认): 没有特定的文件系统保护;服务可能会写入系统的任意区域。
- yes: /usr, /boot, 和 /etc 将是只读的,其他的文件系统仍然可写。
- full: 整个文件系统层次(包括 /) 将是只读的,除了 /dev, /proc, /sys, /tmp 和 /var/tmp(还有 /run,因为它需要在运行时可写)。
ProtectHome
ProtectHome 选项用来控制对用户家目录的访问规则。这有助于增强系统安全性,尤其是在你不想让服务有能力读取或编辑用户数据时。
参数值:
- no(默认): 服务可以对 /home, /root, 和 /run/user 完全访问。
- yes: 服务没有读取、写入和执行 /home, /root, 或 /run/user 目录内容的权限。
- read-only: 服务可以读取 /home, /root, 和 /run/user 的内容,但不能修改。
PrivateTmp
PrivateTmp 选项为服务创建了一个独立的 /tmp 和 /var/tmp 目录。当服务启动时,系统会为其创建新的临时目录,而这些目录对于系统的其它部分是不可见的,服务重启后这些临时目录内容会被清理。
参数值:
- true: 启用隔绀的临时文件系统,确保服务的临时文件不会与其他服务共享,提高隔离性和安全性。
- false(默认): 禁用隔离的 /tmp 和 /var/tmp 文件系统,服务将使用系统全局的临时目录。
提示
当启用 PrivateTmp 后,systemd 会为服务创建两个临时目录:
- /tmp 目录的私有版本。通常在 /tmp/systemd-private-xxxxxx 路径下,其中 xxxxxx 是一个随机生成的字符串,用于避免命名冲突。
- /var/tmp 目录的私有版本。通常在 /var/tmp/systemd-private-xxxxxx 路径下,命名规则与私有 /tmp 目录相同。
服务进程看到的 /tmp 和 /var/tmp 实际上是这些隐蔽的路径,它们通过名字空间隔离技术(namespace isolation)与全局的 /tmp 和 /var/tmp 目录隔绝开来。服务进程所在的命名空间能够访问到这些私有目录,但对系统上的其他进程(不在相同命名空间内的)则是不可见的。
这两个目录只在服务运行时存在,它们是临时挂载的文件系统,服务停止后会被卸载,并且其中的内容会被自动清除。这种方式提供了对于服务运行时产生的临时文件和数据的很好隔离,从而提升了系统的安全性。
如果你需要查看或管理由 PrivateTmp=true 生成的私有临时文件,你需要具有 root 权限,并且知道具体的随机生成的目录名称。可以通过登录到系统并以 root 身份查看 /tmp 和 /var/tmp 目录的内容来找到它们。
提示
在配置服务时应该根据服务的具体需求和安全级别选择合适的值。
例如,一个不需要写入任何系统配置且不需要存取任何用户数据的服务,可能会有配置项 ProtectSystem=full、ProtectHome=yes 和 PrivateTmp=true。相反,如果服务确实需要写入配置到 /etc 或访问用户的家目录,那么需要调整上述设置,或者使用其他相关的 systemd 选项来提供合适的文件系统访问权限。
安全相关配置 [Service 部分]
NoNewPrivileges
防止服务获取新权限。
CapabilityBoundingSet
控制给予服务的 Linux 能力集。
PrivateDevices
提供隔离的 /dev 目录,防止访问物理设备。
ProtectKernelTunables
限制对内核变量的访问。
ProtectControlGroups
限制对控制组的访问。
ProtectKernelModules
防止加载或卸载内核模块。
SystemCallFilter
限制服务可以执行的系统调用。
[Install] 部分
WantedBy
定义启动目标(target),该服务默认被这些目标所包含。
RequiredBy
类似于 WantedBy,但与 Requires= 关联。
Alias
允许服务通过另一个名称被地址。
Type 详细说明
Type=simple
解释: 默认值。假设主服务进程即为由 ExecStart= 指定的进程。启动程序不会自行后台化。systemd 认为这个服务启动完毕,只要启动命令顺利运行。
使用场景: 如果服务以前台运行且不会自行后台化,应选择此类型。这很适合现代的程序,特别是那些本身就是为了在容器环境中运行而设计的程序。
Type=forking
解释: 适用于传统的 UNIX 服务。这类服务在启动时会分裂一个子进程(fork),然后父进程立即退出。
使用场景: 主要用于那些遵循传统 UNIX “双进程”启动方式的程序。它会启动一个后台守护进程,并且父进程在启动完成后退出。对于那些需要自行后台化的老式服务(比如 Apache HTTP 服务器的某些旧版本),这是合适的选择。
Type=oneshot
解释: 此类型的服务主要适用于执行一次性任务然后退出的服务。systemd 在开始其他单元之前等待该服务的 ExecStart 进程退出。
使用场景: 通常用于初始化环境的脚本或者其他准备工作,比如设置网络配置或加载内核模块的任务。你可以将多个一次性服务按顺序排列,以逐步完成初始化任务。
Type=notify
解释: 对于此类型的服务,systemd 会等待服务通过 systemd 的通知接口发送一个准备完成的信号,然后认为服务启动完成。这是一种显式的同步机制。
使用场景: 适用于需要执行复杂初始化,且能够显式通知 systemd“已准备好”的服务。需要服务自身与 systemd 的通信接口兼容,因此主要用于对 systemd 集成有深度支持的程序。
Type=idle
解释: systemd 将推迟执行服务的 ExecStart= 指令,直到所有其它任务都执行完毕。
使用场景: 这种类型的用途相对较少,仅在你希望所有其它初始化已经完成,且没有更多其他任务时才启动的服务上使用。例如,用于显示某种欢迎消息的服务。