What You See Is What You Get Element

ラボ:Oracle Solaris 11のセキュリティ機能によるアプリケーションの保護

OTNのシステム管理者/開発者コミュニティのハンズオン・ラボ
 

feedback_button

このラボでは、アプリケーションとシステムの保護に役立つOracle Solarisのいくつかのセキュリティ機能について簡単に学習します。具体的には、以下のテクノロジーについて説明します。

  • 特権
  • RBAC(権限と認証)
  • サービス管理機能(SMF)との統合

前提条件

必要なソフトウェア

ラボの演習3および4には、Apache 2.2が必要です。

Apache 2.2をSolaris 11にインストールするには、以下の手順を実行します。

  • デスクトップ上の「Add More Software」アイコンをクリックします。

Add More Softwareアイコン

  • プロンプトが表示されたら、rootパスワード(アプライアンスのインストール時に初めてOracle Solaris 11を起動したときに設定したもの)を入力します。

Password Required画面

  • apache-22を検索します。
  • web/server/apache-22」を選択します。

Package Manager

  • Install/Update」をクリックして、Apache Webサーバーをインストールします。

ラボの演習

  1. SolarisのRBACと特権の概要
  2. Solarisの特権の詳細
  3. プロセスの特権と権限
  4. SMF、プロセス特権、および認証

演習1:SolarisのRBACと特権の概要

予想される所要時間:20分間

この演習の目標は、SolarisにおけるRBAC/特権のフレームワークを基本的に理解することです。

予備知識

以下の概要説明について、Joerg MoellenkampLess known Solaris features: RBAC and Privileges - Part 1: Introductionに関する彼の寄稿に感謝の意を表明します。

rootについて

rootは以前から存在していました。そして、rootには制限がありませんでした。これは、望ましい状態ではありませんでした。rootは、それ自体が制御の対象となることなく、すべてのものを制御できました。しかし、rootを制御する必要がありました。一般ユーザーとrootを区別するものは、短い文字列だけでした。この特別な文字列を知っていれば、誰でもrootとしてコマンドを実行できました。

ただし、rootは、単独の存在ではありませんでした。rootには、デーモンという複数の従属プログラムがありました。それらのプログラムのいくつかは、日常のジョブを実行するために一般ユーザーが持たない特別な権限を必要としました。しかし、rootは、不可分の存在でした。そのため、従属プログラムは、rootの権限によって動作する必要がありました。とはいえ、従属プログラムは、rootとは異なり完全ではありませんでした。一部の従属プログラムは、一般ユーザーが一定量を超えるコマンドを同時に命令するだけで、一般ユーザーによって命令される動作を何でも実行するようになりました。

スーパーユーザー

UNIXシステムにおける従来の権限は、二面性があります。スーパーユーザーと一般ユーザーです。一般ユーザーはシステムにおいて制限のある一連の権限を持ち、スーパーユーザーは制限のない一連の権限を持ちます。一般ユーザーがシステムを変更するには、直接rootとしてログインするか、rootの権限を取得(su -コマンドを使用)する必要があります。ただし、そのようなユーザーは、システムに無制限にアクセスできます。多くの場合、これは望ましくありません。たとえば、オペレータがシステムで実行しなければならない作業が、ユーザー作成だけである場合、オペレータにシステム変更権限を与える必要があるでしょうか。useraddpasswdを実行できるようにオペレータをトレーニングしたとします。このオペレータが他のコマンドにも興味を持った場合には、どうすればいいでしょうか。ユーザー作成やパスワード変更にはroot権限が必要です。このオペレータの操作を制限するには、いくつかの手順が必要です。

しかし、問題はこれにとどまりません。プログラムが機能するには、システムを変更する必要があります。その典型的な例が、Webサーバーです。Webサーバーでポート80を使用したいとします。1024より少ない番号のポートは、特権ポートです。ポート80をリスニングするには、システムの構造を変更できる特別な権限が必要です。一般ユーザーには、これらの権限はありません。このため、Webサーバーをrootとして起動する必要があります。このプロセスの子プロセスは、一般ユーザーで実行することにより、rootの権限を失います。しかし、プログラムのこのシングル・インスタンスは、そのユーザーのすべての権限を持ちます。このプロセスは必要以上の権限を持つため、悪意のあるユーザーによる攻撃の手段となる可能性があります。

最小特権

セキュリティには最小特権という概念があります。ユーザーが割り当てられたタスクを実行するために必要なだけの最小限の特権のみを、そのユーザーに与えることです。現実世界に例えると、学校のすべての部屋に入れるマスター・キーを、C棟の作業しか行わない用務員に渡すことはしません。逆に、緊急事態に備えて、信頼できる一部の職員には、すべての部屋に入れる権限を与えます。

コンピュータのセキュリティにも同じ考え方があります。すべてのユーザーは、そのユーザーのジョブの実行できる、システムにおける最小限の特権のみを持つ必要があります。スーパーユーザーの概念は、すべてかゼロかというモデルであるため、これには適していません。スーパーユーザーの概念では、基本的な特権を持つ一般ユーザーと無制限の権限を持つユーザーが存在し、その中間はありません。これは、最小特権モデルと合致しません。

ロールベース・アクセス制御(RBAC)

用務員の鍵は、良い例です。大きな学校を想像してください。配管担当(名前はLennyとCarl)、校庭担当(名前はHomer)、およびセキュリティ・システム担当(名前はMarge、Lennyもときどき手伝います)の各用務員がいるとします。

