![sudo:以另一个用户身份运行 Zoom](https://linux22.com/image/179930/sudo%EF%BC%9A%E4%BB%A5%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E8%BF%90%E8%A1%8C%20Zoom.png)
我使用 iptables 阻止我孩子的 Linux 帐户的所有互联网流量。有时我想让他们使用一个程序或另一个程序。在这种情况下,我允许他们通过 sudoers 作为另一个(无限)用户运行该程序。这次我尝试让他们使用缩放功能,如下:
kiddy ALL= (daddy) NOPASSWD: /usr/bin/zoom
但是,运行sudo -u daddy /usr/bin/zoom
不会产生任何输出(也没有错误),但缩放不会开始。从命令行运行 Zoom 会启动 GUI 客户端,但显然无法连接(这是预期的)。这是怎么回事?
如果我尝试执行相同的操作gnome-terminal
,而不是zoom
添加到visudo
以下行:kiddy ALL= (daddy) NOPASSWD: /usr/bin/gnome-terminal
然后运行:sudo -u daddy /usr/bin/gnome-terminal
我收到此错误:
No protocol specified
Unable to init server: Could not connect: Connection refused
# Failed to parse arguments: Cannot open display:
一旦以 user 身份登录 Gnome,我就会遇到上述所有问题kiddy
,但是如果我以 user 身份登录 Gnome,daddy
然后在终端运行中,su kiddy
然后运行sudo -u daddy gnome-terminal
or sudo -u daddy zoom
- 一切正常。
我应该向文件添加一些额外的变量sudoers
吗?如果是 - 我如何确定需要哪些变量以及它们的值是什么?
env
以下是典型 Debian 10 用户(guest
在本例中命名)的输出:
SHELL=/bin/bash
SESSION_MANAGER=local/debox:@/tmp/.ICE-unix/2055,unix/debox:/tmp/.ICE-unix/2055
QT_ACCESSIBILITY=1
COLORTERM=truecolor
XDG_MENU_PREFIX=gnome-
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
LANGUAGE=en_IL:en
SSH_AUTH_SOCK=/run/user/1001/keyring/ssh
DESKTOP_SESSION=gnome
GTK_MODULES=gail:atk-bridge
XDG_SEAT=seat0
PWD=/home/guest
XDG_SESSION_DESKTOP=gnome
LOGNAME=guest
XDG_SESSION_TYPE=wayland
GJS_DEBUG_TOPICS=JS ERROR;JS LOG
GDM_LANG=en_IL
HOME=/home/guest
USERNAME=guest
LANG=en_IL
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
XDG_CURRENT_DESKTOP=GNOME
VTE_VERSION=5402
WAYLAND_DISPLAY=wayland-0
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/a2088f04_0308_4c60_9882_a758f7d883b8
GJS_DEBUG_OUTPUT=stderr
XDG_SESSION_CLASS=user
TERM=xterm-256color
USER=guest
GNOME_TERMINAL_SERVICE=:1.59
DISPLAY=:0
SHLVL=1
XDG_VTNR=2
XDG_SESSION_ID=4
XDG_RUNTIME_DIR=/run/user/1001
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
GDMSESSION=gnome
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
_=/usr/bin/env
答案1
可能它不知道要使用什么显示器。当您使用 sudo 启动它时,它会创建一个新的 shell。如果该 shell 不知道显示,它将无法打开窗口。
要测试这一点,请尝试以相同的方式 sudo xterm (/usr/bin/xterm)。它打开了吗?如果没有,我们可能会在这里做一些事情。
它可能就像在 sudo 行中添加 VAR=DISPLAY 一样简单。有关具体详细信息,请参阅 sudo 手册页。
答案2
如果初始 GUI 会话以 user 身份运行kiddy
,则会话密钥文件(位于~/.Xauthority
或环境变量指向的自定义位置XAUTHORITY
)由该用户拥有,默认情况下其他任何人都无法读取。
如果您sudo
使用 root,这不是问题,因为 root 通常可以读取所有内容(除非用户的主目录位于使用root_squash
选项集导出的 NFS 共享上)。您只需export XAUTHORITY=/home/$SUDO_USER/.Xauthority
确保DISPLAY
变量从原始会话中保留下来即可。
但是,当您习惯sudo -u daddy
切换到另一个非root帐户并想要使用GUI程序时,您需要使用可以自动处理此问题的GUI版本的用户切换工具(例如gksu
Gnome或kdesudo
KDE),或者给出第二个用户帐户可以自行访问会话密钥(或其副本)。
GUI 用户切换工具将是推荐的方式,因为它们可以适当地处理基本 GUI 会话访问之外的其他事物,例如辅助功能所需的环境变量和/或更复杂的字符输入方法,例如中文/所需的字符输入方法。例如日文/韩文字符输入。
某些发行版可能还具有 PAM 模块或其他预配置,以使其更加自动化。
但是,如果您需要手动执行此操作,则必须执行三件事才能获得以未执行 GUI 登录的用户身份运行 GUI 程序的基本能力:
- 目标用户必须拥有 X 会话密钥文件的可访问副本(或由原始会话中的变量
~/.Xauthority
指向)。XAUTHORITY
如果考虑安全性,则该文件应该只能由原始用户和目标用户访问。 - 目标用户可能需要有一个
XAUTHORITY
变量指向 X 会话密钥文件的可访问副本(除非该副本放置在~/.Xauthority
目标用户的位置) - 目标用户必须具有
DISPLAY
与原始会话相同的变量值
貌似gksu
已经被删除了。为了允许sudo
保留必要的环境变量,您可以编写一个/etc/sudoers.d/zoomforkiddy
包含以下内容的文件(建议使用它visudo -f /etc/sudoers.d/zoomforkiddy
来创建/编辑它):
Defaults:kiddy env_keep += "DISPLAY XAUTHORITY"
kiddy ALL = (daddy) NOPASSWD: /usr/bin/zoom
这允许必要的环境变量通过sudo
,并仅授予kiddy
无密码访问权限/usr/bin/zoom
。
然后添加daddy
到kiddy
的用户组:
sudo usermod -a -G kiddy daddy
如果设置了组访问权限,这将允许daddy
访问的文件。kiddy
因此,现在kiddy
将能够将他的 Xauthority 文件复制到可以访问的某个位置daddy
并设置权限,以便(仅)daddy
可以访问它。
现在创建一个脚本,例如/usr/local/bin/zoom_for_kiddy
并将其设置为可执行文件 ( chmod a+rx /usr/local/bin/zoom_for_kiddy
):
#!/bin/sh
if [ "$XAUTHORITY" = "" ]
then
XAUTHORITY="$HOME/.Xauthority"
fi
if [ -f "$XAUTHORITY" ]
then
cp "$XAUTHORITY" /tmp/zoom_for_kiddy_xauth
trap "rm -f /tmp/zoom_for_kiddy_xauth" EXIT
chmod 640 /tmp/zoom_for_kiddy_xauth
export XAUTHORITY=/tmp/zoom_for_kiddy_xauth
sudo -u daddy /usr/bin/zoom "$@"
else
echo "ERROR: cannot find the Xauthority file" >&2
fi
该脚本将复制kiddy
的 Xauthority 文件daddy
,设置权限,将 XAUTHORITY 环境变量设置为可用于 的值daddy
,然后开始/usr/bin/zoom
执行sudo
。退出时zoom
,Xauthority 文件的副本将随着执行脚本的 shell 退出而自动删除。
现在您可以调整kiddy
桌面环境来/usr/local/bin/zoom_for_kiddy
代替真实的桌面环境来使用/usr/bin/zoom
。任何命令参数都zoom
将按原样通过脚本传递到真实的参数。
答案3
我ego
为类似的用例编写了 (Alter Ego)。使用 ego,您可以在另一个本地用户下启动程序。除了 X11 设置之外,它还处理 Wayland 和 PulseAudio 套接字共享:https://github.com/intgr/ego
所以你只需运行ego --sudo -u daddy app
or ego -u daddy zoom
(某些应用程序在 --sudo 模式下会出现故障)。
如果遇到问题,请在 GitHub 上提出问题。