2.1 su
切換用戶或以指定用戶運行命令。
使用su可以指定運行命令的身份(user/group/uid/gid)。
為了向后兼容,su默認不會改變當前目錄,且僅設置HOME和SHELL這兩個環境變量(若目標用戶非root,則還設置USER和LOGNAME環境變量)。推薦使用--login選項(即"-"選項)避免環境變量混亂。
su [options...] [-] [user [args...]] 選項說明: -c command:使用-c選項傳遞要指定的命令到shell上執行。使用-c執行命令會為每個su都分配新的會話環境 -, -l, --login:啟動shell作為登錄的shell,模擬真正的登錄環境。它會做下面幾件事: 1.清除除了TERM外的所有環境變量 2.初始化HOME,SHELL,USER,LOGNAME,PATH環境變量 3.進入目標用戶的家目錄 4.設置argv[0]為"-"以便設置shell作為登錄的shell 使用--login的su是交互式登錄。不使用--login的su是非交互式登錄(除不帶任何參數的su外 -m, -p, --preserve-environment:保留整個環境變量(不會重新設置HOME,SHELL,USER和LOGNAME), 保留環境的方法是新用戶shell上執行原用戶的各配置文件,如~/.bashrc。 當設置了--login時,將忽略該選項 -s SHELL:運行指定的shell而非默認shell,選擇shell的順序優先級如下: 1.--shell指定的shell 2.如果使用了--preserve-environment,選擇SHELL環境變量的shell 3.選項目標用戶在passwd文件中指定的shell 4./bin/sh
注意:
(1). 若su沒有給定任何參數,將默認以root身份運行交互式的shell(交互式,所以需要輸入密碼),即切換到root用戶,但只改變HOME和SHELL環境變量。
(2). su - username是交互式登錄,要求密碼,會重置整個環境變量,它實際上是在模擬真實的登錄環境。
(3). su username是非交互登錄,不會重置除HOME/SHELL外的環境變量。
例如:用戶wangwu家目錄為/home/wangwu,其shell為/bin/csh。
shell> head -1 /etc/passwd ; tail -1 /etc/passwd root:x:0:0:root:/root:/bin/bash wangwu:x:2002:2002::/home/wangwu:/bin/csh
首先su到wangwu上,再執行一個完全不帶參數的su。
shell> su - wangwu # 使用su - username后,以登錄shell的方式模擬登錄,會重新設置各環境變量。su - username是交互式登錄 shell> env | egrep -i '^home|^shell|^path|^logname|^user' HOME=/home/wangwu SHELL=/bin/csh USER=wangwu LOGNAME=wangwu PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin PWD=/home/wangwu
shell> su # 不帶任何參數的su,是交互式登錄切換回root,但只會改變HOME和SHELL環境變量 shell> env | egrep -i '^home|^shell|^path|^logname|^user|^pwd' SHELL=/bin/bash USER=wangwu PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin PWD=/home/wangwu HOME=/root LOGNAME=wangwu
shell> su - # su - 的方式切換回root Password: shell> env | egrep -i '^home|^shell|^path|^logname|^user|^pwd' SHELL=/bin/bash USER=root PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PWD=/root HOME=/root LOGNAME=root
shell> su wangwu # 再直接su username,它只會重置SHELL和HOME兩個環境變量,其他環境變量保持不變 shell> env | egrep -i '^home|^shell|^path|^logname|^user|^pwd' SHELL=/bin/csh USER=wangwu PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PWD=/root HOME=/home/wangwu LOGNAME=wangwu
在某些環境下或腳本中,可能需要臨時切換身份執行命令,注意這時候的環境變量是否會改變,否則很可能報錯提示命令找不到。
2.2 sudo
sudo可以讓一個用戶以某個身份(如root或其他用戶)執行某些命令,它隱含的執行方式是切換到指定用戶再執行命令,因為涉及到了用戶的切換,所以環境變量是否重置是需要設置的。
sudo支持插件實現安全策略。默認的安全策略插件是sudoers,它是通過/etc/sudoers或LDAP來配置的。
安全策略是控制用戶使用sudo命令時具有什么權限,但要注意,安全策略可能需要用戶進行身份認證,如密碼認證的機制或其他認證機制,如果開啟了認證要求,則在指定時間內未完成認證時sudo會退出,默認超時時間為5分鍾。
安全策略支持對認證進行緩存,使得在一定時間內該用戶無需再次認證就可以執行sudo命令,默認緩存時間為5分鍾,sudo -v可以更新認證緩存。
sudo支持日志審核,可以記錄下成功或失敗的sudo。
2.2.1 /etc/sudoers文件
該文件里主要配置sudo命令時指定的用戶和對應的權限。
shell> visudo # 以下選取的是部分行 ## hostname or IP addresses instead. # 主機別名Host_Alias # Host_Alias FILESERVERS = fs1, fs2 # Host_Alias MAILSERVERS = smtp, smtp2 ## User Aliases # 用戶別名User_Alias # User_Alias ADMINS = jsmith, mikem ## Command Aliases # 命令別名 # Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig # Cmnd_Alias LOCATE = /usr/bin/updatedb root ALL=(ALL) ALL # sudo權限的配置 # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS ## Allows people in group wheel to run all commands # %wheel ALL=(ALL) ALL ## Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL
在這個文件里,主要有別名(用戶別名,主機別名,命令別名)的配置和sudo權限的配置。
安全策略配置格式為:
用戶名 主機名=(可切換到的用戶身份) 權限和命令
① ② ③ ④
①用戶名:可以用組,只需在組名前加個百分號%表示。
②主機名:表示該用戶可以在哪些主機上運行sudo,可以用hostname也可以用ip指定。
③可切換的用戶身份,即指定執行命令的用戶,也可以用組。
④權限和命令:允許執行和不允許執行的命令(多個命令間用逗號分隔)和特殊權限,命令可以帶其選項及參數。命令要寫絕對路徑。不允許執行的命令需要在命令前加上"!"來表示。可以使用標簽,如NOPASSWD標簽表示切換或以指定用戶執行該標簽后的命令時不需要輸入密碼。一行寫不下時可使用"\"續行。
標簽使用方法:
NOPASSWD:/usr/sbin/useradd,PASSWD:/usr/sbin/userdel
它表示useradd命令不需要輸入密碼,而userdel需要輸入密碼。
對於別名,相當於用戶對於用戶組。權限配置處都可以使用別名,即①②③④處都能使用別名來配置。
例如,主機別名里設置多個主機,以后在②位置處直接使用主機別名。
FILESERVERS = fs1, fs2
以下是某設置示例:
DEFAULT=/bin/*,/sbin/ldconfig,/sbin/ifconfig,/usr/sbin/useradd,/usr/sbin/userdel,/bin/rpm,/usr/bin/yum,/sbin/service,/sbin/chkconfig,sudoedit /etc/rc.local,sudoedit /etc/hosts,sudoedit /etc/ld.so.conf,/bin/mount,sudoedit /etc/exports,/usr/bin/passwd [!-]*,!/usr/bin/passwd root,/bin/su - [!-]*,!/bin/su - root,!/bin/su root, /bin/bash, /usr/sbin/dmidecode, /usr/sbin/lsof, /usr/bin/du, /usr/bin/python, /usr/sbin/xm,sudoedit /etc/profile,sudoedit /etc/bashrc,/usr/bin/make,sudoedit /etc/security/limits.conf,/etc/init.d/*,/usr/bin/ruby ABC ALL=(ALL)NOPASSWD:DEFAULT
其中上面的"/usr/bin/passwd [!-]*"表示允許修改加參數的密碼。"/bin/su - [!-]*"表示允許"su -"到某用戶下,但必須給參數。
2.2.2 sudo和sudoedit命令
當sudo執行指定的command時,它會調用fork函數,並設置命令的執行環境(如某些環境變量),然后在子進程中執行command,sudo的主進程等待命令執行完畢,然后傳遞命令的退出狀態碼給安全策略並退出。
sudoedit等價於sudo -e,它是以sudo的方式執行文件編輯動作。
sudo [options] [command] 選項說明: -b :(background)該選項告訴sudo在后台執行指定的命令。 注意,如果使用該選項,將無法使用任務計划(job)來控制維護這些后台進程, 需要交互的命令應該考慮是否真的要后台,因為可能會失敗 -l[l] [command]:當單獨使用-l選項時,將列出(list)用戶可執行和被禁止的命令。 當配合command時,且該command是被允許執行的命令,將列出命令的全路徑及該命令參數。 如果command是不被允許執行的,則sudo直接以狀態碼-1退出。 可以指定多個字母"l"來顯示更詳細的格式 -n :使得sudo變成非交互模式,但如果安全策略是要求輸入密碼的,則sudo將報錯 -S :(stdin)該選項使得sudo從標准輸入而非終端設備上讀取密碼,給定的密碼必須在尾部加上換行符 -s [command] :(shell)指定要切換到的shell,如果給定command,則在此shell上執行該命令 -U user :(other user)配合-l選項來指定要列出哪個用戶的權限信息 -u user :(user)該選項明確指定要以此處指定的用戶而非root來運行command。 若使用uid的方式指定用戶,則需要使用"#uid",但很多時候可能需要對"#"使用"\"轉義,即使用"\#uid" -E :(environment)該選項告訴sudo在執行命令時保留自己的環境變量,保留環境變量的方式是執行環境配置文件。 但因為跨了用戶,所以很可能某些家目錄下的環境配置文件會因為無權限而執行失敗,此時sudo將報錯 -k [command] :當單獨使用-k選項時,sudo將使得用戶的認證緩存失效。下次執行sudo命令需要輸入密碼。 當配合command時,-k選項將忽略用戶的緩存,所以sudo將要求用戶輸入密碼,但這次輸入密碼不會更新認證緩存 但執行-k選項本身,不需要密碼 -K :(sure kill)類似於-k選項,但它會完全移除用戶的認證緩存,且不會配合command,執行-K本身不需要密碼 -v :(validate)該選項使得sudo更新用戶認證緩存 -- :暗示sudo命令行參數到此結束
在sudo上可以直接設置環境變量,它會傳遞為command的環境。設置的方式為var=value,如LD_LIBRARY_PATH=/usr/local/pkg/lib
由於sudo默認的安全策略插件是sudoers,所以當用戶執行sudo時,系統會自動去尋找/etc/sudoers文件(該文件里被root配置了用戶對應的權限,也即安全策略),查看sudo要使用的用戶是否有對應的權限,如果有則執行,如果沒有權限就失敗退出sudo。