それぞれ、役割に応じて異なる一連の特権を持ちます。たとえば、配管担当の用務員は、暖房装置のあるすべての部屋に入れます。校庭担当の用務員は、芝刈り機のある車庫にしか入れません。

用務員は、その用務員の仕事を開始するときに、その役割を取得します。特権の観点からは、用務員が誰であるかは重要ではなく、用務員がどの役割を取得しているかが重要です。Lennyは、タイム・カードを押して、それ以降の8時間に及ぶ配管担当の用務員の役割を取得します。そして、Lennyは、その仕事を行っている間、その役割固有の特権を使用します。ただし、Lennyには、事務室や作業場で行う作業もあります。これらは、Lenny用の部屋なので、特別な特権を必要としません。

ロール・ベースのアクセス制御も、この例とよく似ています。ユーザーは、システムにログインして、作業を開始します。このユーザーは、たとえば、自分宛の電子メールを読み(特権は不要)、そのメールの内容が"上司からのユーザー(xy45345)の作成指示 "であることを確認します。ここで、特権が必要になります。このユーザーは、ユーザー管理者のロール(役割)を取得し、ユーザーを作成します。ジョブが完了したら、特権は不要になります。ロールを解除し、一般ユーザーの権限で、上司宛の"作業完了通知"メールを作成します。

つまり、ロール・ベースのアクセス制御とは、ロールを定義し、それらに特権を与えて、ユーザーをこのロールに割り当てることです。

特権

この言葉は、この概要説明で、これまで何度も使用しました。では、特権とは何でしょうか。特権とは、何かを行うための権限です。たとえば、配管担当の用務員が、暖房装置の制御パネルの鍵を持つことです。

UNIXユーザーの場合も同じです。UNIXシステムでは、すべてのユーザーに特権があります。一般ユーザーは、許可される場合に、ファイルを開いたり、閉じたり、読み取ったり、書き込んだり、削除したりする特権を持ちます。許可される場合というのは、ユーザーがファイルを自分で作成した場合、ユーザーがファイルの作成者と同じグループに属している場合、ファイルの作成者がすべてのユーザーにそれらを実行する権限を与えている場合などです。これは当たり前のことのように思えるかもしれませんが、ユーザーがシステムに提示したログイン資格証明に基づく特権です。この一般ユーザーは、システム上のすべてのファイルを読み取ったり、ポート番号1024を使用したりする特権を持ちません。

システム上で行われるすべてのことは、これらの特権に基づいています。Solarisでは、タスクが、多数の特権セットに分割されています。現時点で、70の異なる特権がシステムに存在します。一般ユーザーとの相違は、一般ユーザーが基本特権セットしか持たない点です(一方、rootはすべての特権を持ちます)。

Solarisではモデルが変更されており、特権とユーザーは相互に結び付いていません。どのユーザーにも従来のrootユーザーの権限を与えることができ、rootユーザーの特権を制限することもできます。システムの標準構成がスーパーユーザー・モデルと類似していることを要求するOracleのバイナリ互換性保証により、Solarisは、従来のスーパーユーザー・モデルのように見える構成になっています。アプリケーションによっては、rootユーザーまたはUID 0にのみ無制限の権限があることを前提としており、これ以外のユーザーで起動すると終了する場合があります。

Solarisでは、UID 0がシステム構成ファイルの所有者であり、そのために、システム構成を変更できる点が唯一特別な点です。

SolarisにおけるRBACと特権

どちらの機能も、Trusted Solaris製品から生まれました。Trusted Solarisは、最高水準のセキュリティを保証するSolarisのバージョンでした。現在では、これらのメカニズムが、Trusted Extensionsとの組み合わせにより、通常のSolarisに含まれています。つまり、RBACは、実際には古い機能であり、Solaris 8(2000年に発表)以降のSolarisに組み込まれています。特権は、Solaris 10の最初のリリース(2005年2月)でSolaris全般に組み込まれました。

RBACの基本概念

  • 権限:特権を与えられたユーザーとして実行可能なコマンドを実行するための権利です。たとえば、rootとしてrebootコマンドを実行する権利などです。
  • 認証:セキュリティに影響する可能性のある一連の操作をユーザーまたはロールが実行することを可能にする権利です。たとえば、インストール時のセキュリティ・ポリシーによって、一般ユーザーにsolaris.device.cdrwという認証が与えられます。この認証により、ユーザーは、CD-ROMデバイスの読取り/書込みを実行できます。
  • 権限プロファイル:ユーザーまたはロールに割り当てることのできる管理機能の集合です。権限プロファイルは、認証、セキュリティ属性を持つコマンド、およびその他の権限プロファイルで構成できます。権限プロファイルにより、セキュリティ属性のグループ化が容易になります。
  • ロール:特権を与えられたアプリケーションを実行するための特別なIDです。この特別なIDは、割り当てられたユーザーだけが取得できます。ロールによって実行されているシステムでは、スーパーユーザーは不要です。スーパーユーザーの機能は、さまざまなロールに分散されます。

RBACとロールの詳細

デスクトップで、背景の任意の場所を右クリックし、ポップアップ・メニューから「Open Terminal」を選択してターミナル・ウィンドウを開きます。

Solaris 11メニュー

Oracleユーザーに割り当てられているロールを調べましょう。ターミナル・ウィンドウで、以下のコマンドを実行します。

oracle@solaris:~$ roles
root

ご覧のように、ロールrootがユーザーに割り当てられているので、rootロールを取得できます。Solaris 11では、rootはユーザーではなくロールです。このため、一般ユーザーとしてシステムにログインしてから、suコマンドを使用してrootロールを取得する必要があります。

