首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以另一个具有Logind会话的用户的身份运行Systemd服务

以另一个具有Logind会话的用户的身份运行Systemd服务
EN

Unix & Linux用户
提问于 2020-06-02 01:29:48
回答 1查看 2.3K关注 0票数 2

问题

如何在引导时以任意用户的身份运行任意服务,为该用户创建logind会话(特别包括/run/user/uid下的所有好处),而不必以该用户的身份显式登录?

背景

我正在转换一个用于无根podman + systemd服务的坞-组合部署。我已经弄明白了大多数podman的东西,但我特别为让它通过systemd运行而感到挣扎。

在上一次部署中,我为每个服务创建了一个用户帐户,并将容器配置为以该用户身份运行。从文件系统控制和维护的角度来看,这非常方便,实际上是我希望保留的主要属性。

为此,我发现了 askubuntu问题,它使我能够将用户直接嵌入到系统作业中,并让它以上述用户的身份执行。太完美了。

现在,麻烦来了: Fedora转移到cgroup v2,现在由systemd来处理,实际上,这一努力最初是出于这个原因。因此,podman需要能够与systemd对话,而这又基本上需要logind设置的登录会话(如果我正确理解链接的话)。我不是系统专家,所以请纠正我的任何这一点。

我确实找到了接近我所追求的关于等待用户会话的另一个问题,但似乎表明这是不可能的。我的情况在两个主要方面有所不同:

  • 我不想等任何一节课。这应该在没有交互的引导下运行)。
  • 我的解决方案需要足够强大,以承受手动干预,使服务上下运行。

如前所述,<#>So实际上是在寻找任何方法,使系统服务能够以特定用户的身份运行,具有足够的登录环境,以便服务应用程序能够连接到systemd (或者至少可以连接到systemd的cgroup v2部分)。

最后,下面是其中一个服务的示例systemd单元文件,它按预期工作,直到它需要连接到systemd为止。此外,当我的登录用户手动执行podman调用时,它完全工作。

代码语言:javascript
复制
[Unit]
Description=Emby Podman Container

[Service]
User=emby
Group=emby
Restart=on-failure
ExecStartPre=/usr/bin/rm -f /%t/%n-pid /home/emby/%n-cid
ExecStart=/usr/bin/podman run --conmon-pidfile /%t/%n-pid --cidfile /home/emby/%n-cid -d --name=emby --cgroup-manager=systemd -e TZ="$TZ" -p 8096:8096 -p 8920:8920 -v /opt/docker/storage/emby:/config -v /media/media/:/media emby/embyserver
ExecStop=/usr/bin/sh -c "/usr/bin/podman rm -f `cat /home/emby/%n-cid`"
KillMode=none
Type=forking
PIDFile=/%t/%n-pid

[Install]
WantedBy=multi-user.target
EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2020-06-04 22:06:28

因此,经过大量的绞尽脑汁之后,我找到了一个可行的解决方案,这个解决方案虽然不那么优雅,但却比我想象的要简单。让我们先来看看这个功能单元文件:

代码语言:javascript
复制
[Unit]
Description=Emby Podman Container
BindsTo=user@1012.service
After=user@1012.service

[Service]
User=emby
Group=media
Restart=on-failure
ExecStartPre=/usr/bin/rm -f /home/emby/%n-pid /home/emby/%n-cid
ExecStartPre=-/usr/bin/podman rm emby
ExecStart=/usr/bin/podman run --conmon-pidfile /home/emby/%n-pid --cidfile /home/emby/%n-cid \
          --name=emby --rm --cgroup-manager=systemd \
          -e TZ="$TZ" \
          -p 8096:8096 -p 8920:8920 \
          -v /opt/docker/storage/emby:/config \
          -v /media/media/:/media \
          emby/embyserver
ExecStop=/usr/bin/sh -c "/usr/bin/podman rm -f `cat /home/emby/%n-cid`"
KillMode=none
Type=forking
PIDFile=/home/emby/%n-pid

[Install]
WantedBy=multi-user.target

这里的关键洞察力是让systemd管理用户会话本身(而不是让您做任何其他事情)。在此配置中,BindsToAfter的使用是必不可少的,因为它们将强制在emby服务实际启动之前完全创建emby用户的用户会话。此外,这使得管理员(读: me)不必登录到每个用户中来启用会话,随着更多的服务和用户的添加,会话应该会有所帮助。

有关设置的其他一些有用的说明:

  • -d标志已从podman中删除,以便可以通过journalctl -fu emby _TRANSPORT=stdout查看stdout。便于测试和验证。
  • 根据user@.service手册页,必须用UID而不是名称(在我的系统emby == 1012上)实例化用户服务。我还没有找到在任何非Exec命令中进行扩展的方法,因此,目前这是硬编码的。如果有人知道怎么清理这件事,我很想听听。
  • PID文件已被移动到用户的主目录中,因为/run不能写字(也很好)。

我尝试过的其他一些方法没有奏效:

  • ExecPre中直接启动用户服务。此单元以用户身份运行,因此无法为该用户启动系统(鸡,见蛋)。
  • 自动登录用户。注意:这可能有效,但对完全登录的用户有安全影响。
  • 通过su改变用户。系统维护人员对su的看法相当模糊.拒绝修复它。撇开宗教争论不谈,素素不起作用。

Additional参考资料:

编辑:

当然,一旦我发布这篇文章,我就能找到神奇的搜索字符串,它将我引向一个文章,它可以消除我的方法。

为了简洁起见,本文的要点包括以root身份运行服务,并使用--uidmap/--gidmap将容器的根用户映射到所需的系统用户。

然而,这个解决方案是特定于podman的,所以我将把上面的内容留给那些需要访问systemd的非根、非podman进程的人。

最后,我认为我的解决方案更安全,因为如果攻击者破坏容器运行时,范围仍然仅限于我的非特权用户。不过,这可能会被另一个正在运行的用户服务增加的攻击面所抵消,因此,这可能是一次清洗。

票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/590347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档