Skip to content
Published on

[オペレーティングシステム] 17. 保護:アクセス制御とサンドボックス

Authors

保護:アクセス制御とサンドボックス

保護(Protection)はオペレーティングシステムにおいて、プロセスとユーザーがリソースにアクセスすることを制御するメカニズムです。セキュリティが外部脅威からシステムを防御することであれば、保護は内部的にアクセス権限を管理することです。


1. 保護の目標

┌────────────────────────────────────────┐
│           保護の原則                    │
│                                        │
│  最小権限の原則                         │
  (Principle of Least Privilege)│                                        │
│  → プロセス/ユーザーに作業遂行に       │
│    必要な最小限の権限のみ付与          │
│                                        │
│  例:- Webサーバー: Webファイルの読みのみ- DBサーバー: データディレクトリのみ  │
- 一般ユーザー: カーネル領域アクセス不可│
│                                        │
│  権限分離(Need-to-Know):│  → 各モジュールが自分の役割に必要な    │
│    情報のみアクセス可能                │
└────────────────────────────────────────┘

2. 保護リング(Protection Rings)

ハードウェアレベルで権限レベルを階層化する構造です。

┌─────────────────────────────────────┐
│       保護リング(x86)              │
│                                     │
│    ┌─────────────────────────┐      │
│    │ Ring 3: ユーザーアプリ   │      │
│    │  ┌─────────────────┐    │      │
│    │  │ Ring 2: (未使用) │    │      │
│    │  │  ┌───────────┐  │    │      │
│    │  │  │ Ring 1:   │  │    │      │
│    │  │   (未使用)  │  │    │      │
│    │  │  │ ┌───────┐ │  │    │      │
│    │  │  │ │Ring 0:│ │  │    │      │
│    │  │  │ │カーネル│ │  │    │      │
│    │  │  │ └───────┘ │  │    │      │
│    │  │  └───────────┘  │    │      │
│    │  └─────────────────┘    │      │
│    └─────────────────────────┘      │
│                                     │
Ring 0: すべてのハードウェアアクセス可能│
Ring 3: 制限された命令のみ実行可能  │
│  システムコールでRing切り替え         │
└─────────────────────────────────────┘

現代システムの権限構造

┌───────────────────────────────────────┐
ハイパーバイザーモード (Ring -1)├───────────────────────────────────────┤
カーネルモード (Ring 0)- メモリ管理、プロセス管理            │
- デバイスドライバ、ファイルシステム  │
├───────────────────────────────────────┤
ユーザーモード (Ring 3)- アプリケーション、ライブラリ        │
- システムコールでカーネルサービス要求│
└───────────────────────────────────────┘

3. 保護ドメイン(Domain of Protection)

プロセスがアクセスできるリソースの集合を保護ドメインといいます。