ターミナル・ウィンドウで、以下のように入力します。

oracle@solaris:~$ userattr type root
role

oracle@solaris:~$ auths root
solaris.*

ご覧のように、rootは、 すべてのsolaris 認証によってロールとして定義されています。この効果は、従来のrootユーザーと似ています。これは、下位互換性のための措置です。

また、ユーザーにrootロールが割り当てられているため、rootロールを取得することにより、以下の処理を試みることができます。

oracle@solaris:~$ whoami
oracle
oracle@solaris:~$ su
Password: <root password>
oracle@solaris:~# whoami
root
oracle@solaris:~# who am I
oracle   pts/1        Apr 21 07:32	(:0.0)
oracle@solaris:~# exit
exit
oracle@solaris:~$

Joe Doeという新しいユーザーをシステムに追加しましょう。

oracle@solaris:~$ useradd -d /export/home/jdoe -m -s /bin/ksh -c "Joe Doe" jdoe
UX: useradd: ERROR: Permission denied.

ご覧のように、useraddコマンドの使用が許可されません。"root"特権でuseraddを実行するには、suを使用して、足りない権限をアカウントに割り当てる必要があります。suコマンドを実行すると、rootパスワードの入力を求められます。

oracle@solaris:~$ su root -c "usermod -K profiles='User Management' oracle"
Password: <your root password>

oracle@solaris:~$ userattr profiles oracle
User Management

このように、ユーザー管理権限が得られました。この権限を利用するには、プロファイル・シェル(pfbashなど)を起動して、新しいユーザー(jdoe)を作成します。

oracle@solaris:~$ pfbash
oracle@solaris:~$ useradd -d /export/home/jdoe -g oinstall -m -s /bin/ksh -c "Joe Doe" jdoe

ユーザーのパスワードを変更するには、User Securityプロファイルが割り当てられている必要がありますが、このプロファイルを通常のユーザーに割り当てることは推奨されません。これは、そのユーザーが、より権限のあるユーザーを含む他のユーザーのパスワードを変更できるようになるためです。User Managementプロファイルは、すでに持っているものを委任することしかできないため安全です。それでは、rootロールを使用して新しいユーザーのパスワードを変更しましょう。

oracle@solaris:~$ su root -c passwd jdoe
Password: <root password>

New Password: abc123
Re-enter new Password: abc123
passwd: password successfully changed for jdoe
oracle@solaris:~$ su - jdoe
Password: abc123
Oracle Corporation    SunOS 5.11    11.0    November 2011
jdoe@solaris:/export/home/jdoe$ roles
No roles
jdoe@solaris:/export/home/jdoe$ su root
Password: <root password>
Roles can only be assumed by authorized users
su: Sorry
jdoe@solaris:/export/home/jdoe$ exit
oracle@solaris:~$

注:-g oinstallオプションがuseraddコマンドに使用されています。これを加える必要があるのは、oracleユーザーが、このラボのセットアップでは、デフォルトでoinstallグループに含まれているためです。Oracle Solaris 11におけるデフォルト・グループは、staffです。このため、-g oinstallによってユーザーをoinstallグループに追加することを明示的に要求しないでuseraddを実行すると、新しいユーザーをstaffグループへ追加しようとします。この操作は、oracleユーザーでは許可されません。これは、"User Management"プロファイルを持つユーザーが、そのユーザーのすでに属しているグループにしか新しいユーザーを追加できないためです。

Solaris 11のロール認証の新機能

Solaris 11では、ロール認証の手順が変更されました。古いバージョンのSolaris(Oracle Solaris 11 Expressを含む)を実行している場合は、ロールを取得するためにロール・パスワードを知っている必要があります。Oracle Solaris 11では、ユーザーが特定のロールを取得する場合にロール・パスワードまたはユーザー・パスワードのどちらを使用するかを指定することができます。   管理者は、'roleauth'キーワードについて'user'または'role'を指定できます。roleauthを指定しない場合は、'role'が指定されます。デフォルトでは、新しく作成されるすべてのロールが'user'になります。

まとめ

ご覧のように、jdoeにはロールが割り当てられておらず、このユーザーはsuを使用してrootロールを取得することができません。このユーザーについては、後で説明します。では、演習2で、特権の詳細について学習しましょう。


演習2:Solarisの特権の詳細

予想される所要時間:20分間

はじめに

この演習の目的は、Solarisの特権とそれらの使用方法を理解することです。

予備知識

特権

特権とは、カーネルで操作を実行するための権限です。これらの権限は、カーネルによって設定されます。カーネル内で何かを行う場合は、常に、アクセスが特権によって制御されます。

特権リスト

contract_event、contract_identity、contract_observer、cpc_cpu、dtrace_kernel、dtrace_proc、dtrace_user、file_chown、file_chown_self、file_dac_execute、file_dac_read、file_dac_search、file_dac_write、file_downgrade_sl、file_flag_set、file_link_any、file_owner、file_setid、file_upgrade_sl、graphics_access、graphics_map、ipc_dac_read、ipc_dac_write、ipc_owner、net_access、net_bindmlp、net_icmpaccess、net_mac_aware、net_mac_implicit、net_observability、net_privaddr、net_rawaccess、proc_audit、proc_chroot、proc_clock_highres、proc_execproc_forkproc_info、proc_lock_memory、proc_owner、proc_priocntl、proc_session、proc_setid、proc_taskid、proc_zone、sys_acct、sys_admin、sys_audit、sys_config、sys_devices、sys_ipc_config、sys_linkdir、sys_mount、sys_iptun_config、sys_dl_config、sys_ip_config、sys_net_config、sys_nfs、sys_ppp_config、sys_res_config、sys_resource、sys_smb、sys_suser_compat、sys_time、sys_trans_label、virt_manage、win_colormap、win_config、win_dac_read、win_dac_write、win_devices、win_dga、win_downgrade_sl、win_fontpath、win_mac_read、win_mac_write、win_selection、win_upgrade_sl、xvm_control

