前回は、すべてのコマンドが使用できてしまう特権ユーザー(スーパーユー ザー)の利用制限について説明した。今回は、引き続き特権ユーザーが通常行うsuのセキュリティ上の問題点やsudoの基本的な使い方について紹介する。
suコマンドは、再ログインになしにrootに限らず任意のユーザーにスイッチすることができるという、とても便利なコマンドだ。しかし、そんなsuコマンドには、以下に示すようなことが懸念されている。
●rootのパスワードを入力する必要がある
suコマンドは、実行時にスイッチするユーザーのパスワードを入力する必要がある。例えばtelnetでリモートログイン*1してsu rootした場合、当然のことながらネットワーク上にはrootのパスワードが流れてしまうため、万が一盗聴された場合にシステム全体を乗っ取られる可能性も高くなる。また、su rootを実行できるユーザー間でrootのパスワードを共有することになるので、共有する人数が多ければ多いほどrootパスワードの漏えいの危険性も増すことになる。
●suした後の実行コマンドがログに残らない
suを実行すると任意のユーザー権限でシェルを実行するが、シェルを実行した後の各コマンドの実行履歴がログに残らない。例えば、いつだれがroot権限でそのコマンドを実行したのかが特定できない。*2
●コマンド単位で権限を制限できない
suコマンドは、特定コマンドのみsuの実行を許したり、禁止したりすることができない。例えばsu rootすると、スイッチしたrootユーザーのシェル権限が与えられ、その上で実行するすべてのコマンドがroot権限で動作することになる。
以上のようなsuコマンドで懸念されている点を改善するため、本稿ではsudoを使った管理者特権の利用制限について説明する。
sudo(superuser do)は、あるユーザーが別のユーザーとしてコマンドを実行できるようにするためのコマンドだ。先述のsuコマンドと目的は同じだが、セキュリティ面ではsudoの方がより強化されている。
sudoのメインページ(http://www.courtesan.com/sudo/)やミラーサイトからsudoのソースやRPM版などをダウンロードしインストールする(ファイルの整合性チェックも忘れず行うこと)。 portsやpkgsrcの場合はsecurity/sudoからインストールする。
なお、sudoのバージョン1.6.5p2までにはセキュリティホールが含まれているので最新版を入手すること。以下はソースからコンパイルする一例だ。
% gunzip -cd < sudo-1.6.7p5.tar.gz | tar xvf - % cd sudo-1.6.7p5 % ./configure % make # make install
コンパイルで手間どうことはないだろうが、詳細については展開先のINSTALLファイルを参照するとよいだろう。
インストールが完了したら、あとは実際にsudoコマンドを使ってみる。sudoコマンドの書式を以下に示す。
sudoコマンドの書式 |
---|
sudo[オプション]コマンド |
sudoコマンドの主なオプション | 指定する内容 |
---|---|
-l | 現在の設定状況を表示 |
-L | sudoのデフォルト設定値(変数)を表示 |
-u | user|#uid コマンドの実行ユーザー名もしくはUIDを指定する。省略した場合rootが仮定される |
-s | シェルを実行する。suと同じような形式 |
ここで説明した以外にもいくつかオプションがあるので、man sudoで確認しておくとよいだろう。
基本的な使い方を覚えたらあとは実際に使うだけだが、デフォルトの設定では一般ユーザーはsudoを利用できない。例えば、以下のようなrootしか読めないファイル(/var/log/secure)をsudoを使って読もうとすると、拒否メッセージが表示され、管理者あてにメールが届くことになる(デフォルト)。
% ls -l /var/log/secure -rw------- 1 root wheel 0 Apr 8 2003 /var/log/secure
sudoコマンド実行拒否の様子
% sudo less /var/log/secure We trust you have received the usual lecture from the local System Administrator. It usually boils down to these two things: #1) Respect the privacy of others. #2) Think before you type. Password: kimuのパスワードを入力 kimu is not in the sudoers file. This incident will be reported.
また、拒否メッセージと同時に、rootあてに以下のようなメールも届く。
From: kimu To: root Subject: *** SECURITY information for atmarkit.example.co.jp *** atmarkit.example.co.jp : Oct 8 03:35:19 : kimu : user NOT in sudoers ; TTY=ttyp7 ; PWD=/home/kimu ; USER=root ; COMMAND=/usr/bin/less /var/log/secure
さらには、sudoで実行した結果は、ログ(/var/log/messagesなど)にも記録される。
Oct 8 03:35:19: atmarkit sudo: kimu : TTY=ttyp7 ; PWD=/home/kimu ; USER=root ; COMMAND=/usr/bin/less /var/log/secure
ご覧いただいたとおり、デフォルトの設定ではroot以外だれもsudoを使えない状態なので、次に示す設定が必要になる。
デフォルトではroot以外はsudoを使えない。そのため、最初に基本的な設定から行う。例えばsuで行ったように、wheelグループに属するユーザーに対してsudoの利用権限を与えるように設定を変更してみる。
sudoの設定は、sudoersファイルで行う。そしてsudoersファイルを編集するには、viなどのエディタで直接編集するのではなく、sudoのメンテナンスコマンドであるvisudoコマンドを使うようにする。
# visudo
visudoは、sudoersファイルのロックや構文チェック*3なども行ってくれる便利なコマンドで、ファイルの編集には、環境変数のEDITOR にセットされているエディタが使用される。
*3
sudoersファイルの記述を間違えると以下のようなエラーが表示され、sudoersを再編集するどうかを聞かれる。
>>> sudoers file: syntax error, line 28 <<<
What now?
“What now?” に対してeを入力すると編集モードに戻る。
wheelグループを許可する設定は、あらかじめコメントアウト(先頭に#が付加)されているだけなので、以下に示すとおり行頭の#を取り除いて保存、終了すればよい。
%wheel ALL=(ALL) ALL
wheelグループにkimuを追加し、もう一度同じようにsudoを試してみる。
% sudo less /var/log/secure Password: kimuのパスワードを入力
正しく設定されていれば、lessで/var/log/secureファイルの中身を読むことができるはずだ。
さて、ここまでで気付いたかもしれないが、冒頭に述べたsuコマンドで懸念されていた点が、2つほどクリアされていることが分かる。
1.rootパスワードの不要
su rootを実行する場合は、rootのパスワードが必要になるが、sudoでは、sudoを実行したユーザーのパスワードさえ分かっていればよいので、各ユーザー間でrootのパスワードを共有する必要がなくなる。su rootを実行する場合は、rootのパスワードが必要になるが、sudoでは、sudoを実行したユーザーのパスワードさえ分かっていればよいので、各ユーザー間でrootのパスワードを共有する必要がなくなる。
2.実行したコマンドの履歴保存
sudoで実行したコマンドの履歴はログファイル(syslog)に記録される。
Oct 8 03:35:19: atmarkit sudo: kimu : TTY=ttyp7 ; PWD=/home/kimu ; USER=root ; COMMAND=/usr/bin/less /var/log/secure
上記の例では、ユーザーkimuがターミナルttyp7からlessコマンドで/var/log/secureファイルを参照した結果だ。PWDはどのディレクトリ上からコマンドを実行したか、USERはどのユーザー権限でコマンドを実行したのかが記録される。
ただし、ログへの保存はsudoが実行されるたびに行われるが、sudo -sやsudo suでシェル権限を取得し、その上で実行されるコマンドについては記録されないことに注意する必要がある。
残りの1つ(コマンド単位で権限を制限)については、次で説明する。
sudoを有効活用するためには、提供されている機能の仕組みと構文を理解しておく必要がある。
●エイリアス(別名)機能
sudoersには、次の4タイプのエイリアスを定義できる。
エイリアスタイプ | 用途 |
---|---|
User_Alias | ユーザー名の別名を定義する |
Runas_Alias | 実行ユーザー名の別名を定義する |
Host_Alias | 接続元ホストの別名を定義する |
Cmnd_Alias | 実行するコマンドの別名を定義する |
例えば、User_Aliasを使うことで、複数のユーザーをある1つの名前としてグループ化させることができる。各エイリアスの書式は以下のとおりとなる。
User_Alias NAME = User_List [: NAME = User_List]…… Runas_Alias NAME = Runas_List [: NAME = Runas_List]…… Host_Alias NAME = Host_List [: NAME = Host_List]…… Cmnd_Alias NAME = Cmnd_List [: NAME = Cmnd_List]……
エイリアスタイプや定義エイリアス(NAME)は、大文字のA-Z、数字、アンダーバー(_)を使用する。そして先頭文字は必ずA〜Zで始まる必要がある。
以下に各エイリアスの使用例を示す。
User_Alias WEBMASTER = kimu, yasu, foobar Runas_Alias OP = root, operator Host_Alias INTERNAL = 192.168.0.0/24 Host_Alias EXTERNAL = 172.16.0.1, 172.16.0.10 Cmnd_Alias DUMPS = /bin/mt, /sbin/dump, /sbin/rdump, \ /sbin/restore, /sbin/rrestore Cmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown, /sbin/poweroff, \ /sbin/reboot, /sbin/fastboot, /sbin/init
1行目のUser_Aliasでは、エイリアス名WEBMASTERに、それぞれkimu、yasu、foobarの3つのユーザー名を割り当てている。
2行目のRunas_Aliasでは、エイリアス名OPに、rootおよびoperatorというコマンドの実行ユーザーを割り当てている。
3、4行目のHost_Aliasでは、エイリアス名INTERNALに192.168.0.0/24というネットワークを、エイリアス名EXTERNALに172.16.0.1および172.16.0.10というIPアドレスを持つホストをそれぞれ割り当てている。
5、6行目のCmnd_Aliasでは、エイリアス名DUMPSにバックアップを採取するために必要なコマンド群(/bin/mt、/sbin/dumpなど)を割り当て、エイリアス名SHUTDOWNにOSを起動・停止するために必要なコマンド群を割り当てている。
●制限対象ユーザーの定義
特定ユーザーやグループ、さらには前述のUser_Aliasで指定した内容を基に、sudoで利用できるユーザー、接続元ホスト、コマンドなどを制限する。書式は以下のとおりとなる。
User_Spec User_List Host_List = (Runas_List) (NOPASSWD: | PASSWD:)? Cmnd_List
“?” が付加されている項目は、省略可能であることを意味している。
以下に前述のエイリアスも含めた利用制限の簡単な例を示す。
Host_Alias INTERNAL = 192.168.0.0/24 Cmnd_Alias REBOOT = /sbin/reboot kimu ALL = (ALL) ALL %wheel ALL = (ALL) ALL yasu ALL = (www) /usr/bin/su foobar INTERNAL = (root) REBOOT
1、2行目は、先述のエイリアスの説明で、制限対象ユーザーの定義は空行をはさんだ4行目から始まる。
4行目のユーザーkimuは、すべての接続元(ALL)から、すべてのユー ザー権限((ALL))で、すべてのコマンド(ALL)を実行できる。
5行目のグループ%wheelも4行目と同様のことを行える。
6行目のユーザーyasuは、すべての接続元(ALL)から、ユーザーwwwの権限で((www))、コマンド/usr/bin/suのみ実行できる。
7行目のユーザーfoobarは、INTERNALの接続元から、ユーザーrootの権限で((root))、REBOOTで定義されたコマンド(/sbin/reboot)のみ実行できる。
以上の使用例から、どういった設定を行うのかを直感的に理解していただけたと思う。このほかのsudoersの設定や詳細については、sudoのオンラインマニュアル(man sudoers)で確認してほしい。
基幹業務サーバともなると、役割に応じて担当者が異なることもある。例えば、バックアップテープ交換の担当者とWeb サーバの起動・停止の担当者が異なるようなケースだ。
両担当者ともメンテナンスを行うためにはroot権限が必要となるが、セキュリティ上の理由、または操作ミスによる影響範囲を最小限に抑えるために、root権限によるコマンドの実行を特定コマンドのみに限定したい場合がある。そのようなケースにおいて、sudoは非常に重宝する。
例:ユーザーbackupとユーザーwebadmのroot権限で実行可能なコマンドを制限する。
% sudo visudo
sudoersに以下の2行を追加する。
backup ALL = (root) /bin/mt webadm ALL = (root) /etc/rc.d/apache.sh
設定は保存終了した時点で有効となる。
例:前述の例に、特定のネットワークから接続してきたユーザーのみ許可するように拡張する。ユーザーbackupは192.168.0.0/24、ユーザーwebadmは192.168.100.0/24 からのみに限定する。
% sudo visudo
sudoersに以下を追加(修正)する。
Host_Alias NET1 = 192.168.0.0/24 Host_Alias NET2 = 192.168.100.0/24 backup NET1 = (root) /bin/mt webadm NET2 = (root) /etc/rc.d/apache.sh
以上、実際の運用ともなると、もう少し細かな調整が必要になるが、やるべきことは理解していただけたと思う。
最後に、sudo を使う上で、よくやってしまいがちなミスをなくすための設定を紹介しておく。その代表的な例として、OSの起動・停止コマンドをsudoから実行できないようにする設定である。これにより、操作ミスでうっかりサーバを再起動してしまったということがなくなる。
例:OSを起動・停止するコマンドの実行のみ禁止する。それ以外は許可。
% sudo visudo
sudoers に以下を追加する。
Cmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown, /sbin/poweroff, \ /sbin/reboot, /sbin/fastboot, /sbin/init root ALL=(ALL) ALL, !SHUTDOWN %wheel ALL=(ALL) ALL, !SHUTDOWN
Cmnd_AliasでSHUTDOWNを定義し、OSの起動・停止に関するコマンドを グループ化する。後はグループ化したSHUTDOWNをsudoで実行できないように設定するだけだ。その場合、SHUTDOWNの先頭に!を付加して“否定”にする必要がある。設定後、実際にSHUTDOWNで定義されたコマンドを実行しようとすると、以下のような拒否メッセージが表示され実行できなくなる。
% sudo reboot Sorry, user kimu is not allowed to execute '/sbin/reboot' as root on atmarkit.example.co.jp.
OS起動・停止コマンド以外にも、実運用に影響を与えてしまいそうなコマンドは、sudoで気軽に実行できないように制限することをお勧めする。特に簡単に止めることのできない基幹系のサーバならなおさらだ。
それらのコマンドを使う場合は、sudo -sやsudo suでシェル権限を得てから、ワンクッションおいてから慎重に実行するとよいだろう。
sudoでは一度入力されたパスワードをターミナルごとにキャッシュする。デフォルトでは5分間有効となり、キャッシュタイムアウトはsudoを実行するたびに更新される。
この機能は非常に便利だが、パスワードの入力なしに連続してsudoを実行できるため、root権限でコマンドを実行する際に重要となる“慎重さ”を欠いてしまう。そのため、特に重要なサーバの場合はキャッシュを利用せず、sudo実行時に毎回パスワードを聞くような設定(timestamp_timeout = 0)をsudoersに記述しておくとよいだろう。
Defaults timestamp_timeout = 0
また、“慎重さ”をさらに持たせたいのであれば、sudoのパスワードプロンプトも変更することをお勧めする。sudoを実行した際のパスワードプロンプトは、
Password:
のようなシンプルなものだが、これにsudoを実行したユーザー名(%u)やホスト名(%h)などを明示することで、sudoコマンド実行者に、どのサーバ上でどのユーザーから実行しようとしているのかを再認識させることができる。
sudoのパスワードプロンプトを変更する場合は、sudoresに例えば以下のように記述する。
Defaults passprompt = "%u@%h Password: "
設定を保存すると、「kimu@atmarkit Password:」のようなパスワードプロンプトに変更される。
なお、このほかDefaultsで設定変更可能な内容は、sudo -Lかman sudoersで確認するとよいだろう。
Copyright © ITmedia, Inc. All Rights Reserved.