ドメインD1(ユーザーA:
  file1.txt → read, write
  file2.txt → read
  printer  → print

ドメインD2(ユーザーB:
  file2.txt → read, write
  file3.txt → read, write, execute

ドメインD3(デーモンプロセス):
  file1.txt → read
  network  → send, receive

ドメイン切り替え

プロセスが一つのドメインから別のドメインに遷移することです。

// setuid 프로그램에 의한 도메인 전환 예시
// passwd 명령어: 일반 사용자 → root 권한으로 전환

// 실행 전: uid = 1000 (일반 사용자)
// /usr/bin/passwd 는 setuid root

// 실행 중: euid = 0 (root), ruid = 1000
// → /etc/shadow 파일 수정 가능

// 실행 후: uid = 1000 (원래 사용자로 복귀)

4. アクセス行列(Access Matrix)

リソースへのアクセス権限を体系的に表現するモデルです。

           │  file1   │  file2   │  file3   │ printer │ Domain 2───────────┼──────────┼──────────┼──────────┼─────────┼─────────┤
Domain 1   │ read     │ read     │          │ print   │ switch  
(ユーザーA)│ write    │          │          │         │         │
───────────┼──────────┼──────────┼──────────┼─────────┼─────────┤
Domain 2   │          │ read     │ read     │         │         
(ユーザーB)│          │ write    │ write    │         │         │
───────────┼──────────┼──────────┼──────────┼─────────┼─────────┤
Domain 3   │ read     │          │          │         │         
(デーモン) │          │          │ execute  │         │         │

アクセス行列の実装方法

1. アクセス制御リスト(ACL)- 列基準

file1のACL:
┌────────────┬──────────────┐
Domain 1   │ read, write  │
Domain 3   │ read         │
└────────────┴──────────────┘
// POSIX ACL 설정 예시 (Linux)
// 명령어로 ACL 설정
// setfacl -m u:user1:rw file1.txt
// setfacl -m g:developers:r file1.txt

// ACL 확인
// getfacl file1.txt
// # file: file1.txt
// # owner: root
// # group: root
// user::rw-
// user:user1:rw-
// group::r--
// group:developers:r--
// mask::rw-
// other::---

2. 能力リスト(Capability List)- 行基準

Domain 1の能力:
┌──────────┬──────────────┐
│ file1    │ read, write  │  ← 能力(capability)
│ file2    │ read         │     = オブジェクト + 権限
│ printer  │ print        │
└──────────┴──────────────┘

ACL vs Capability 比較

特性ACLCapability
観点オブジェクト(リソース)中心主体(プロセス)中心
権限確認ファイルアクセス時にACL検索プロセスの能力リスト確認
権限取消容易(ACLから削除)困難(分散した能力の追跡必要)
使用例UNIX権限、Windows NTFSMach、seL4マイクロカーネル

5. 役割ベースアクセス制御(RBAC)

ユーザーに直接権限を付与する代わりに、役割(Role)に権限を割り当て、ユーザーを役割に配属します。

ユーザー            役割               権限
┌────────┐     ┌──────────┐     ┌──────────────────┐
Alice  │────→│ 管理者   │────→│ ユーザー管理     │
Bob    │     │          │     │ システム設定     │
└────────┘     └──────────┘     │ ログアクセス     │
                                └──────────────────┘
┌────────┐     ┌──────────┐     ┌──────────────────┐
Carol  │────→│ 開発者   │────→│ コードリポジトリ │
Dave   │     │          │     │ ビルドシステム   │
Eve    │────→│          │     │ テスト環境       │
└────────┘     └──────────┘     └──────────────────┘
(Eveは開発者 + 監査者の役割を同時に持てる)

RBACの利点

  • 管理容易: ユーザー入退社時に役割の追加/削除のみ
  • 最小権限: 役割に必要な最小権限のみ割り当て
  • 職務分離: 競合する役割を同時に持てないよう制限可能

6. 強制アクセス制御(MAC)- SELinux

DAC vs MAC

DAC(任意アクセス制御):            MAC(強制アクセス制御):
- ファイル所有者が権限を決定        - システムポリシーが権限を決定
- ユーザーが自由に権限変更          - 管理者のみポリシー変更可能
- UNIX基本ファイル権限              - SELinux, AppArmor

DAC問題:
ユーザーがroot権限取得時 → すべてのファイルアクセス可能

MAC利点:
rootでもSELinuxポリシーにより制限される

SELinuxの概念

SELinuxセキュリティコンテキスト:
user : role : type : level

:
system_u:system_r:httpd_t:s0    (Apache Webサーバー)
system_u:object_r:httpd_sys_content_t:s0  (Webコンテンツ)

ポリシールール:
allow httpd_t httpd_sys_content_t : file { read open getattr };
→ httpd_tタイプのプロセスはhttpd_sys_content_tタイプのファイルを
  読み取り、開く、属性確認のみ可能
# SELinux 상태 확인
getenforce
# Enforcing, Permissive, Disabled

# 파일의 보안 컨텍스트 확인
ls -Z /var/www/html/
# -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

# 프로세스의 보안 컨텍스트 확인
ps -eZ | head -5

# 보안 컨텍스트 변경
chcon -t httpd_sys_content_t /var/www/html/newfile.html

7. サンドボックス(Sandboxing)

プログラムの実行環境を隔離してシステムの他の部分へのアクセスを制限します。

サンドボックス技法

┌────────────────────────────────────────────┐
│           サンドボックス階層                 │
│                                            │
システムコールフィルタリング (seccomp-bpf):│  ┌──────────────────────────────────┐      │
│  │ プロセス                         │      │
│  │ → open(), read() → 許可         │      │
│  │ → execve()       → 遮断         │      │
│  │ → socket()       → 遮断         │      │
│  └──────────────────────────────────┘      │
│                                            │
│  名前空間隔離(Linux):│  ┌──────────────────────────────────┐      │
│  │ PID名前空間: プロセス隔離        │      │
│  │ NET名前空間: ネットワーク隔離    │      │
│  │ MNT名前空間: ファイルシステム隔離│      │
│  │ USER名前空間: ユーザー隔離       │      │
│  └──────────────────────────────────┘      │
│                                            │
│  chroot / pivot_root:│  ┌──────────────────────────────────┐      │
│  │ プロセスが見るルートディレクトリ  │      │
│  │ を制限してファイルシステム隔離    │      │
│  └──────────────────────────────────┘      │
└────────────────────────────────────────────┘

seccomp-bpfの例

#include <seccomp.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    // seccomp 필터 초기화 (기본: 모든 시스템 콜 차단)
    scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);

    // 허용할 시스템 콜만 추가
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);

    // 필터 적용
    seccomp_load(ctx);

    printf("Sandboxed process running\n");

    seccomp_release(ctx);
    return 0;
}