凡例:青色 - 基本特権

従来のUNIXの場合

従来のUNIXシステムにはrootユーザーがあり、このユーザーがすべての特権を持っています。そして、制限された特権セットを持つ一般ユーザーがあります。一部のタスクは、場合により、実行するために管理者特権が必要です。ただし、システムを管理する必要まではありません。

oracle@solaris:~$ ls -l /usr/sbin/traceroute
-r-sr-xr-x 1 root bin 46868 2010-11-05 08:02 /usr/sbin/traceroute
oracle@solaris:~$ ls -l /usr/sbin/ping
-r-sr-xr-x 1 root bin 55940 2010-11-05 08:01 /usr/sbin/ping

traceroutepingは、どちらもsetuidツールであるため、使用できます。setuidにより、特定のユーザーIDとそのユーザーが持つすべてによってプロセスを実行できるようになります。rootに対するsetuidの場合、そのプロセスはrootの特権を持ちます。Solarisのsetuidプログラムは、特権を認識し、その操作に必要な特権だけを保持することができます。

pingには特殊な特権(ICMPへのアクセスを使用する特権)が必要です。従来のシステムでは、この権限は、rootユーザーのために予約されています。このため、pingプログラムは、rootの権限で実行する必要があります。問題は、このプログラムの実行時に、プログラムがユーザーのすべての権限を持つことです。このプログラムは、ICMPへのアクセスだけでなく、/etcにあるファイルの削除といった、システムでのすべての操作を実行できます。これは、pingまたはtracerouteでは問題にならないかもしれませんが、より大きなプログラムのことを考える必要があります。setuidプログラムを悪用することで、ユーザーの特権をエスカレーションすることができます。

一般ユーザーの特権について考えてみましょう。pprivという、システム内の任意のプロセスの特権を取得するツールがあります。$$は、実際のプロセスID(次の場合はシェルのプロセスID)のショートカットです。

oracle@solaris:~$ ppriv $$
1684:    -bash
flags = <none>
    E: basic
    I: basic
    P: basic
    L: all

"basic"が示す内容を確認するために、-vpprivフラグに追加してエイリアスを展開できます。

oracle@solaris:~$ ppriv -v $$
1684:    -bash
flags = <none>
    E: file_link_any,file_read,file_write,net_access,proc_exec,proc_fork,proc_info,proc_session
    I: file_link_any,file_read,file_write,net_access,proc_exec,proc_fork,proc_info,proc_session
    P: file_link_any,file_read,file_write,net_access,proc_exec,proc_fork,proc_info,proc_session
    L: contract_event,contract_identity,contract_observer,cpc_cpu,dtrace_kernel,dtrace_proc,dtrace_user,file_chown,file_chown_self,file_dac_execute,file_dac_read,file_dac_search,file_dac_write,file_downgrade_sl,file_flag_set,file_link_any,file_owner,file_read,file_setid,file_upgrade_sl,file_write,graphics_access,graphics_map,ipc_dac_read,ipc_dac_write,ipc_owner,net_access,net_bindmlp,net_icmpaccess,net_mac_aware,net_mac_implicit,net_observability,net_privaddr,net_rawaccess,proc_audit,proc_chroot,proc_clock_highres,proc_exec,proc_fork,proc_info,proc_lock_memory,proc_owner,proc_priocntl,proc_session,proc_setid,proc_taskid,proc_zone,sys_acct,sys_admin,sys_audit,sys_config,sys_devices,sys_dl_config,sys_ip_config,sys_ipc_config,sys_iptun_config,sys_linkdir,sys_mount,sys_net_config,sys_nfs,sys_ppp_config,sys_res_bind,sys_res_config,sys_resource,sys_smb,sys_suser_compat,sys_time,sys_trans_label,virt_manage,win_colormap,win_config,win_dac_read,win_dac_write,win_devices,win_dga,win_downgrade_sl,win_fontpath,win_mac_read,win_mac_write,win_selection,win_upgrade_sl,xvm_control

システム内の各プロセスは、プロセスが特権を使用できるかどうかを決定する4つの特権セットを持ちます。特権の理論は、非常に複雑です。各特権セットが他の特権セットを制御する方法または制御される方法を学習する場合は、Oracle Solaris 11セキュリティーサービス開発ガイドの"特権の実装方法"を参照することを推奨します。

ここでは、最初の文字の意味だけを説明します。

  • E:実効(Effective)特権セット
  • I:継承可能な(Inheritable)特権セット
  • P:許可された(Permitted)特権セット
  • L:制限(Limit)特権セット

特権セットは、鍵束と考えることができます。実効特権セットは、用務員が鍵束として持っている鍵です。許可された特権セットは、用務員が鍵束に加えることができる鍵です。用務員は、一部の鍵を鍵束から取り除くことを判断できます。たとえば、今日は232号室の作業しかしないので、他の鍵はすべて必要ない、と考えるかもしれません。不要な鍵は事務室に置いていきます。この場合、鍵束を紛失しても、この1つの部屋の出入りに問題が生じるだけで、学校全体の問題とはなりません。

