免密碼 sudoer 關機

debian shutdown 命令本來可以在本機由任何使用者執行, 也就是只要坐在電腦前,任何帳號都能直接關機。 但如果在床上用手機用 ssh, 要從手機關機就要用 sudo,要打密碼麻煩。 所以就用 ssh 公私鑰免密碼,再把 sudo 也設成免密碼。

不知道 shutdown 的機制是怎麼做的, shutdown 好像是一個符號連結到 systemd, 由於是符號連結,權限是 777; systemd 也是 a+x ,大家都能看系統狀態, shutdown 也就任何使用者能都能執行。

但 systemd 內部被以 shutdown 執行時, 會判斷執行者的權限,如果是從遠端像 ssh 登入, 就會報錯然後退出:

Failed to set wall message, ignoring: Interactive authentication required.
Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: Interactive authentication required.

從遠端得要用 sudo,但我遠端已用公私鑰登入,不用打密碼。 如果還要用 sudo 關機,就還得打一次密碼。 sudo 要打一次密碼真有點麻煩, 有時候用 ssh 登入只想執行個 sudo 命令, 就要登入打一次密碼,sudo 再打一次。

ssh 用公私鑰就不用密碼, sudo 則可以用 visudo 改 /etc/sudoers , sudo 本來能指定能執行的指令, 加 NOPASSWD: 選項可以指定不用密碼。 我是創一個群組,指定該群組可以不用密碼執行 sudo shutdown

# %group  host runspec  option:  path
%shutdown ALL=(ALL:ALL) NOPASSWD:/sbin/shutdown

我讀 sudoers 的手冊讀半天,她語法是用 EBNF 寫, 開頭有稍微簡介一下 EBNF 的語法, 但沒有看,反正就和 regexp 有點像。

中間卡很久,visudo 如果格式錯誤, 會報錯不讓你存檔,就試半天:

  1. runspec 不知道要設什麼, 後來就抄原本就有的 sudo 群組設定。
  2. shutdown 原本不知道要用絕對路徑, 後來無意間才試對。

現在用 VXConnectBot 設一個主機, 是連到我宿網的 ip,連上後直接執行 sudo shutdown +5+5 是怕按錯,可以有五分鐘時間再取消。 另外 vx connect bot 的登入後執行, 不是 ssh 直接打在最後的指令, 是一樣會開 interactive shell, 還有在命令中寫 enter,才會送出 enter, 執行完也不會退出。