第3回 権限を最小化するLinuxカーネルケーパビリティ

面 和毅
サイオステクノロジー株式会社
インフラストラクチャービジネスユニット
Linuxテクノロジー部
OSSテクノロジーグループ
シニアマネージャ
2006/1/18

 ケーパビリティチェック

 例として、ntpdの場合を見てみましょう。ntpdはシステムの時刻を合わせる(adjust)際に、sys_adjtimexシステムコールを呼び出します。sys_adjtimexシステムコールは/usr/src/linux/kernel/time.cファイル内に以下のように定義されています。

linux/kernel/time.c)
  414 asmlinkage long sys_adjtimex(struct timex __user *txc_p)
  415 {
  416  struct timex txc;   /* Local copy of parameter */
  417  int ret;
  418
  419  /* Copy the user data space into the kernel copy
  420   * structure. But bear in mind that the structures
  421   * may change
  422   */
  423  if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
  424    return -EFAULT;
  425  ret = do_adjtimex(&txc);
  426   return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
  427 }

 425行目でdo_adjtimex()関数を呼び出していますが、この関数は同じファイル内で次のように定義されています。

linux/kernel/time.c)
  230 int do_adjtimex(struct timex *txc)
  231 {
  232  long ltemp, mtemp, save_adjust;
  233  int result;
  234
  235  /* In order to modify anything, you gotta be super-user! */
  236  if (txc->modes && !capable(CAP_SYS_TIME))
  237    return -EPERM;

 236行目で、capable()関数によるケーパビリティのチェックを行っており、CAP_SYS_TIMEのケーパビリティをntpdが持っていなければ、パーミッションチェックでエラーが返ることになります。

 このほか、プロセスがポート1023番以下で起動する際に参照するinet_bind()システムコール内でも以下のように433行目でCAP_NET_BIND_SERVICEのケーパビリティを持っているかどうかがチェックされ、持っていない場合にはパーミッションエラーが返るようになっています。

/usr/src/linux/net/ipv4/af_inet.c)
  395 int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
  396 {
  .
  .
  .
  433  if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
  434    goto out;

 LIDSによるケーパビリティの拡張

 LIDSではさらに、もともとLinuxが持っているケーパビリティに加えて、

CAP_PROTECTED:プロセスをkillシグナルから保護する
CAP_KILL_PROTECTED:CAP_PROTECTEDを与えられたプロセスをkillする
CAP_HIDDEN(LIDS-1系列のみ):プロセスを隠す

という特殊なケーパビリティを追加しています。

・CAP_PROTECTED

 CAP_PROTECTEDを与えられたプロセスは、killシグナルから保護されることになります。つまり、たとえ管理者であっても、このケーパビリティを与えられたプロセスを止められません。

 通常、システムに不正侵入して来たクラッカーや不正行為を行おうとする者は、システムの監査を行っているサービスを止めてから、ファイル改変などの不正行為を行います。泥棒が監視カメラに目隠しをしたり、見えない位置で悪さをしようとするのと同じことです。

 しかし、システムのログを取るsyslogdやネットワーク上のパケットの監視を行うsnort、あるいはシステム上のフォレンジック的な監査ログサービスをCAP_PROTECTEDを用いて保護すると、不正侵入して来た者はサービスを止めることができません。さらにその止めようとしている行為自体も次々とログに書かれていきます。システムを外部からの攻撃から守るだけではなく、システム管理者に対しても不正行為に対する抑止力として働きます。

・CAP_KILL_PROTECTED

 CAP_KILL_PROTECTEDは、CAP_PROTECTEDと対になっています。例えば監査サービスにCAP_PROTECTEDを与えて保護していたとしても、システムを停止する際には監査サービスを停止しなくてはなりません。CAP_KILL_PROTECTEDが与えられたプログラムのみがCAP_PROTECTEDで保護されているサービスをkillできます。

 CAP_KILL_PROTECTEDと次回で説明する「ステート」を組み合わせて使用することにより、システムを安全に停止できるようになります。

・CAP_HIDDEN(LIDS-1系列のみ)

 CAP_HIDDENをプロセスに与えると、そのプロセスは/procから完全に隠された状態になり、psコマンドなどでも存在を確認することができなくなります。

 CAP_HIDDENを監査サービスに与えることにより、外部および内部からは管理者であったとしても、そのシステムが監視を行っていることすら気付かないシステムを作ることができます。ATMなどの監視カメラが隠しカメラになっているようなものです。

 CAP_HIDDENはさまざまな応用が考えられる優れたケーパビリティですが、残念なことにLIDS-2系列からは消滅してしまいました。これはLSM(Linux Security Module)に対応した形になったためです。

2/4

Index
権限を最小化するLinuxカーネルケーパビリティ
  Page1
権限を切り分けるPOSIXケーパビリティ
Linuxカーネルケーパビリティ
Page2
ケーパビリティチェック
LIDSによるケーパビリティの拡張
ファイルに対するアクセス制御のフロー
  Page3
ケーパビリティの実態
  Page4
ケーパビリティの調整方法
LIDSを用いた場合のケーパビリティの調整方法


Security&Trust記事一覧


Security&Trust フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Security & Trust 記事ランキング

本日 月間