継承可能な特権セットは、実際には、鍵束ではありません。用務員が新しい助手について"優れた作業者だが、高価な道具のある部屋の鍵は渡せない"と考えている場合と似ています。制限特権セットは、用務員の上司が班長に対して"助手には、普通の部屋の鍵は渡してもいいが、オラクル製のこの点滅する箱が入っている部屋の鍵は渡してはいけない"という全般的な命令を出す場合と似ています。

現時点では、興味深い特権セットのほとんどがEつまり実効特権セットです。これは、プロセスで効果的に使用できる特権セットです。上記の特権の完全なリストと比べると、この特権セットは非常に少数です。しかし、これは、UNIXシステムを使用する場合の使用経験と一致します。

この点を、rootロールを取得する場合について見てみましょう。

oracle@solaris:~$ su -
Password: <root password>

Oracle Corporation    SunOS 5.11    11.0    November 2011
You have new mail.
root@solaris:~# ppriv $$
1779:    -bash
flags = <none>
    E: all
    I: basic
    P: all
    L: all

このロールは、非常に多くの特権を持っています。実効特権セットは、非常に広範囲です。rootロールを取得する場合は、システムのすべての特権を取得することになります。注:これは、完全に、下位互換性を保持するためのものであり、将来的には使用することが推奨されていません。

一部の特権をjdoeユーザーに追加しましょう。このユーザーはいくつかのアプリケーションをデバッグするためにDTraceにアクセスする必要のあるソフトウェア開発者であると仮定してください。

最初に、jdoeとしてDTraceを使用してみましょう。

# su - jdoe
Password: abc123
Oracle Corporation    SunOS 5.11    11.0    November 2011
jdoe@solaris:/export/home/jdoe$ ppriv $$
1790:    -ksh
flags = <none>

    E: basic
    I: basic
    P: basic
    L: all
jdoe@solaris:/export/home/jdoe$ dtrace -l
dtrace: failed to initialize dtrace: DTrace requires additional privileges

ご覧のように、jdoeには、DTraceの使用するために必要な特権がありません。DTraceを使用するためにユーザーが必要とするものに応じて、DTraceで必要な特権は3つあります(dtrace_kernel、dtrace_proc、dtrace_user)。これらの特権は、以下の3つの異なる方法でユーザーに追加できます。

  1. ユーザーに必要な特権を追加します。これにより、ユーザーは、そのユーザー自身としてDTraceを使用できるようになります。
  2. dtraceコマンドと必要な特権を使用して実行プロファイルを作成し、このプロファイルをユーザーに割り当てます。これにより、このユーザーは、プロファイル・シェル(pfbashなど)を使用してdtraceコマンドを実行できるようになります。
  3. 必要な特権を持つロールを作成し、このロールをユーザーに割り当てます。この場合、ユーザーは、DTraceを使用できるロールを取得する必要があります。

dtrace特権をユーザーに直接追加する方法を見てみましょう(最初のコマンドをrootとして実行してから、rootシェルを終了し、oracleユーザーとして作業を進めます)。

# usermod -K defaultpriv=basic,dtrace_kernel,dtrace_proc,dtrace_user jdoe
oracle@solaris:~$ userattr defaultpriv
basic,dtrace_kernel,dtrace_proc,dtrace_user

:ユーザーに割り当てる特権セットに基本特権を追加する際は、ファイルの作成や新しいプロセスの起動といった基本操作の大半をユーザーが実行できるように追加する必要があります。

ここで表示されるように、jdoeは、dtraceコマンドを使用するために必要な3つの特権を持ちました。では、コマンドを実行してみましょう。

oracle@solaris:~$ su - jdoe
Password: abc123
Oracle Corporation    SunOS 5.11    11.0    November 2011
jdoe@solaris:/export/home/jdoe$ ppriv $$
1814:    -ksh
flags = <none>
    E: basic,dtrace_kernel,dtrace_proc,dtrace_user
    I: basic,dtrace_kernel,dtrace_proc,dtrace_user
    P: basic,dtrace_kernel,dtrace_proc,dtrace_user
    L: all
jdoe@solaris:/export/home/jdoe$ dtrace -l | more

   ID   PROVIDER            MODULE                          FUNCTION NAME
    1     dtrace                                                     BEGIN
    2     dtrace                                                     END
    3     dtrace                                                     ERROR
  530        fbt            smbsrv                 smb_match_private entry
...
  555        fbt            smbsrv                  smb_gmttoken_xdr return
--More--

正常に実行できたので、試しに同じことを実行するロールも作成してみましょう。

最初に、jdoeからdtrace特権を削除しましょう。


oracle@solaris:~$ usermod -K defaultpriv=basic jdoe

oracle@solaris:~$ userattr defaultpriv jdoe
basic
 

次に、rootシェルを使用して(つまりrootユーザーとして)ロールを作成し、このロールに"bugger"という名前を付けてjdoeに割り当てます。

# roleadd -u 201 -d /export/home/bugger -P "Process Management" bugger

oracle@solaris:~$ passwd bugger
New Password: abc123
Re-enter new Password: abc123
passwd: password successfully changed for bugger

oracle@solaris:~$ rolemod -K defaultpriv=basic,dtrace_kernel,dtrace_proc,dtrace_user bugger
oracle@solaris:~$ userattr defaultpriv bugger
basic,dtrace_kernel,dtrace_proc,dtrace_user

oracle@solaris:~$ usermod -R bugger jdoe
oracle@solaris:~$ roles jdoe
bugger

 

