sudo:以另一個使用者身份執行縮放
我使用 iptables 阻止了我孩子的 Linux 帳戶的所有 Internet 流量。有時我想讓他們使用一個或另一個程序。在這種情況下,我使他們能夠通過 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
,但是如果我以身份登錄 Gnomedaddy
,然後在終端執行su kiddy
後跟sudo -u daddy gnome-terminal
orsudo -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
如果初始 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
原樣。
可能它不知道要使用什麼顯示器。當你用 sudo 啟動它時,它會創建一個新的 shell。如果該外殼不知道顯示,它將無法打開視窗。
要對此進行測試,請嘗試以相同的方式 sudo 一個 xterm (/usr/bin/xterm)。它打開了嗎?如果沒有,我們可能會在這裡做一些事情。
它可能就像在 sudo 行中添加 VAR=DISPLAY 一樣簡單。有關具體詳細資訊,請參見 sudo 手冊頁。