適切な権限管理や安定した運用、セキュリティの関係上、 特定のコマンドのみ sudo を許可したいということがあるかと思います。

今回は sudo の設定方法と Tips を紹介していきます。

sudo の設定

sudo の設定は /etc/sudoers で記載された内容が反映されます。

以下は macOS のデフォルトの設定です。

## sudoers file.
##
## This file MUST be edited with the 'visudo' command as root.
## Failure to use 'visudo' may result in syntax or file permission errors
## that prevent sudo from running.
##
## See the sudoers man page for the details on how to write a sudoers file.
##

##
## Host alias specification
##
## Groups of machines. These may include host names (optionally with wildcards),
## IP addresses, network numbers or netgroups.
# Host_Alias	WEBSERVERS = www1, www2, www3

##
## User alias specification
##
## Groups of users.  These may consist of user names, uids, Unix groups,
## or netgroups.
# User_Alias	ADMINS = millert, dowdy, mikef

##
## Cmnd alias specification
##
## Groups of commands.  Often used to group related commands together.
# Cmnd_Alias	PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \
# 			    /usr/bin/pkill, /usr/bin/top

##
## Defaults specification
##

Defaults    env_reset
Defaults    env_keep += "BLOCKSIZE"
Defaults    env_keep += "COLORFGBG COLORTERM"
Defaults    env_keep += "__CF_USER_TEXT_ENCODING"
Defaults    env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE"
Defaults    env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME"
Defaults    env_keep += "LINES COLUMNS"
Defaults    env_keep += "LSCOLORS"
Defaults    env_keep += "SSH_AUTH_SOCK"
Defaults    env_keep += "TZ"
Defaults    env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY"
Defaults    env_keep += "EDITOR VISUAL"
Defaults    env_keep += "HOME MAIL"

Defaults    lecture_file = "/etc/sudo_lecture"

##
## Runas alias specification
##

##
## User privilege specification
##
root ALL=(ALL) ALL
%admin  ALL=(ALL) ALL

## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL) ALL

## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL

## Uncomment to allow members of group sudo to execute any command
# %sudo	ALL=(ALL) ALL

## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).
# Defaults targetpw  # Ask for the password of the target user
# ALL ALL=(ALL) ALL  # WARNING: only use this together with 'Defaults targetpw'

## Read drop-in files from /private/etc/sudoers.d
## (the '#' here does not indicate a comment)
#includedir /private/etc/sudoers.d

この sudoers ファイルを書き換えることで設定を変更することができます。

コマンドの制限

【ユーザー名】 ALL = (ALL:ALL) ALL
%【グループ名】 ALL = (ALL:ALL) ALL

のような書き方でユーザーまたはグループに応じて、 どのユーザーまたはグループまたはその両方として sudo を介し、コマンドを実行できるかの制限を行うことができます。

例えば Xcode にまつわるコマンド類を Example_Group グループに所属しているメンバーに root ユーザーでの実行許可を与えるとした場合、

Cmnd_Alias XCODE_COMMANDS = /usr/bin/xcodebuild, /usr/bin/xcrun, /usr/bin/xcode-select

%Example_Group ALL=(root) XCODE_COMMANDS

とすることで設定することができます。

最初の ALL

ホスト名に対する許可の項目です。ALL は全てのホストを表しており、個別に指定することもできます。

(): の左側の ALL

ユーザーに対する許可の項目です。 ALL は全てのユーザーを表しており、個別に指定することもできます。

(): の右側の ALL

グループに対する許可の項目です。 ALL は全てのグループを表しており、個別に指定することもできます。 また、: 無しの場合はユーザーのみを表し、グループは無視されます。

最後の ALL

コマンドに対する許可の項目です。ALL は全てのコマンドを表しており、個別に指定することもできます。

ファイルの分離

/etc/sudoers を編集することで sudo の設定ができますが、 煩雑になってしまう可能性もあるので、sudoers を直接編集することはオススメしません。
また、ファイルを分けてチェッカーを走らせること(後述参照)で、文法エラー防止にも役立ちます。

ファイルの分離は、

## Read drop-in files from /private/etc/sudoers.d

とあるように、/etc/sudoers.d ディレクトリの中に設定ファイルを入れるとその内容も合わせて読み取ってくれます。

分離したファイルの権限

ファイルを分離した際に気をつけないといけないのが権限です。 /etc/sudoers440 です。/etc/sudoers.d 内に作成した設定ファイルも 440 に変更する必要があります。

文法エラー

sudoers や include したファイルで文法エラーになると sudo コマンドが使えなくなります。 これになると本当に絶望します。

文法エラーになった瞬間は、「やばい、やらかした。。。」と思うかもしれませんが、一応復旧方法はあります。

Linux での復旧方法

pkexec visudo

をすることで super user として visudo を実行することができ、sudoers ファイルを変更することができます。

また、-f オプションを使用することで、sudoers.d のディレクトリ内部のファイルも変更できます。

macOS での復旧方法

macOS には pkexec コマンドが無いため詰んだと思ったのですが、GUI で解決させることができます。

  1. 「Terminal.app で open /etc を入力」または「Finder で 移動 > フォルダへ移動 > /etc を入力 > 移動」します。 macOS で sudo が使えなくなった際の対応手順1 macOS で sudo が使えなくなった際の対応手順2
  2. 該当ファイルを右クリックして「情報を見る」を選択します。 macOS で sudo が使えなくなった際の対応手順3
  3. 鍵アイコンをクリックして、 everyone の項目を 読み / 書き に変更します。 macOS で sudo が使えなくなった際の対応手順4 macOS で sudo が使えなくなった際の対応手順5
  4. 該当ファイルをお好みのエディタで編集して文法エラーを編集してください。
  5. 編集が終わったら 2 の手順で everyone を アクセス不可 に戻して終了です。

Tips

\ が含まれる文字を使用したい

\ は設定ファイルを改行しても連続していることを表すために使用されるため、グループ名などに含まれる場合は \ だと認識されません。 \\ とすることで初めてエスケープされるので注意が必要です。

sudoers のコメント

sudoers# 以降は、コメントとして扱われます。 しかし、#includedir# はコメントではなく、C言語のようなディレクティブとして機能します。

間違えやすいので、 コメントする際は ## のように2以上連続で # を記載することをオススメします。

事前に文法をチェックしたい

文法エラーになっても直せることがわかったものの、毎回リカバリ対応してると try & error が行いづらいです。 設定変更や文法チェックはぶっつけ本番ではなく事前にテストを行いたいです。

visudo -cs -f ファイル名

上記のコマンドを実行することで、文法をチェックが行え、sudoers の設定がスムーズになります。

また、使用したいコマンドは常に変化していくので、運用に耐えうるために CI を回しましょう。 そうすることで設定のチェックを自動化できます。

各オプション

オプション 効果
-c sudoers が問題ないかをチェックするためのモードを ON にするための指定
-s strict モードを ON にするための指定
権限のチェックもしてくれる
-f デフォルトで /etc/sudoers を参照するが、このオプションで他のファイルを参照可能

まとめ

sudo の設定方法および設定ファイルの分離方法と、sudo におけるコマンドの制限の方法を説明しました。

また、文法エラーの復旧方法と、そもそもぶっつけ本番で文法エラーにならないような仕組みについてお話ししました。 CI ガンガン回して行きましょう。

更に詳しい情報に関しては man visudoman sudoers を御覧ください。