【連載】
止められないUNIXサーバのセキュリティ対策
(「止められない基幹業務サーバの管理対策」改め)
第5回 サービスをセキュアにするための利用制限(3)
〜管理者権限の制限のためのsuとsudoの基本〜
三井物産GTI (現:三井物産セキュアディレクション株式会社)
木村 靖
2003/11/5
※ご注意 本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。 |
前回は、すべてのコマンドが使用できてしまう特権ユーザー(スーパーユー ザー)の利用制限について説明した。今回は、引き続き特権ユーザーが通常行うsuのセキュリティ上の問題点やsudoの基本的な使い方について紹介する。
suの問題点 |
suコマンドは、再ログインになしにrootに限らず任意のユーザーにスイッチすることができるという、とても便利なコマンドだ。しかし、そんなsuコマンドには、以下に示すようなことが懸念されている。
- rootのパスワードを入力する必要がある
suコマンドは、実行時にスイッチするユーザーのパスワードを入力する必要がある。例えばtelnetでリモートログイン*1してsu rootした場合、当然のことながらネットワーク上にはrootのパスワードが流れてしまうため、万が一盗聴された場合にシステム全体を乗っ取られる可能性も高くなる。また、su rootを実行できるユーザー間でrootのパスワードを共有することになるので、共有する人数が多ければ多いほどrootパスワードの漏えいの危険性も増すことになる。
*1
telnetではなくsshによる暗号化通信を行えば盗聴の危険性も減るが、それでもrootのパスワードがネットワーク上に流れるのは、あまり気持のよいものではない。
- suした後の実行コマンドがログに残らない
suを実行すると任意のユーザー権限でシェルを実行するが、シェルを実行した後の各コマンドの実行履歴がログに残らない。例えば、いつだれがroot権限でそのコマンドを実行したのかが特定できない。 *2
*2
アカウンティング機能を使えばある程度は残せる。アカウンティング機能については次回説明する。
- コマンド単位で権限を制限できない
suコマンドは、特定コマンドのみsuの実行を許したり、禁止したりすることができない。例えばsu rootすると、スイッチしたrootユーザーのシェル権限が与えられ、その上で実行するすべてのコマンドがroot権限で動作することになる。
以上のようなsuコマンドで懸念されている点を改善するため、本稿ではsudoを使った管理者特権の利用制限について説明する。
sudoを使う |
●sudoとは
sudo(superuser do)は、あるユーザーが別のユーザーとしてコマンドを実行できるようにするためのコマンドだ。先述のsuコマンドと目的は同じだが、セキュリティ面ではsudoの方がより強化されている。
●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 - |
コンパイルで手間どうことはないだろうが、詳細については展開先のINSTALLファイルを参照するとよいだろう。
●sudoの基本的な使い方
インストールが完了したら、あとは実際に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 |
sudoコマンド実行拒否の様子
% sudo less /var/log/secure
|
また、拒否メッセージと同時に、rootあてに以下のようなメールも届く。
From: kimu |
さらには、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 |
正しく設定されていれば、lessで/var/log/secureファイルの中身を読むことができるはずだ。
さて、ここまでで気付いたかもしれないが、冒頭に述べたsuコマンドで懸念されていた点が、2つほどクリアされていることが分かる。
- rootパスワードの不要
su rootを実行する場合は、rootのパスワードが必要になるが、sudoでは、sudoを実行したユーザーのパスワードさえ分かっていればよいので、各ユーザー間でrootのパスワードを共有する必要がなくなる。
- 実行したコマンドの履歴保存
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でシェル権限を取得し、その上で実行されるコマンドについては記録されないことに注意する必要がある。
●詳細な設定を行うために
sudoを有効活用するためには、提供されている機能の仕組みと構文を理解しておく必要がある。
・エイリアス(別名)機能
sudoersには、次の4タイプのエイリアスを定義できる。
エイリアスタイプ
|
用途
|
User_Alias | ユーザー名の別名を定義する |
Runas_Alias | 実行ユーザー名の別名を定義する |
Host_Alias | 接続元ホストの別名を定義する |
Cmnd_Alias | 実行するコマンドの別名を定義する |
例えば、User_Aliasを使うことで、複数のユーザーをある1つの名前としてグループ化させることができる。各エイリアスの書式は以下のとおりとなる。
User_Alias NAME = User_List [: NAME
= User_List]…… |
エイリアスタイプや定義エイリアス(NAME)は、大文字のA-Z、数字、アンダーバー(_)を使用する。そして先頭文字は必ずA〜Zで始まる必要がある。
以下に各エイリアスの使用例を示す。
User_Alias WEBMASTER = kimu, yasu, foobar |
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
|
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権限で実行可能なコマンドを制限する。
- ユーザーbackup:バックアップ操作コマンド(mt)のみrootで実行可能
- ユーザーwebadm:Webサーバの起動・停止スクリプト(apache.sh)のみrootで実行可能
% sudo visudo |
sudoersに以下の2行を追加する。
backup ALL = (root) /bin/mt |
設定は保存終了した時点で有効となる。
例:前述の例に、特定のネットワークから接続してきたユーザーのみ許可するように拡張する。ユーザーbackupは192.168.0.0/24、ユーザーwebadmは192.168.100.0/24 からのみに限定する。
% sudo visudo |
sudoersに以下を追加(修正)する。
Host_Alias NET1 = 192.168.0.0/24
|
以上、実際の運用ともなると、もう少し細かな調整が必要になるが、やるべきことは理解していただけたと思う。
●ありがちなミスを防ぐ
最後に、sudo を使う上で、よくやってしまいがちなミスをなくすための設定を紹介しておく。その代表的な例として、OSの起動・停止コマンドをsudoから実行できないようにする設定である。これにより、操作ミスでうっかりサーバを再起動してしまったということがなくなる。
例:OSを起動・停止するコマンドの実行のみ禁止する。それ以外は許可。
% sudo visudo |
sudoers に以下を追加する。
Cmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown, /sbin/poweroff, \
/sbin/reboot, /sbin/fastboot, /sbin/init |
Cmnd_AliasでSHUTDOWNを定義し、OSの起動・停止に関するコマンドを グループ化する。後はグループ化したSHUTDOWNをsudoで実行できないように設定するだけだ。その場合、SHUTDOWNの先頭に!を付加して“否定”にする必要がある。設定後、実際にSHUTDOWNで定義されたコマンドを実行しようとすると、以下のような拒否メッセージが表示され実行できなくなる。
% sudo reboot |
OS起動・停止コマンド以外にも、実運用に影響を与えてしまいそうなコマンドは、sudoで気軽に実行できないように制限することをお勧めする。特に簡単に止めることのできない基幹系のサーバならなおさらだ。
それらのコマンドを使う場合は、sudo -sやsudo suでシェル権限を得てから、ワンクッションおいてから慎重に実行するとよいだろう。
コラム sudoのパスワードキャッシュとパスワードプロンプト sudoでは一度入力されたパスワードをターミナルごとにキャッシュする。デフォルトでは5分間有効となり、キャッシュタイムアウトはsudoを実行するたびに更新される。 この機能は非常に便利だが、パスワードの入力なしに連続してsudoを実行できるため、root権限でコマンドを実行する際に重要となる“慎重さ”を欠いてしまう。そのため、特に重要なサーバの場合はキャッシュを利用せず、sudo実行時に毎回パスワードを聞くような設定(timestamp_timeout = 0)をsudoersに記述しておくとよいだろう。
また、“慎重さ”をさらに持たせたいのであれば、sudoのパスワードプロンプトも変更することをお勧めする。sudoを実行した際のパスワードプロンプトは、
のようなシンプルなものだが、これにsudoを実行したユーザー名(%u)やホスト名(%h)などを明示することで、sudoコマンド実行者に、どのサーバ上でどのユーザーから実行しようとしているのかを再認識させることができる。 sudoのパスワードプロンプトを変更する場合は、sudoresに例えば以下のように記述する。
設定を保存すると、「kimu@atmarkit Password:」のようなパスワードプロンプトに変更される。 なお、このほかDefaultsで設定変更可能な内容は、sudo -Lかman sudoersで確認するとよいだろう。 |
「第4回」へ |
index | |
第1回 不要なサービスの停止こそ管理の第一歩 | |
第2回 ソフトウェアの現状確認とアップグレード | |
第3回 サービスをセキュアにするための利用制限 | |
第4回 スーパーユーザーの特権を制限する | |
第5回 管理者権限を制限するためのsuとsudoの基本 | |
第6回 特権ユーザーの安全性向上を行うsudoの設定例 | |
第7回 UNIXサーバの運用管理で欠かせないログ管理 |
関連記事 | |
連載:Webアプリケーションに潜むセキュリティホール | |
特集:クロスサイトスクリプティング対策の基本 | |
連載:インシデントレスポンスはじめの一歩〜rootkitを検出するために |
Security&Trust記事一覧 |
ホワイトペーパー(TechTargetジャパン)
- ともだち373人できるかな――IMセキュリティ定点観測 (2010/6/22)
「ところで、IMのセキュリティってどうなんですか」の問いに体当たりで調査! 川口はメッセンジャーをこう使う……? - ウイルスはなぜウイルスなのか (2010/6/14)
安全なプログラムとコンピュータウイルスとの違いは何か? スタティック分析エンジンは、そのリサーチから始まった - ポストGumblar時代のエンドポイント保護は? (2010/5/27)
Gumblarの登場で単純な対策が意味をなさなくなったいま、エンドポイントを保護する手段とは何か? 各社のアプローチを紹介 - 求む、納得できる仮想プライベートサーバ (2010/5/24)
クラウド/仮想化技術のセキュリティをどう考える? 利用者の立場で、データセンターの必要条件を掘り下げます
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
- - PR -