要运行没有 root 权限的进程,您可以在 systemd 中使用 DynamicUser= 或带有 User= 的静态用户。可以在这篇博文中找到对 DynamicUser 的很好的解释:http://0pointer.net/blog/dynamic-users-with-systemd.html
但哪一个更安全呢?除了 DynamicUser 使用动态用户而 User 需要系统用户之外,DynamicUser 和 User 之间的确切区别是什么?
答案1
DynamicUser
更安全,因为它意味着:
ProtectSystem=strict
:整个文件系统层次结构以只读方式安装,API 文件系统子树/dev/
、/proc/
和除外/sys/
。ProtectHome=read-only
:目录/home/
、/root
和/run/user
对此单元调用的进程设为只读。PrivateTmp=yes
:为执行的进程设置一个新的文件系统命名空间,并在其中挂载私有目录/tmp/
和/var/tmp/
命名空间之外的进程不共享的目录。这对于保护对进程临时文件的访问很有用,但使得进程之间的共享变得/tmp/
不可能/var/tmp/
。如果启用此功能,则服务停止后,服务在这些目录中创建的所有临时文件都将被删除。RemoveIPC=yes
:该单元的用户和组进程拥有的所有 System V 和 POSIX IPC 对象都按在单元停止时删除的方式运行
您可以通过在使用时显式设置它们来模仿这些设置User=
,从而有效地获得相同的保护。
一种更好的方法DynamicUser=
是创建服务实例。假设您有foo.socket
which use Accept=yes
。在这种情况下,每次有人连接到您的套接字时,foo@%i.service
都会生成一个新的套接字。每个实例都有DynamicUser=
自己的名称空间和目录,如果使用的/tmp
话,这些名称空间和目录将被共享。User=
答案2
User
即使您设置了 ,也没有什么可以阻止您指定选项DynamicUser=true
。
根据文档对于User=
(强调我的):
与指定的用户/组名一起使用时,
DynamicUser=
在服务启动时动态分配,并在服务停止时释放— 除非它已经静态分配(见下文)。如果DynamicUser=
未使用,则必须在服务启动时之前在用户数据库中静态创建指定的用户和组,例如使用 sysusers.d(5) 工具,该工具在引导或软件包安装时应用。如果用户不存在,则程序调用将失败。
然而,有一个限制,DynamicUser=
在文档:
...注意,如果
User=
指定了并且具有该名称的静态组存在,则要求具有该名称的静态用户已经存在。同样,如果Group=
指定了并且该名称的静态用户存在,则要求该名称的静态组已经存在。
基本上这意味着,如果您使用选项指定自定义User
,DynamicUser
并且存在与用户同名的组,则用户本身必须已经在系统上创建。指定自定义 也同样如此Group
。
前任。如果您指定User=docker
,并且该docker
组存在于您的系统上,则该docker
用户也必须已经存在才能使用该名称。
解决上述限制的方法基本上是确保您不使用系统上已存在的用户或组。
太长了;博士
回答你的问题,DymamicUser=
确实会提高安全性,但这不是是否使用User
or的问题DynamicUser
。 ADynamicUser
可以有一个User
与之关联的实际用户,但该用户将不是是添加到/etc/passwd
或/etc/group
。