我正在尝试设置用户级服务,使用这个答案回答类似的问题。我已经创建了所需的文件并重新启动。
我正在取得进展,因为现在我收到的是“无法获取 D 总线连接:权限被拒绝”,而之前是“无法获取 D 总线连接:连接被拒绝”,但我很困惑,因为我不知道它试图访问什么对象(文件?套接字?),所以甚至无法检查当前权限。有什么想法吗?
到目前为止我已经添加了:
loginctl enable-linger userservice
/usr/lib/systemd/user/dbus.service (-rw-r--r-- root root)
[Unit]
Description=D-Bus User Message Bus
Requires=dbus.socket
[Service]
ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
[Install]
Also=dbus.socket
/usr/lib/systemd/user/dbus.socket (-rw-r--r-- root root)
[Unit]
Description=D-Bus User Message Bus Socket
[Socket]
ListenStream=%t/bus
ExecStartPost=-/bin/systemctl --user set-environment DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus
[Install]
WantedBy=sockets.target
Also=dbus.service
/home/用户服务/.config/systemd/user/用户服务.service
[Unit]
Description=Test user-level service
[Service]
Type=dbus
BusName=com.wtf.service
ExecStart=/home/userservice/userservice.py
Restart=on-failure
[Install]
WantedBy=default.target
没有添加其他地方的任何链接...
使其失败:
systemctl --user status
编辑2018-10-25:
添加export XDG_RUNTIME_DIR=/run/user/$(id -u)
到.bashrc
。变量已设置,现在我得到:Failed to get D-us connection: no such file or directory
。奇怪的是, 和 都没有man systemctl
提到systemctl --help
该--user
选项,而两者都提到--system
并指定这是默认值(那么其他选项是什么)。
使用带有 SELinux 的 RHEL 7.4(systemd 219
如所报告systemctl --version
)。
答案1
我注意到 Tableau 服务器使用 --user systemd 服务 - 他们甚至在他们的文档中对此有说明: https://help.tableau.com/current/server-linux/en-us/systemd_user_service_error.htm
systemd 用户服务不像常规的 systemd 进程管理器那样常用。Red Hat 在 RHEL 7 中禁用了 systemd 用户服务(因此所有来自 RHEL 的发行版,如 CentOS、Oracle Linux 7、Amazon Linux 2)。但是,RedHat 向 Tableau 保证,只要重新启用该服务,就可以运行 systemd 用户服务。
他们是如何做到的(例如,用户 ID 为 29575)
# cat /etc/systemd/system/[email protected]
[Unit]
Description=User Manager for UID %i
After=systemd-user-sessions.service
# These are present in the RHEL8 version of this file except that the unit is Requires, not Wants.
# It's listed as Wants here so that if this file is used in a RHEL7 settings, it will not fail.
# If a user upgrades from RHEL7 to RHEL8, this unit file will continue to work until it's
# deleted the next time they upgrade Tableau Server itself.
After=user-runtime-dir@%i.service
Wants=user-runtime-dir@%i.service
[Service]
LimitNOFILE=infinity
LimitNPROC=infinity
User=%i
PAMName=systemd-user
Type=notify
# PermissionsStartOnly is deprecated and will be removed in future versions of systemd
# This is required for all systemd versions prior to version 231
PermissionsStartOnly=true
ExecStartPre=/bin/loginctl enable-linger %i
ExecStart=-/lib/systemd/systemd --user
Slice=user-%i.slice
KillMode=mixed
Delegate=yes
TasksMax=infinity
Restart=always
RestartSec=15
[Install]
WantedBy=default.target
创建该文件后:
systemctl daemon-reload
systemctl enable [email protected]
systemctl start [email protected]
并且您需要通过 bashrc 或类似方式在该用户的环境中设置 XDG_RUNTIME_DIR:
[ -z "${XDG_RUNTIME_DIR}" ] && export XDG_RUNTIME_DIR=/run/user/$(id -ru)
我已经在最近的 RHEL 7.8 上进行了测试并且它可以按预期运行,执行此操作后我可以以我的用户身份运行“systemctl --user status”。
答案2
因此,存在一个长期存在的问题,即XDG_RUNTIME_DIR
当用户登录时,环境变量无法正确设置,或者根本无法设置,因此无法访问用户 D-Bus。当用户通过本地图形控制台以外的其他方法登录时,就会发生这种情况。
您可以通过向用户添加以下内容来解决此问题$HOME/.bashrc
:
export XDG_RUNTIME_DIR=/run/user/$(id -u)
然后注销并重新登录。
答案3
您应该了解 PAM 的工作原理。
如果你使用以下任一方式登录系统
- 图形会话
- 在终端上登录(用户名和密码)
- 远程控制
然后 PAM 机制将调用pam_systemd
,这将设置所有需要使用的钩子systemctl
;如果您使用sudo
或切换用户su
,则不会发生这种情况。
这是故意的,明白吗 https://github.com/systemd/systemd/issues/7451#issuecomment-346787237
奇怪的是,实际上/etc/pam.d/su
包括包含/etc/pam.d/common-session
的调用,pam_systemd
但这失败了,实际上/var/log/auth.log
说:
pam_systemd(su:session):无法创建会话:已在会话中运行
目前,一个好方法是使用以ssh
另一个用户的身份连接到同一台机器,类似于ssh user@localhost
。
答案4
systemd 248(2021 年 3 月发布)引入了语法
systemctl --user -M username@ status
(该命令需要以 root 身份运行)
例如
[myuser@laptop ~]$ sudo systemctl --user -M testuser@ status
● testuser@
State: running
Jobs: 0 queued
Failed: 0 units
Since: Thu 2022-11-03 22:59:10 CET; 164ms ago
CGroup: /user.slice/user-1492.slice/[email protected]
├─init.scope
│ ├─ 21922 /usr/lib/systemd/systemd --user
│ └─ 21929 "(sd-pam)"
└─session.slice
└─dbus-broker.service
├─ 21950 /usr/bin/dbus-broker-launch --scope user
└─ 21951 dbus-broker --log 4 --controller 9 --machine-id fa369ab69fcf4e54ad8a274517ea5096 --max-bytes 100000000000000 --max-fds 25000000000000 --max-matches 5000000000
或者您也可以打开一个新的交互式登录会话
[myuser@laptop ~]$ sudo machinectl shell testuser@
Connected to the local host. Press ^] three times within 1s to exit session.
[testuser@laptop ~]$ systemctl --user status
● laptop
State: running
Jobs: 0 queued
Failed: 0 units
Since: Thu 2022-11-03 22:56:50 CET; 57s ago
CGroup: /user.slice/user-1492.slice/[email protected]
└─init.scope
├─ 21799 /usr/lib/systemd/systemd --user
└─ 21806 "(sd-pam)"
“sudo -u 用户名 -i”不会创建 systemd 登录会话
苏是 ”不是用于打开全新登录会话的工具“ 根据https://github.com/systemd/systemd/issues/7451#issuecomment-346787237 (我认为 sudo 与 su 相关。仅运行 sudo 成为另一个用户将不会启动该用户的 systemd 守护程序)
我尝试了一些例子Fedora 36和systemd 250:
例如“sudo -u 用户名 -i”
[myuser@laptop ~]$ sudo useradd test1
[myuser@laptop ~]$ sudo -u test1 -i
[test1@laptop ~]$ pgrep -u $USER -l
25217 bash
[test1@laptop ~]$ env | grep XDG
XDG_DATA_DIRS=/home/test1/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
[test1@laptop ~]$
例如“sudo machinectl shell 用户名@”
[myuser@laptop ~]$ sudo useradd test2
[myuser@laptop ~]$ sudo machinectl shell test2@
Connected to the local host. Press ^] three times within 1s to exit session.
[test2@laptop ~]$ pgrep -u $USER -l
25086 bash
25091 systemd
25100 (sd-pam)
25115 (sd-pam)
[test2@laptop ~]$ env | grep XDG
XDG_SESSION_TYPE=tty
XDG_SESSION_CLASS=user
XDG_SESSION_ID=51
XDG_RUNTIME_DIR=/run/user/1494
XDG_DATA_DIRS=/home/test2/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/
[test2@laptop ~]$ ls -l $XDG_RUNTIME_DIR/bus
srw-rw-rw-. 1 test2 test2 0 Nov 4 08:42 /run/user/1494/bus
[test2@laptop ~]$
参考:
相关内容来自systemd248 发行说明: https://github.com/systemd/systemd/blob/6c83054c0133eb53245e479d71589dceff76cf74/NEWS#L2796-L2800