ユーザに特権を与える方法

はじめに

今回は Solaris 10 の最小特権の仕組みを使用して、ユーザに特権を与える方法をご紹介します。

最小特権は、今まで root ユーザに集中していた権限を、必要に応じて一般ユーザに分け与える機能です。非 root ユーザが実行するプログラムでメモリをロックしたい場合や、開発者用アカウントで DTrace を実行させたい場合等、権限を委譲する際に必要となります。

特権を付与する手順

それでは早速、ユーザに特権を付与する手順を確認して行きましょう。

特権を付与する対象のユーザ

今回特権を付与するユーザはこのように作成した一般ユーザです。

 # mkdir /export/home/    
 # useradd -d /export/home/daleka -m -s /bin/zsh daleka
 # passwd daleka

現在の特権の確認

まずはユーザが現在保持している特権を確認します。使用するコマンドは ppriv <Login Shell PID> です。

 # su - daleka
 % ppriv $$
 1164:   -zsh
 flags = <none>
         E: basic
         I: basic
         P: basic
         L: all

E の欄に表示されているのが現在有効になっている特権です。ここでは basic 特権が設定されています。basic 特権は、幾つかある一般ユーザの基本的な権限をひとまとめにした特権です。

続いて、basic 特権の中にどんな特権が含まれているかを調べてみます。basic 特権の内容は ppriv -l basic コマンドで確認することができます。

 % ppriv -l basic
 file_link_any
 proc_exec
 proc_fork
 proc_info
 proc_session
 net_access

basic 特権の中には全部で 6 つの特権が含まれていることが分かりました。

それぞれの特権の詳細は ppriv -lv <特権> コマンドで調べることができます。

 ppriv -lv proc_fork
 proc_fork
         Allows a process to call fork1()/forkall()/vfork()

proc_fork はプロセスをフォークさせる特権である事が分かります。

ユーザに付与可能な特権の一覧は ppriv -l all で表示することができます。

 % ppriv -l all
 contract_event
 contract_observer
 cpc_cpu
 dtrace_kernel
 dtrace_proc
 dtrace_user
 file_chown
 file_chown_self
 file_dac_execute
 file_dac_read
 ...(略)
 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
 ... (以下略)

この様に、沢山の特権が定義されていることが分かります。proc_priocntl は Solaris Container 内で Oracle ASM を動かす際に必要になる特権です。

特権の付与

続いて、実際に特権を付与する方法をご紹介します。

使用するコマンドは usermod です。ここでは、メモリをロックする際に必要になる proc_lock_memory 特権を付与してみます。

 # usermod -K defaultpriv=basic,proc_lock_memory daleka

このように、元々付与されていた basic 特権の後に、カンマ区切り、空白無しで、新たな特権名を指定して defaultpriv パラメータを設定すると、特権を追加することができます。

特権を追加すると /etc/user_attr に変更が反映されます。

 # grep daleka /etc/user_attr                           
 daleka::::type=normal;defaultpriv=basic,proc_lock_memory

特権が付与された事は ppriv コマンドでも確認できます。

 # su - daleka
 % ppriv $$
 1301:   -zsh
 flags = <none>
         E: basic,proc_lock_memory
         I: basic,proc_lock_memory
         P: basic,proc_lock_memory
         L: all

以上で特権付与の手順は完了です。

実験

テストプログラムを使用して、特権が正しく有効になっているかを確認してみます。

使用するテストプログラムは mlock というコマンドラインプログラムで、この文書の下の方にソースコードを掲載してあります。特権が有効になっているかの確認には ppriv -De コマンドを使用します。

mlock プログラムは mlock() 関数を使用してメモリをロックするプログラムです。メモリをロックするには proc_lock_memory 特権が必要になりますが、まずは試しに proc_lock_memory 特権が付いていない状態で実行してみます。

 % ppriv -De ./mlock
 mlock[1726]: missing privilege "proc_lock_memory" (euid = 100, syscall = 131)
 needed at memcntl+0x14b

