maehachi08 Anything Blog

2013年06月07日
sudo、sudoersについてちょっと調べてみた

sudoとは

sudo(superuser do)は、許可されたユーザが、スーパーユーザをはじめ自分以外のユーザに変身してコマンドを実行できるようにするコマンドです。
sudoコマンドで実行されたコマンドの実効uid/gidは変身対象ユーザの/etc/passwdに記述されたuid/gidと同じ値がセットされてコマンドが実行されます。sudoコマンドのデフォルトの動作としてsudoを起動するユーザと同一だったりする場合は、パスワードは要求されない。それ以外の場合は、パスワードを要求して、本人であることを証明するように求めます。ここでいうパスワードはsudoコマンドを実行するユーザのものを指します。ユーザの認証がすむと、タイムスタンプが更新され、ユーザはしばらくの間 (sudoers で設定が変更されていないかぎり 5分間) パスワードなしで sudo を使用することができる。

sudoを使えるのは/etc/sudoersファイルに定義されたユーザだけ

先ほどsudoの説明の中で、”許可されたユーザが、スーパーユーザをはじめ自分以外のユーザに変身して”と書いた通り、許可のないユーザではsudoを使用できません。そして、デフォルトでは、rootユーザのみがsudoを使用する権限があります。
なので、いきなり一般ユーザでsudoコマンドを実行しても怒られます。まずは、その辺を確認しておきましょう。

一般ユーザでログインします。

$ id
uid=5000(pachi) gid=1000(worker) 所属グループ=1000(worker)

例えば、/var/log/messagesの内容を確認したい場合、普通にlessコマンドで見れないですよね。

$ less /var/log/messages
/var/log/messages: 許可がありません

これは当然なので、次にsudoで実行してみます。

$ sudo less /var/log/messages
[sudo] password for pachi: 
pachi は sudoers ファイル内にありません。この事象は記録・報告されます

うわぁ、なんか報告される...こわいですねぇ。
それはともかくとして、ここで重要なのは、

sudoを実行できるユーザは/etc/sudoersファイルに所定のフォーマットで定義されたユーザだけ

ということです。

/etc/sudoersにユーザを定義してsudoを使えるようにしよう

先述したとおり、デフォルトでsudoを実行できるのはrootだけです。それを確認しつつ、/etc/sudoersにユーザを追加する際の記述方法について触れていきます。

/etc/sudoersの下の方に以下のような記述があります。

root    ALL=(ALL)       ALL

この設定はどのホストでも(どこからでも)任意のユーザとしていかなるコマンドでも実行することを許可する設定です。
文法は以下のように捉えることができます。

<sudo権限を与えるユーザ名> <sudoを実行するホスト>=( <sudoで変身できるユーザ> ) <sudoを利用して利用可能なコマンド>

また、sudo権限をユーザではなく、グループに対して定義することも可能です。グループに対してsudo権限を与える場合はグループ名の頭にパーセント(%)を付けます。以下はwheelグループに対しての設定です。

%wheel ALL=(ALL) ALL

また、/etc/sudoersファイルにはそれぞれの設定値にエイリアスを設定する機能が存在します。ALLとかだとざっくりなんでもう少しセキュリティを考慮した設定を例として記載します。

  1. 許可するホストは192.168.0.0/16に存在するホストに制限
  2. 許可するユーザはpachi,maepachiの2ユーザに制限
  3. 変身するユーザをrootのみに制限
  4. sudo権限で実行可能なコマンドをcat,less,more,tail,headのみに制限

このような制限で/etc/sudoersに定義する場合は以下のようになります。

# Host_Aliasは範囲指定ではなく個別ホストのアドレスも定義可能
# Host_Alias    LOCAL   =  192.168.100.100
Host_Alias    LOCAL   =  192.168.0.0/16
User_Alias    WORKER  =  pachi, maepachi
Runas_Alias   OP      =  root
Cmnd_Alias    READER  =  /bin/cat, /usr/bin/less, /bin/more, /usr/bin/tail, /usr/bin/head

# エイリアスを使用しても並び順は変わらない
# <sudo権限を与えるユーザ名> <sudoを実行するホスト>=( <sudoで変身できるユーザ> ) <sudoを利用して利用可能なコマンド>
WORKER  LOCAL=(OP) READER

さて、基本的な記述方法を説明しましたが、重要な事を書き忘れていました。。。

/etc/sudoersファイルを編集する場合はvisudoコマンドを使用すること