正常に実行できました。では、jdoeがDTraceを使用できることを確認しましょう。

oracle@solaris:~$ su - jdoe
Password:
Oracle Corporation    SunOS 5.11    11.0    November 2011
jdoe@solaris:/export/home/jdoe$ roles
bugger
jdoe@solaris:/export/home/jdoe$ su bugger
Password:
jdoe@solaris:~$ ppriv $$
1885:    sh
flags = PRIV_PFEXEC
    E: basic,dtrace_kernel,dtrace_proc,dtrace_user
    I: basic,dtrace_kernel,dtrace_proc,dtrace_user
    P: basic,dtrace_kernel,dtrace_proc,dtrace_user
    L: all
jdoe@solaris:~$ dtrace -l | more
   ID   PROVIDER            MODULE                          FUNCTION NAME
    1     dtrace                                                     BEGIN
    2     dtrace                                                     END
    3     dtrace                                                     ERROR
  530        fbt            smbsrv                 smb_match_private entry
...
  555        fbt            smbsrv                  smb_gmttoken_xdr return
--More--

 

まとめ

以上で、特権とそれらをユーザーに割り当てる方法について基本的に理解できたはずです。ただし、同じことをプロセスに対しても実行できることが望ましいので、この点について演習3で学習しましょう。


演習3:プロセスの特権と権限

予想される所要時間:10分間

予備知識

特権をユーザーに追加する方法をすでに学習しました。ここでは、特権とプロセスの相互作用について学習します。特権を認識するプロセスと特権を認識しないプロセスの両方について説明します。

特権を管理するという発想は、ユーザーとそのシェルに限定されるものではありません。どのシステムでも、何十ものプログラムがデーモンとして動作しています。

これらのデーモンは、複数の方法で特権と相互に作用します。その最良の方法は、"特権を認識するプログラミング"です。使用しているシステム用のデーモンを作成すると仮定しましょう。たとえば、デーモンがexec()コールを決して実行しないことが分かっているとします。この場合は、この特権を問題なく削除できます。このプロセスは、許可された特権セットを変更します。このプロセスは、特権を削除できますが、追加できません。このため、もし誰かがプロセスにアクセスできたとしても、その攻撃者はexec()コールを実行できません。このプロセスには、そのようなコールを実行する特権もありません。また、攻撃者は、その特権を追加しなおすこともできません。Solaris内の複数のプロセスとプログラムは、すでに特権を認識します。その例としては、カーネル・レベル暗号化フレームワーク・デーモンなどがあります。デーモンの特権について見てみましょう。

特権を監視または管理するには、プロセス自体がすでにそれらの特権を持っている必要があります。このため、以降の演習のためにrootロールを取得します。

oracle@solaris:~$ su - root
Password: <root password>

oracle@solaris:~# ps -ef | grep "kcfd"
  daemon   129     1   0   Apr 04 ?           0:00 /lib/crypto/kcfd
  oracle  1902  1684   0 08:19:19 pts/1       0:00 grep kcfd
oracle@solaris:~# ppriv -v 129
129:    /lib/crypto/kcfd
flags = PRIV_AWARE
    E: file_owner,file_read,file_write,net_access,proc_priocntl,sys_devices
    I: none
    P: file_owner,file_read,file_write,net_access,proc_priocntl,sys_devices
    L: none

このデーモンは、一般ユーザーの基本特権も持っていません。このデーモンは、そのジョブを実行するための必要最小限の特権だけを持っています。

特権を認識しないプロセス

しかし、すべてのものが完全ではありません。特権を認識しないプロセスも存在します。したがって、別の方法によって特権を制限する必要があります。ここで、サービス管理機能が役立ちます。以下の例は、Glenn BrunetteのブループリントであるLimiting Service Privileges in the Solaris 10 Operating Systemからコピーしたものです。

Apache Webサーバーを例に取ってみましょう。Apache Webサーバーは、特権を認識しません。サービス管理フレームワーク(SMF)を使用してこのデーモンを起動します。

oracle@solaris:~# svcadm -v enable -s apache22
svc:/network/http:apache22 enabled.

正常に実行できたので、Apacheデーモンのプロセスを調べます。

oracle@solaris:~# ps -ef | grep "apache" | grep -v grep
webservd  1931  1928   0 08:22:59 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  1934  1928   0 08:22:59 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  1932  1928   0 08:22:59 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  1935  1928   0 08:22:59 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  1933  1928   0 08:22:59 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
    root  1928     1   1 08:22:58 ?           0:00 /usr/apache2/2.2/bin/httpd -k start

6つのデーモンがwebservdとして動作し、1つのデーモンがrootとして動作しています。

oracle@solaris:~# ppriv 1928
1928:	/usr/apache2/2.2/bin/httpd -k start
flags = <none>
	E: all
	I: basic
	P: all
	L: all

rootプロセスに関しては、予想されるとおり、rootユーザーの完全な特権セットを持っています。その子プロセスの一つについて調べてみましょう。

oracle@solaris:~# ppriv 1931
1931:    /usr/apache2/2.2/bin/httpd -k start
flags = <none>
    E: basic
    I: basic
    P: basic
    L: all

基本特権しか持っておらず、はるかに望ましい状態です。

さて、この構成には理由があります。UNIXシステムでは、ポートが2つのグループに分かれます。1~1023は特権を持つポートであり、1024以降は特権を持たないポートです。特権ポートへのバインドには、それを実行できる特権が必要です。一般ユーザーはこの特権を持っていませんが、rootは持っています。そして、このために、rootとして動作するプロセスが1つ必要になるのです。rootとして動作するApacheプロセスの権限リストを思い出してください。このプロセスはすべての特権を持っていますが、必要な特権はそれらのうちの1つだけです。ただし、その特権は、基本特権セットに含まれていません。


