這裡介紹 Linux 中 su
與 sudo
指令的使用方式,並提供幾個常用的範例。
Linux 系統最高權限的管理者帳號為 root
,也稱為超級使用者(superuser)帳號,這個帳號在使用上沒有任何限制,管理者只要取得這個帳號就可以對系統進行各種變更,例如格式化與掛載硬碟、新增或刪除使用者帳號、更改各種系統服務、更新系統等。
root
權限非常高,縱使是 Linux 老手在使用時也必須非常小心,若下錯指令是有可能造成系統損毀的,因此在管理 Linux 系統時,通常不建議直接使用 root
登入系統進行所有的操作,有些人為了方便甚至使用 root
登入後進入 X Window 的桌面環境,這會讓整個桌面環境中所有的應用程式都直接取得 root
權限,任何程式都可以在未經許可的狀況下存取或更改系統的任何設定,對於 Linux 伺服器來說這樣的動作是非常危險的。
為了避免不小心把系統搞砸,降低出錯的機率,在維護 Linux 系統時標準的作法是使用一般的帳號登入,遇到需要 root
權限時,再使用 su
或 sudo
取得較高的權限進行系統變更,以下是 su
與 sudo
的用法教學。
su
指令su
指令可以讓一般的 Linux 使用者取得 root
權限,取得 root
權限的使用者就如同 root
一樣可以對系統進行各種變更動作。
su
單純執行 su
並輸入 root
的密碼之後,就可以取得 root
權限,在不過這種情況下,雖然使用者帳號的 user id 變成 0
(root
的 user id),但是其他的環境變數並沒有跟著改變。
若只是單純需要以 root
權限做一些更改檔案等小動作,以上面這種簡單的 su
用法就夠了,而如果是要進行比較複雜的系統管理,牽涉到許多 root
帳號的環境變數(例如 PATH
或 MAIL
等)時,就要改用下面這種方式:
su -
在 su
後面加上一個減號後,就可以仿照 root
登入的方式,進入一個完整的 shell 環境,這個新的 shell 環境就跟使用 root
重新登入一樣。
不管是使用 su
或是 su -
,都會開啟一個新的 shell 環境,在完成所有需要 root
權限的工作之後,要執行 exit
或是按下 Ctrl
+ d
才會離開該 shell。若在進入新的 shell 之後,僅只需要執行一行簡單的指令,執行完後就馬上跳出,可以使用 -c
參數來指定要執行的指令內容:
su - -c "service nginx reload"
上面這個例子就會仿照重新登入的方式進到 root
帳號的 shell,並執行 service nginx reload
,完成後就自動離開 root
的 shell。
su
除了可以讓一般使用者取得 root
權限之外,也可以取得其他的帳號權限,我們可以在執行 su
時指定帳號名稱:
su seal
上面這行指定可以取得 seal
這個帳號的權限,而這裡在輸入密碼時就要輸入 seal
這個帳號的密碼。如果您是在 root
權限之下透過 su
指令來取得一般使用者的權限,這種狀況就可以不需要輸入該使用者的密碼。
sudo
指令sudo
指令類似 su
,也是可以用來取得 root
或是其他帳號的權限,不過它在取得 root
或其他帳號權限的時候,是輸入自己的密碼,而不是 root
或其他帳號的密碼,使用上比較方便。
root
帳號,無法用 root
直接登入系統,所有的系統管理動作都是透過 sudo
來取得 root
權限。sudo
在使用上會跟 su -c
類似,執行完指定的指令之後就會自動離開,這個例子會以 root
權限執行 ls
,查看一般使用者無法讀取的目錄:
sudo ls /usr/local/protected
若要查看 gtwang
這個使用者家目錄的檔案,可以切換為該帳號的權限之後,再用 ls
查看:
sudo -u gtwang ls ~gtwang
切換為 www
這個網頁伺服器用的系統帳號權限,編輯網頁檔案:
sudo -u www vi ~www/htdocs/index.html
sudo
也可以用 -g
參數來取得指定群組的權限,例如取得 adm
群組權限後,查看系統的記錄檔:
sudo -g adm view /var/log/syslog
等待十五分鐘之後重新開機:
sudo shutdown -r +15 "quick reboot"
許多人會習慣拿 sudo
與 su
放在一起使用,這樣藉由 su
取得一個新的 shell,而且也不用輸入 root
的密碼,通常在 Ubuntu Linux 中很常用:
sudo su -
/etc/sudoers
設定檔sudo
可以在不需要 root
密碼的情況下取得 root
權限,當然在正常的 Linux 系統中不可能讓所有的使用者都可以使用 sudo
,它是依據 /etc/sudoers
設定檔來管控的,只有在這個檔案中有被特別設定的使用者或群組才能使用 sudo
指令。
/etc/sudoers
的時候,請使用 visudo
這個指令來開啟 vi
編輯器進行編輯,系統會在編輯完成後自動檢查設定檔的語法是否正確,避免錯誤的語法導致 sudo
無法使用。/etc/sudoers
對個別使用者設定的語法格式如下:
帳號名稱 來源主機=(可切換帳號) 可執行的指令
其中四的欄位的意義為:
sudo
的帳號名稱。sudo
指令,可用來防止入侵者從不明的主機登入攻擊。若指定為 ALL
則代表不限制來源主機。ALL
則代表可以取得任何帳號的權限。ALL
則代表可以執行任何令。若要讓 gtwang
這個帳號可以使用 sudo
執行所有的指令,則在 /etc/sudoers
中加入這一行設定:
gtwang ALL=(ALL) ALL
基本上讓使用者允許使用 sudo
指令取得 root
權限,就等同於讓該使用者成為一位系統管理者了,所以別隨便開放 sudo
給一般的使用者,尤其是對於 Linux 不甚熟悉的人。
假設 accmgr
這個管理者是專門幫使用者重新這定密碼的,我們就可以透過這樣的設定限制 accmgr
這個管理者只能使用 root
權限執行 passwd
來更改使用者的密碼,而不能做其他的事情:
accmgr ALL=(root) /usr/bin/passwd
上面這種寫法有一個漏洞,就是 accmgr
也可以更改 root
帳號的密碼,如果 root
的密碼可被任意更改,整個系統的管理權限也會被取得,所以我們必須防止 accmgr
更動 root
的密碼:
accmgr ALL=(root) !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
這裡我們將可執行的指令加上更多的限制,首先是不可以直接執行 /usr/bin/passwd
,僅允許 /usr/bin/passwd
加上一般的使用者帳號,然後將 /usr/bin/passwd root
這個更改 root
密碼的指令也禁止。
如果要對特定群組底下的所有帳號一次開放權限,可以使用這樣的群組設定語法:
%群組名稱 來源主機=(可切換帳號) 可執行的指令
群組設定的語法跟個別帳號的方式相似,只不過群組的名稱在指定時前面要加上一個百分比 %
的符號,而其餘欄位則都相同。例如若要讓 wheel
群組中的所有使用者都可以使用 sudo
,則加入:
%wheel ALL=(ALL) ALL
如果想要讓特定的使用者可以在不需要輸入密碼的情況下,直接使用 sudo
,可以加入 NOPASSWD
的設定,例如:
gtwang ALL=(ALL) NOPASSWD:ALL
讓整個群組的使用者都不需要密碼:
%wheel ALL=(ALL) NOPASSWD:ALL
在沒有加入 NOPASSWD
的設定之下,如果使用者在五分鐘之內連續使用 sudo
好幾次,那麼只有在第一次使執行時需要輸入密碼,隨後再次執行 sudo
時,系統就不會要求使用者重複輸入,這樣的設計是預設五分鐘之內連續執行的指令應該都是同一人所為,所以不用再次輸入密碼,但若是超過五分鐘之後,就要重新驗證密碼。
有的時候 /etc/sudoers
的設定比較複雜,例如遇到很多的使用者以及指令組合的狀況時,我們可以使用別名(alias)的方式來管理設定:
User_Alias MYACC = accmgr, gtwang, seal Cmnd_Alias MYEXE = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root MYACC ALL=(root) MYEXE
這裡我們使用 User_Alias
建立一個帳號別名 MYACC
,其內容就是等號後方的那些帳號名稱,而 Cmnd_Alias
則是建立指令的別名,若要建立來源主機的別名則可用 Host_Alias
,所有的別名都要以大寫英文字母來命名,這樣的話就可以將冗長的設定簡化,並且重複使用,日後要修改也會比較方便。
參考資料:Unixmen、鳥哥的 Linux 私房菜、凍仁的筆記