これは非常に重要なことです。
visudo は sudoers ファイルをロックして、重複した編集が同時に行われないようにするとともに、整合性をざっと調べ、文法エラーのチェックを行ってくれます。
実際、あるターミナルでvisudo実行中に別のターミナルからvisudoを実行すると以下のエラーが表示されます。

# visudo 
visudo: /etc/sudoers がビジー状態です。後で再試行してください

また、文法に間違いがある状態でeditorを閉じようとすると警告が発せられます。

# visudo
visudo: >>> /etc/sudoers: syntax error (100行付近) <<<
次は何でしょうか? 
オプション:
  e -- sudoers ファイルを再度編集します
  x -- sudoers ファイルへの変更を保存せずに終了します
  Q -- sudoers ファイルへの変更を保存して終了します (*危険です!*)

そもそも/etc/sudoersはvimで開いた場合はreadonlyオプションが付いているので(:wq!なら可能ですが)上書きが出来ないようになっています。

# ls -l /etc/sudoers
-r--r----- 1 root root 4232  6月  7 20:21 2013 /etc/sudoers

上記のような理由から/etc/sudoersを編集する際は、visudoコマンドを使用しましょう。

sudo実行時の環境変数

CentOS6.4では/etc/sudoersに以下の設定がでデフォルトで有効です。設定についての説明をコメント行で追記してます。

# /etc/sudoers


# sudo が実行されるのは、ユーザが実際の tty にログインしたときだけになる。
# つまり、sudo を実行できるのは、 ログイン・セッションからだけであって、
# cronやcgi-binスクリプトといった他の方法を介して実行することが出来ない。
Defaults    requiretty


# visiblepwは使用しているターミナルでエコーの抑制ができず、
# パスワードがスクリーンに表示されてしまう場合でも、 sudo はパスワードを求めます。
# 今回は、頭にビックリマーク(!)が付加されているのでその逆で、
# visiblepwは使用しているターミナルでエコーの抑制ができない場合はsudo は実行を拒否する。
Defaults   !visiblepw


# sudo は環境変数 HOME を変身対象ユーザのホームディレクトリに設定する
# (-u オプションが使用されないかぎり、それは root である)。
# 事実上、暗黙のうちに sudo に -Hオプションが常に指定されることになる。
Defaults    always_set_home


# sudoは最小限の環境でコマンドを実行する。その環境に含まれる変数は以下のとおり。
# LOGNAME, SHELL, USER, USERNAME  、 及び SUDO_*
#
# その後でさらに、sudo を起動するユーザの環境にある変数のうち、
# env_keep や env_check のリストにマッチするものが追加される。
Defaults    env_reset


# env_reset オプションが有効になっているときでも、ユーザの環境にそのまま保存される環境変数。
# このオプションの引き数は、ダブルクォートで囲まれ、スペースで区切られたリストでもよく、
# ダブルクォートなしの単一の値でもよい。
#
# リストは、 =, +=, -=, !演算子を使って、それぞれ置き換えたり、
# 追加したり、削除したり、無効にしたりすることができる。
# 保存される変数のデフォルトのリストは、root ユーザが
# sudo に -V オプションを付けて実行した時に表示される。
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"


# sudo から実行されるあらゆるコマンドが使用するパス。
# sudo実行時に環境変数 PATH として使用されることになる。
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

こう見ていくとsudoも奥が深いし、使い込むのならそれなりに/etc/sudoersを改良していく必要もありそうですね。

では、sudo実行時のenvを見てみましょう。先ほどの/etc/sudoersの設定だとファイル読み込みコマンドのみ許可しているので、Cmnd_Aliasエイリアスに/bin/envを追加してみましょう。

# visudo
Cmnd_Alias    READER  =  /bin/cat, /usr/bin/less, /bin/more, /usr/bin/tail, /usr/bin/head, /bin/env

sudo権限でenvコマンドを実行します。

$ sudo env                                                               
[sudo] password for pachi: 
HOSTNAME=manage001.pachi.local
TERM=screen
HISTSIZE=1000
QTDIR=/usr/lib64/qt-3.3
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/pachi
LANG=ja_JP.UTF-8
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LOGNAME=root
USER=root
USERNAME=root
HOME=/root
SUDO_COMMAND=/bin/env
SUDO_USER=pachi
SUDO_UID=5000
SUDO_GID=1000

今日はここまでにします。