Linux 下使用 sudo
命令,可以讓普通使用者也能執行一些或者全部的 root 命令。本文就對我們常用到 sudo 操作情景進行簡單分析,通過一些例子來了解 sudo 命令相關的技巧。
情景一:使用者無許可權執行 root 命令
普通使用者登入 shell 之後,如果自身沒有許可權訪問某個檔案或執行某個命令時,若該使用者獲得root授權,那麼就可以在需要執行的命令之前加上 sudo,臨時切換到root使用者的許可權,完成相關的操作。在sudo於1980年前後被寫出之前,一般使用者管理系統的方式是利用su切換為超級使用者。但是使用su的缺點之一在於必須要先告知超級使用者的密碼,而sudo使一般使用者不需要知道超級使用者的密碼即可獲得許可權。
那麼哪些使用者可以臨時獲得 root 許可權呢?這就需要在 /etc/sudoers 檔案中進行配置:
授權給單個使用者:
1 2 |
# User privilege specification guohl ALL=(ALL) ALL |
上面這個例子中:
- guohl:允許使用 sudo 的使用者名稱
- ALL:允許從任何終端(任何機器)使用 sudo
- (ALL):允許以任何使用者執行 sudo 命令
- ALL:允許 sudo 許可權執行任何命令
如果我們想讓使用者 test 只能在本主機(主機名為guohl-pc)以 root 賬戶執行/bin/chown、/bin/chmod 兩條命令,那麼就應該這樣配置:
1 2 |
# User privilege specification test guohl-pc=(root) /bin/chown,/bin/chmod |
如果test 登入之後執行 sudo 命令,不滿足上面三個條件命令均失敗。
授權給使用者組:
1 2 3 |
# Allow members of group sudo to execute any command # (Note that later entries override this, so you might need to move it further down) %sudo ALL=(ALL) ALL |
和授權給單個使用者類似,只不過將使用者名稱在這裡換成%組名
,所有在該組中的使用者都按照此規則進行授權。對於該例,所有在 sudo 組內的使用者都有在任何終端(第一個ALL)、以任何使用者(第二個ALL)、執行任何命令(第三個ALL)的許可權,檢視 /etc/group 檔案可以知道哪些使用者屬於 sudo 組。
舉例:
如果當前帳號在 /etc/sudoers 檔案中被授予 sudo 的許可權,那麼你就可以將任何 root 命令作為 sudo 命令的引數,使用 root 許可權來執行該命令。舉例來說,掛載一個檔案系統只能由 root 來執行,但是一個普通使用者也可以使用 sudo 來掛載:
1 2 |
$sudo mount /dev/sda7 /mnt [sudo] password for guohailin: |
首次使用會要求你輸入當前使用者的密碼,系統確實輸入正確即以 root 許可權來執行 mount 命令,接下來一段時間(預設為5分鐘)再次使用 sudo 命令就不需要輸密碼了。
情景二:vim 編輯後發現忘記使用 sudo
我們經常會遇到這樣的一個囧境:使用 vim 對某個檔案進行編輯,編輯完之後,按 ESC
之後回到普通模式,再按 :wq
準備儲存退出時,發現沒有許可權對該檔案進行修改,我們在使用 vim 命令時忘記在前面加 sudo 了。我就經常出現這種問題,之前的做法是隻能不儲存強退,再加上 sudo 重新編輯。
但是今後我們再也不需要用這麼愚蠢的做法了,我們可以在 vim 的普通模式下,按 :w !sudo tee %
,這樣就可以 root 許可權來儲存檔案了,你也無需因為自己一時忘記加個 sudo 而沮喪懊惱了!
情景三:執行 root 命令忘記加 sudo
我們還會遇到這樣稍微好一點的情形:輸入一個長長的命令,按 Enter
之後出現無許可權操作,因為我們忘記加 sudo 了。大多人的做法是按 ↑
回到上一條命令,在該命令之前加上 sudo,再執行該命令。
以後,我們無需這樣了,只要輸入 sudo !!
即可,這裡的 !! 代表上一條命令。如:
1 2 3 4 5 6 7 8 9 |
$ head -n 4 /etc/sudoers head: cannot open `/etc/sudoers' for reading: Permission denied $ sudo !! sudo head -n 4 /etc/sudoers # /etc/sudoers # # This file MUST be edited with the 'visudo' command as root. # |
情景四:shell 內建命令如何使用 sudo
shell 是一個互動式的應用程式,在執行外部命令時通過 fork 來建立一個子程式,再通過 exec 來載入外部命令的程式來執行,但是如果一個命令是 shell 內建命令,那麼只能直接由 shell 來執行。sudo 的意思是,以別的使用者(如root)的許可權來 fork 一個程式,載入程式並執行,因此 sudo 後面不能跟 shell 的內建命令,如:
1 2 |
$ sudo cd /sys/kernel/debugfs sudo: cd: command not found |
在這種情況,我們又沒有 root 賬戶的密碼,我們怎樣執行該命令呢?有種辦法就是使用 sudo 獲得root shell 的許可權,然後在root shell 中執行該命令。進入root shell 很簡單,輸入sudo bash
確認本使用者的密碼即可,此時你會發現命令提示符顯示當前是 root。一旦獲得root shell,你可以執行任何命令而不需要在每條命令前輸入sudo了。
另外,常用的shell 內建命令在這裡 有簡單介紹,我們可以使用 type 命令來檢視命令的型別,如:
1 2 3 4 |
$ type ls ls is /bin/ls $ type umask umask is a shell builtin |
情景五:sudo 操作記錄日誌
作為一個 Linux 系統的管理員,不僅可以讓指定的使用者或使用者組作為root使用者或其它使用者來執行某些命令,還能將指定的使用者所輸入的命令和引數作詳細的記錄。而sudo的日誌功能就可以使用者跟蹤使用者輸入的命令,這不僅能增進系統的安全性,還能用來進行故障檢修。但是要記錄sudo的日誌還要一些簡單的配置:
- 建立sudo日誌檔案
我們將sudo日誌檔案放置在/var/log/sudo.log
檔案中:
1$ sudo touch /var/log/sudo.log - 修改
/etc/rsyslog.conf
配置檔案
我使用系統為Ubuntu13.04 為改名字,但有些系統名為/etc/syslog.conf
,注意不同發行版之間的差別,在該檔案加入下面一行:
1local2.debug /var/log/sudo.log #空白不能用空格,必須用tab - 修改
/etc/sudoers
配置檔案
注意網上很多關於sudo日誌檔案配置都缺少這一步!在該檔案中加入下面一行:
1Defaults logfile=/var/log/sudo.log - 重啟 syslog 服務:
1$ sudo service rsyslog restart - 檢視 sudo 日誌記錄:
經過上面的配置,sudo 的所有成功和不成功的sudo
命令都記錄到檔案/var/log/sudo.log 中,例如我執行幾條sudo 命令之後,檢視該檔案的記錄如下:
123456789$ cat sudo.logSep 20 22:10:51 : guohailin : TTY=pts/1 ; PWD=/var/log ; USER=root ;COMMAND=/bin/cat /etc/sudoersSep 20 22:11:36 : guohailin : TTY=pts/1 ; PWD=/var/log ; USER=root ;COMMAND=/usr/sbin/service rsyslog restartSep 20 22:11:45 : guohailin : TTY=pts/1 ; PWD=/var/log ; USER=root ;COMMAND=/bin/lsSep 20 22:12:08 : guohailin : TTY=pts/1 ; PWD=/var/log ; USER=root ;COMMAND=/bin/ls /root/