ブラウザのサンドボックス

┌──────────────────────────────────────────┐
│              ブラウザ                     │
│                                          │
│  ┌──────────┐  ┌──────────┐              │
│  │ブラウザ  │  │ブラウザ  │              │
│  │プロセス  │  │プロセス  │ ← 高い権限   │
│  │(メイン)│  │(GPU)   │              │
│  └────┬─────┘  └──────────┘              │
│       │                                  │
│  ┌────┴─────┬──────────┬──────────┐      │
│  │レンダラー│レンダラー │レンダラー│      │
│  │(タブ1)│(タブ2)  │(タブ3) │      │
│  │サンドBOX│サンドBOX  │サンドBOX │ ← 低い│
│  │ファイル │ネットワーク│システム  │  権限 │
│  │アクセス │アクセス   │コール    │      │
│  │制限     │制限       │制限      │      │
│  └─────────┴──────────┴──────────┘      │
└──────────────────────────────────────────┘

8. コード署名(Code Signing)

実行ファイルの出所と完全性を検証するメカニズムです。

開発者:
1. コード作成
2. ハッシュ生成: hash(コード) = H
3. 署名生成: sign(H, 秘密鍵) = S
4. コード + 署名S + 証明書を配布

ユーザー(OS:
1. コードダウンロード
2. 証明書から公開鍵を抽出
3. 署名検証: verify(S, 公開鍵) = H'
4. コードハッシュ計算: hash(コード) = H
5. H == H' ? 実行許可 : 遮断
┌────────────────────────────────────────────┐
OS別コード署名ポリシー              │
│                                            │
│  macOS:- Gatekeeper: 署名済みアプリのみ実行許可 │
- 公証(Notarization): Appleサーバー検証│
│                                            │
Windows:- Authenticode: 実行ファイル署名          │
- SmartScreen: 評判ベースフィルタリング   │
│                                            │
Linux:- カーネルモジュール署名検証              │
- Secure Boot: UEFIブートチェーン検証    │
│                                            │
│  モバイル(iOS/Android):- アプリストア署名必須                    │
- iOS: すべてのコード署名必須            │
└────────────────────────────────────────────┘

9. まとめ

  • 保護原則: 最小権限、権限分離、職務分離
  • 保護リング: ハードウェアレベルの権限階層(Ring 0 ~ Ring 3)
  • アクセス行列: ACL(オブジェクト中心)と能力リスト(主体中心)で実装
  • RBAC: 役割ベースアクセス制御で管理容易性を確保
  • MAC/SELinux: 強制アクセス制御でrootもポリシーにより制限
  • サンドボックス: seccomp、名前空間等でプロセス隔離
  • コード署名: 実行コードの出所と完全性の検証
クイズ:保護

Q1. DACとMACの違いは何ですか?

A1. DAC(任意アクセス制御)はファイル所有者が自由に権限を設定・変更できます。MAC(強制アクセス制御)はシステム管理者が定義したセキュリティポリシーによってアクセスが決定され、個々のユーザーやrootでもポリシーを回避できません。

Q2. ACLと能力リスト方式の長所と短所を比較してください。

A2. ACLはオブジェクト中心で、特定ファイルに誰がアクセス可能かを簡単に把握でき権限の取消も容易です。能力リストは主体中心で、特定プロセスがどのリソースにアクセス可能かを素早く確認できますが、特定リソースに対するすべての能力を見つけて取り消すのが困難です。

Q3. サンドボックスはセキュリティにどのように貢献しますか?

A3. サンドボックスはプログラムがアクセスできるシステムリソースを厳格に制限します。例えばブラウザのレンダラープロセスが脆弱性により攻撃されても、サンドボックスがファイルシステムアクセスとシステムコールを制限するため、攻撃者がシステム全体を掌握することを困難にします。