在我的拱门服务器上,我设置了仅限于其主目录的用户。我跑:
useradd -m -s /bin/bash username
和passwd username
我读了这篇维基文章...
我想我应该使用 systemd 用户服务让每个用户在启动时运行一个节点服务器。因此,我登录到一个用户帐户su username
并创建了一个文件,~/.config/systemd/user/serve.service
其中包含:
[Unit]
Description=One of the servers
[Service]
ExecStart=/usr/bin/node /home/username/server.js
[Install]
WantedBy=default.target
然后我跑了,systemctl --user enable serve.service
它的回应是Failed to connect to bus: Permission denied
据我了解,我应该systemctl --user ...
以用户身份而不是 root 身份运行命令。
那么我在这个配置中错过了什么?
答案1
所以我登录了一个用户帐户
su username
不,你没有。
您尚未登录。 您正在增强以下人员的特权您现有的登录会话和su username
。
systemctl
该--user
选项可定位您的每用户桌面总线,由您的每用户桌面总线守护程序管理,并通过该总线与systemd
管理您的每用户服务的每用户实例进行通信。
su
不是登录机制。有用在现有的交互式登录会话。在该会话中,您的进程具有环境变量,这些环境变量告诉它们您的每用户运行时目录在哪里 ( XDG_RUNTIME_DIR
)、每用户桌面总线在哪里 ( DBUS_SESSION_BUS_ADDRESS
),以及其他一些信息,例如您的 X 服务器在哪里 ( DISPLAY
)。
特别是,DBUS_SESSION_BUS_ADDRESS
可以隐式引用XDG_RUNTIME_DIR
或显式命名相同的路径。该路径通常类似于/run/user/1001/bus
桌面总线代理的访问套接字(例如,假设您的用户 ID 为 1001)。
这些变量不会被 改变su
。多年来,对此一直存在着反复的争论,包括其他类似命令的行为,例如pkexec
.
这样做的结果是,如果您su
在登录会话中连接到第二个用户,systemctl
则以该第二个用户的身份运行,尝试连接到位于第一个用户私有目录中的桌面总线代理访问套接字。用户 1002(为示例而为第二个用户选择一个用户 ID)无法访问/run/user/1001
其中的任何内容,即使 xe 对该目录具有读取+执行访问权限,xe 也无法访问,/run/user/1001/bus
因为这也只向用户 1001 授予访问权限。
当然,这是不是首先要与之交谈的合适的桌面总线经纪人。您想与第二用户的桌面总线代理,并通过它到达第二个用户的每用户实例systemd
。
简单的解决方案是将su
这些环境变量设置为适合第二个用户帐户的环境变量,指向第二个用户的桌面总线:
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1002/bus su 用户名 -c 'systemctl --user'
当然,在这种情况下,我会使用一个方便的工具来设置它,userenv
这使我不必手动键入该总线地址:
su 用户名 -c 'userenv --set-dbus systemctl --user'
进一步阅读
- https://unix.stackexchange.com/a/407863/5132
- https://unix.stackexchange.com/a/423648/5132
- 乔纳森·德博因·波拉德 (2014)。不要滥用 su 来删除用户权限。常见答案。
- 乔纳森·德博因·波拉德。
userenv
。 nosh 工具集手册页。软件。 - https://unix.stackexchange.com/a/427917/5132