演習4:SMF、プロセス特権、および認証

予想される所要時間:10分間

はじめに

特権を認識するプロセスと特権を認識しないプロセスの両方についてすでに学習しました。ここでは、SMFを使用して、制限された特権セットを持つユーザーに特権を認識しないプロセスを管理させる方法と、rootに対するsetuidを使用せずにそのユーザーに必要な特権を与える方法を学習します。

特権を監視または管理するには、プロセス自体がすでにそれらの特権を持っている必要があります。このため、以降の演習のためにrootロールを取得します。

予備知識

rootのApacheプロセスを排除する方法

Apacheプロセスには、こうあるべきというものはありません。Solarisでは、任意のユーザーまたはプロセスに特権ポートを使用する特権を与えることができます。rootプロセスはもはや不要です。

そこで、この方法でApacheプロセスを構成してみます。まず、演習3から動作しているApacheを非アクティブ化する必要があります。

oracle@solaris:~$ su - root
Password: <root password>
oracle@solaris:~# svcadm -v disable -s apache22
svc:/network/http:apache22 disabled.

ここでは、サービス管理機能(SMF)について説明しませんが、SMFで特定のプロパティを設定することにより、サービスの起動を制御できます。

1  oracle@solaris:~# svccfg -s apache22
2  svc:/network/http:apache22> setprop start/user = astring: webservd
3  svc:/network/http:apache22> setprop start/group = astring: webservd
4  svc:/network/http:apache22> setprop start/privileges = astring:
5  basic,!proc_session,!proc_info,!file_link_any,net_privaddr
6  svc:/network/http:apache22> setprop start/limit_privileges = astring: :default
7  svc:/network/http:apache22> setprop start/use_profile = boolean: false
8  svc:/network/http:apache22> setprop start/supp_groups = astring: :default
9  svc:/network/http:apache22> setprop start/working_directory = astring: :default
10 svc:/network/http:apache22> setprop start/project = astring: :default
11 svc:/network/http:apache22> setprop start/resource_pool = astring: :default
12 svc:/network/http:apache22> end


もっとも興味深いのは、2~4行目です。何も変更していない状態で、Apacheデーモンはrootとして起動し、常にwebservdユーザーによってプロセスを分岐します。しかし、この構成のrootユーザーを排除する必要があります。そこで、webservdユーザーによってデーモンを直接起動し、同じことをグループIDについても実行します。

ここで、さらに興味深いことがあります。この行(4行目)がないと、カーネルは、Apacheのポート80へのバインドを拒否します。webservdは、特権ポートを使用する特権を持たない一般ユーザーです。start/privilegesプロパティにより、これらの特権がサービスを起動するように設定されます。まず、サービスに基本特権を与えます。次に、特権ポートを使用する特権を追加します。これで、サービスを起動します。

ただし、まだできることがあります。Webサーバーは、ハードリンクを実行するべきではありません。また、Webサーバーは、そのセッションの外部にシグナルを送信しません。さらに、Webサーバーは、シグナルを送信できるプロセス以外のプロセスのステータスを調べません。このため、これらの特権は不要です。proc_sessionproc_info、およびfile_link_anyは、基本特権セットに含まれています。特権の前に!を追加することにより、これらの特権を削除します。

oracle@solaris:~# svcadm -v refresh apache22
Password:
Action refresh set for svc:/network/http:apache22.

これで、SMFに構成の変更が通知されました。

これまで、Apacheデーモンは、root特権を使用していました。このため、ファイルおよびディレクトリの所有権に関しては、複雑ではありませんでした。デーモンは、システム内の任意のディレクトリまたはファイルの読取り/書込みを実行できました。一般ユーザーを使用してデーモンの特権セットを削除するため、一部のファイルの所有権を変更したり、一部のファイルを削除したりする必要があります。

oracle@solaris:~# mkdir -p -m 755 /var/apache2/2.2/run
oracle@solaris:~# chown webservd:webservd /var/apache2/2.2/run
oracle@solaris:~# chown webservd:webservd /var/apache2/2.2/logs/access_log
oracle@solaris:~# chown webservd:webservd /var/apache2/2.2/logs/error_log


注:
サービスはrootとして動作しなくなりますが、トレードオフが発生します。"root"構成では、ログは、rootによって所有されており、"webservd"による変更は不可能でした。新しいモデルでは、Webサーバーの特権が減っていますが、ログは、"webservd"によって所有され、書込み可能になっています。これは、良くも悪くもなく、単なるトレードオフです。

また、構成の一部を変更する必要もあります。LockFileとPidFileを移動しなければなりません。前に指定した2つの構成ディレクティブのうちの1つがなかったため、単にこれらを構成ファイルの最後に追加します。

oracle@solaris:~# bash -c 'echo LockFile /var/apache2/2.2/logs/accept.lock >> /etc/apache2/2.2/httpd.conf'
oracle@solaris:~# bash -c 'echo PidFile /var/apache2/2.2/run/httpd.pid >> /etc/apache2/2.2/httpd.conf'

これで、すべての準備が整いました。では、試してみましょう。

oracle@solaris:~# svcadm -v enable -s apache22
svc:/network/http:apache22 enabled.

ここで、動作しているhttpdプロセスを調べます。

