问题
如何在引导时以任意用户的身份运行任意服务,为该用户创建logind会话(特别包括/run/user/uid下的所有好处),而不必以该用户的身份显式登录?
背景
我正在转换一个用于无根podman + systemd服务的坞-组合部署。我已经弄明白了大多数podman的东西,但我特别为让它通过systemd运行而感到挣扎。
在上一次部署中,我为每个服务创建了一个用户帐户,并将容器配置为以该用户身份运行。从文件系统控制和维护的角度来看,这非常方便,实际上是我希望保留的主要属性。
为此,我发现了这 askubuntu问题,它使我能够将用户直接嵌入到系统作业中,并让它以上述用户的身份执行。太完美了。
现在,麻烦来了: Fedora转移到cgroup v2,现在由systemd来处理,实际上,这一努力最初是出于这个原因。因此,podman需要能够与systemd对话,而这又基本上需要logind设置的登录会话(如果我正确理解这链接的话)。我不是系统专家,所以请纠正我的任何这一点。
我确实找到了接近我所追求的关于等待用户会话的另一个问题,但似乎表明这是不可能的。我的情况在两个主要方面有所不同:
如前所述,<#>So实际上是在寻找任何方法,使系统服务能够以特定用户的身份运行,具有足够的登录环境,以便服务应用程序能够连接到systemd (或者至少可以连接到systemd的cgroup v2部分)。
最后,下面是其中一个服务的示例systemd单元文件,它按预期工作,直到它需要连接到systemd为止。此外,当我的登录用户手动执行podman调用时,它完全工作。
[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发布于 2020-06-04 22:06:28
因此,经过大量的绞尽脑汁之后,我找到了一个可行的解决方案,这个解决方案虽然不那么优雅,但却比我想象的要简单。让我们先来看看这个功能单元文件:
[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管理用户会话本身(而不是让您做任何其他事情)。在此配置中,BindsTo和After的使用是必不可少的,因为它们将强制在emby服务实际启动之前完全创建emby用户的用户会话。此外,这使得管理员(读: me)不必登录到每个用户中来启用会话,随着更多的服务和用户的添加,会话应该会有所帮助。
有关设置的其他一些有用的说明:
-d标志已从podman中删除,以便可以通过journalctl -fu emby _TRANSPORT=stdout查看stdout。便于测试和验证。Exec命令中进行扩展的方法,因此,目前这是硬编码的。如果有人知道怎么清理这件事,我很想听听。/run不能写字(也很好)。我尝试过的其他一些方法没有奏效:
ExecPre中直接启动用户服务。此单元以用户身份运行,因此无法为该用户启动系统(鸡,见蛋)。Additional参考资料:
编辑:
当然,一旦我发布这篇文章,我就能找到神奇的搜索字符串,它将我引向一个文章,它可以消除我的方法。
为了简洁起见,本文的要点包括以root身份运行服务,并使用--uidmap/--gidmap将容器的根用户映射到所需的系统用户。
然而,这个解决方案是特定于podman的,所以我将把上面的内容留给那些需要访问systemd的非根、非podman进程的人。
最后,我认为我的解决方案更安全,因为如果攻击者破坏容器运行时,范围仍然仅限于我的非特权用户。不过,这可能会被另一个正在运行的用户服务增加的攻击面所抵消,因此,这可能是一次清洗。
https://unix.stackexchange.com/questions/590347
复制相似问题