proc_lock_memory 特権が不足しているというメッセージが表示されました。必要な特権が欠けているため、メモリのロックは失敗してしまいました。なお、メッセージの最後に出力されている memcntl は mlock() 関数の内部で呼び出されるシステムコールです。

つづいて、proc_lock_memory 特権を付与してから実行してみます。

 # usermod -K defaultpriv=basic,proc_lock_memory daleka
 # su - daleka
 % ppriv -De ./mlock

今度は必要な特権を全て持っているため、メッセージは何も表示されません。メモリのロックは成功しました。

実験 その 2

もう一つの確認方法として truss コマンドを使用する方法もご紹介します。

まずは proc_lock_memory 特権が付いていない状態で実行してみます。

 % truss -tmemcntl ./mlock
 ...
 memcntl(0x08062000, 10, MC_LOCK, 0, 0, 0)       Err#1 EPERM [proc_lock_memory]

proc_lock_memory 特権が無いので、memcntl システムコールが EPERM エラーになりました。truss コマンドの出力を見ると、proc_lock_memory 特権が付いていないことによるエラーだと分かります。

つづいて、proc_lock_memory 特権を持っている状態で実行してみます。

 # usermod -K defaultpriv=basic,proc_lock_memory daleka
 # su - daleka
 % truss -tmemcntl ./mlock
 ...
 memcntl(0x08062000, 10, MC_LOCK, 0, 0, 0)       = 0

memcntl システムコールが 0 を返してきたので、今度はきちんとロックできました。

以上、特権の設定がきちんと効果を発揮していることを確認できました。

テストプログラム

こちらが実験で使用した mlock プログラムのソースコードです。

 # cat mlock.c
 /* compile: gcc mlock.c -o mlock */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/mman.h>
 
 #define MEMSIZE 10
 #define ALI 8192
 
 int main() {
 
   int size = MEMSIZE;
   int align = ALI;
   caddr_t addr;
 
   addr = memalign(align, size);
   bzero(addr, size);
   mlock(addr, size);
 
   getchar();
   munlock(addr, size);
 
 }
 # gcc mlock.c -o mlock

付与した特権を取り除く

付与した特権を元に戻すには、元から付与されていた特権のみを指定して usermod コマンドを実行します。

 # usermod -K defaultpriv=basic daleka                 
 # su - daleka

元の通り、basic 特権のみ付与されている事が分かります。

 % ppriv $$
 1479:   -zsh
 flags = <none>
         E: basic
         I: basic
         P: basic
         L: all

ただし /etc/user_attr のエントリーは消えません。

 % grep daleka /etc/user_attr 
 daleka::::type=normal;defaultpriv=basic

どんな特権があるか調べたい場合は

ppriv -lv all で全ての特権とその説明を表示させることができます。

 % ppriv -lv all
 contract_event
         Allows a process to request critical events without limitation.
         Allows a process to request reliable delivery of all events on
         any event queue.
 contract_observer
         Allows a process to observe contract events generated by
         contracts created and owned by users other than the process's
         effective user ID.
         Allows a process to open contract event endpoints belonging to
         contracts created and owned by users other than the process's
         effective user ID.
 cpc_cpu
         Allow a process to access per-CPU hardware performance counters.
 dtrace_kernel
         Allows DTrace kernel-level tracing.
 dtrace_proc
         Allows DTrace process-level tracing.
         Allows process-level tracing probes to be placed and enabled in
         processes to which the user has permissions.
 ... (以下略)

おわりに

以上、Solaris の最小特権機能をご紹介しました。この機能を利用して必要な権限だけを委譲する事で、システム全体のセキュリティを保つことができます。更に詳しく調べたい方は マニュアル をご覧下さい。

参考資料

投稿されたコメント:

コメント
コメントは無効になっています。
About

Search

Archives
« 4月 2014
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今日