oracle@solaris:~# ps -ef | grep "httpd" | grep -v "grep"

webservd  2064  2057   0 08:43:24 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  2061  2057   0 08:43:24 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  2062  2057   0 08:43:24 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  2060  2057   0 08:43:24 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  2063  2057   0 08:43:24 ?           0:00 /usr/apache2/2.2/bin/httpd -k start
webservd  2057     1   1 08:43:23 ?           0:00 /usr/apache2/2.2/bin/httpd -k start

違いが分かりますか。rootとして動作しているhttpdが存在しません。すべてのプロセスが、webservdのユーザーIDで動作しています。これで、目的は達成されました。

プロセスの特権を調べましょう。最初に、以前はrootとして動作していたものを調べます。

oracle@solaris:~# ppriv 2057
2057:    /usr/apache2/2.2/bin/httpd -k start
flags = <none>
    E: basic,!file_link_any,net_privaddr,!proc_info,!proc_session
    I: basic,!file_link_any,net_privaddr,!proc_info,!proc_session
    P: basic,!file_link_any,net_privaddr,!proc_info,!proc_session
    L: all

root特権ではなく、ジョブを実行するための最小特権のみが与えられています。さらに、他のプロセスに関するセキュリティも向上しています。Webサーバーの構成を変更する前は、Webサーバーが一般ユーザーの基本特権を持っていました。現在では、この特権セットも制限されています。

ただし、やはり、Apacheを起動するには、特権を持つユーザーである必要があります。特権を持たないユーザーに"サービス"の管理を委任できれば、状況がさらに改善されます。認証を使用することで、これを実現できます。また、認証は、SMFと統合されます。ユーザーにapach22サービスを管理する権限を与えるために、2つの認証をユーザーに追加する必要があります。サービスを管理するための認証と、サービスの状態を変更するための認証が必要です。

  • solaris.smf.value.http/apache22:Apacheサービスのプロパティの値を変更する権限をユーザーに与えます。
  • solaris.smf.manage.http/apache22svcadmによってApacheサービスの状態を変更する権限をユーザーに与えます。

サービスの状態はサービスのプロパティとして保持されるため、サービスの状態の変更には両方の認証が必要です。

oracle@solaris:~# svcprop http:apache22 | grep auth
httpd/value_authorization astring solaris.smf.value.http/apache22
general/action_authorization astring solaris.smf.manage.http/apache22
general/value_authorization astring solaris.smf.value.http/apache22

最初に、認証を/etc/security/auth_attrに追加する必要があります。


oracle@solaris:~# echo solaris.smf.manage.http:::Mange Apache 2.2:: >> /etc/security/auth_attr
Password: oracle
oracle@solaris:~# echo solaris.smf.value.http:::Mange Apache 2.2:: >> /etc/security/auth_attr

注:
ほとんどのSMFマニフェストでは、action_authorizationとvalue_authorizationの両方に1つの認証が使用されます。これは、それらが一般に、一緒に使用されるためです。

特権の操作が完了したため、ここで、rootロールを終了できます。前から使用しているjdoeユーザーに認証を追加しましょう。

oracle@solaris:~# exit
oracle@solaris:~$ usermod -A solaris.smf.manage.http/apache22,solaris.smf.value.http/apache22 jdoe

oracle@solaris:~$ userattr auths jdoe
solaris.smf.manage.http/apache22,solaris.smf.value.http/apache22

jdoeがApacheを起動および停止できることを確認しましょう。

oracle@solaris:~$ su - jdoe
Password: abc123
Oracle Corporation    SunOS 5.11    11.0    November 2011
jdoe@solaris:/export/home/jdoe$ /usr/sbin/svcadm enable apache22
jdoe@solaris:/export/home/jdoe$ svcs apache22
STATE          STIME    FMRI
online          8:43:23 svc:/network/http:apache22
jdoe@solaris:/export/home/jdoe$ /usr/sbin/svcadm disable apache22
jdoe@solaris:/export/home/jdoe$ svcs apache22
STATE          STIME    FMRI
disabled        8:53:37 svc:/network/http:apache22

正常に機能したこと、つまり、SMFを使用して、Apacheなどのサービスを操作できるようになり、必要最小限の特権がサービスに与えられてrootとして起動する必要がなくなっていることを確認します。また、Apacheには不要でありながら、ハッカーがシステムを制御するために必要とする、一部の特権も削除されました。

さらに、ここで表示されるように、特権を持たないユーザーに、特定のサービスのみの管理を許可する適切な認証を与えることにより、SMFによってApacheサービスを管理する権限をそれらのユーザーに追加しました。

jdoe@solaris:/export/home/jdoe$ svcs sendmail
STATE          STIME    FMRI
online          6:48:12 svc:/network/smtp:sendmail
jdoe@solaris:/export/home/jdoe$ svcadm disable sendmail
svcadm: svc:/network/smtp:sendmail: Permission denied.

これで、Oracle Solarisのセキュリティ機能によるアプリケーションの保護に関するハンズオン・ラボは無事に完了です。

このラボで使用したテクノロジーについて詳しくは、次のリンクにアクセスしてください。

http://www.oracle.com/technetwork/server-storage/solaris/overview/security-163473.html
http://www.oracle.com/us/products/servers-storage/solaris/security/index.html

Restricting Service Administration in the Solaris 10 OS
Limiting Service Privileges in the Solaris 10 OS
Privilege Debugging in the Solaris 10 Operating System
Privilege Bracketing in the Solaris 10 Operating System

ご参加くださり、ありがとうございました。

false