memcached + selinux engine

19
OSS Development Study Meeting-06 1 Memcached + SELinux engine OSS開発勉強会-06 KaiGai Kohei (@kkaigai ) <[email protected]>

Upload: kohei-kaigai

Post on 22-May-2015

1.572 views

Category:

Technology


1 download

DESCRIPTION

OSS開発勉強会-06の資料

TRANSCRIPT

Page 1: memcached + selinux engine

OSS Development Study Meeting-06 1

Memcached + SELinux engine

OSS開発勉強会-06

KaiGai Kohei (@kkaigai)<[email protected]>

Page 2: memcached + selinux engine

OSS Development Study Meeting-06 2

Memcachedの特徴

�Key-Valueストア� <Key>に対応する<Value>を保存/取得するだけの機能

� トランザクション、検索式、型定義...など無い!�速さこそ正義

�分散システム� Memcachedサーバ自体に一切の分散機能は無い

� ライブラリがKey値に応じたMemcachedサーバを選択して接続

�memcached プロトコル

� テキストベースのシンプルなプロトコルhttp://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt

�多くの互換Key-Valueストア

� Tokyo Tyrant, Repocached, Flared, KumoFS, ...

Page 3: memcached + selinux engine

OSS Development Study Meeting-06 3

Memcachedシステムイメージ

Web-Apps

libmemcached

Web-Server

Memcached

PostgreSQL

User

ライブラリが接続先のMemcachedサーバを選択

ライブラリが接続先のMemcachedサーバを選択

個々のMemcachedサーバは互いに独立にKey-Valueペアを格納する

個々のMemcachedサーバは互いに独立にKey-Valueペアを格納する

Page 4: memcached + selinux engine

OSS Development Study Meeting-06 4

Memcached 内部構造

�プロトコル解析部

�Key-Valueストレージ� これ、Key-Valueストレージの部分をモジュール化できるよね?

libevent

プロトコル処理部

Key-Value

ストレージ

Key-Value

ストレージwith

New Feature

get_item()

hash_item *

GET aaa

‘xyzxyz’

Page 5: memcached + selinux engine

OSS Development Study Meeting-06 5

Memcached Engine (1/2)

�Engine Interface v1

�次期メジャーバージョン(v1.6.x系)の新機能

typedef struct engine_interface_v1 {

:

/**

* Retrieve an item.

*

* @param handle the engine handle

* @param cookie The cookie provided by the frontend

* @param item output variable that will receive the located item

* @param key the key to look up

* @param nkey the length of the key

* @param vbucket the virtual bucket id

*

* @return ENGINE_SUCCESS if all goes well

*/

ENGINE_ERROR_CODE (*get)(ENGINE_HANDLE* handle,

const void* cookie,

item** item,

const void* key,

const int nkey,

uint16_t vbucket);

こんな感じでInterfaceが定義されている

こんな感じでInterfaceが定義されている

Page 6: memcached + selinux engine

OSS Development Study Meeting-06 6

Memcached Engine (2/2)

�オリジナルRFC

Memcache Engine Interface (Dec, 18 2008)

http://code.google.com/p/memcached/wiki/EngineInterface

�Engine-Interfaceとは?

� Key-Valueペアの管理をプラグインに任せる

� 何がいいのか?

� 独自の拡張機能ごとに “memcachedクローン” を作らずに済む

� Persistent Storage, Name Space, Access Control, etc...

�本体 ⇔ プラグイン間のインターフェースを規定

� ENGINE_HANDLE_V1構造体: 本体�プラグインの呼び出し

� SERVER_HANDLE_V1構造体: プラグイン�本体の呼び出し

Page 7: memcached + selinux engine

OSS Development Study Meeting-06 7

議論を通じた仕様の変更

� socket-fdを取得するServerAPIの追加� SELinuxはgetpeercon(3)にsockfdを与えて、接続元プロセスの権限 (=security context) を取得するため

� SERVER_HANDLE_V1構造体 に get_socket_fd() が追加

� ->delete() の手順を変更

� 従来の実装

1. ->get() に Key値を与えて呼び出し、本体は item *ポインタを取得

2. ->delete()に item *ポインタを与えてKey-Valueペアの削除

� 問題点

� ->get()内で評価すべきパーミッションは、“read権限”なのか、それとも”delete”権限なのか、特定できない

� 修正後の実装

� ->delete() にKey値を与えるよう ENGINE_HANDLE_V1構造体を修正

Page 8: memcached + selinux engine

OSS Development Study Meeting-06 8

Memcached and Security

� できる事はほとんど何もない� 絶対に外部ネットワークから接続可能にしちゃダメ

� 一応、SASL認証で接続の可否を決める事はできる

� あと、root権限で走らせてはならない

� Memcached Security; by Dustin Sallingshttp://dustin.github.com/2010/08/08/memcached-security.html

Memcached

Web Server

Web Apps (1) Firewalling, always

(1) Firewalling, always

(2) SASL auth,if needed

(2) SASL auth,if needed

(3) Not run as root(3) Not run as root

Page 9: memcached + selinux engine

OSS Development Study Meeting-06 9

SELinuxによるアクセス制御

domain ofclassified processes

domain ofunclassified processes

inter processcommunication channels

Filesystem

classifiedinformation

unclassifiedinformation

Networks

memcached RDBMS

SELin

ux

SecurityPolicy

“機密” 情報は、どこに格納しても“機密”情報として扱う

Page 10: memcached + selinux engine

OSS Development Study Meeting-06 10

SELinux対応Memcached

�必要機能� Key-Valueペアを格納し、高速に探索する(できれば Persistent Storage 機能もサポート)

� Key-Valueペアにセキュリティコンテキストを関連付け

�本体側からの呼び出し時にアクセス制御を行う

�方針� Key-Valueペアは mmap(2) した領域に配置

� 容易に Persistent Storage 化可能

� B+Treeインデックスを用いる

� サイズの増減に柔軟に対処できる。順スキャン可能。

Page 11: memcached + selinux engine

OSS Development Study Meeting-06 11

selinux_engine.so

selinux_engine.so の構成

mblock.c

mbtree.c

mcache.c

interface.c selinux.c

メモリブロックのalloc()/free()

メモリブロックのalloc()/free()

B+木インデックスB+木インデックス

Key/Valueペア管理、セキュリティラベル

Key/Valueペア管理、セキュリティラベル

Engine V1 のフック関数

Engine V1 のフック関数

SELinuxを用いたアクセス制御

SELinuxを用いたアクセス制御

Memcached

本体

Engine V1

インターフェース

Page 12: memcached + selinux engine

OSS Development Study Meeting-06 12

mblock.c

� mmap(2)した領域を 2^N サイズ単位で割り当て・解放する

� Buddyアルゴリズムを用いたメモリ管理

� シンプルで領域の分割併合を行いやすい方法

� 最悪の場合、メモリ利用率は 50% そこそこに…。

� 別の mchunk_t を参照する際にポインタを使えない。

� uint64_t 幅のオフセット値を使用する

MCHUNK_TAG_FREE

uint16 magic

uint8 mclass

uint8 tag

mlist_t list

uint64_t prev

uint64_t next

MCHUNK_TAG_ITEM

uint16 magic

uint8 mclass

uint8 tag

uint16_t flags

uint16_t keylen

uint32_t datalen

uint32_t secid

uint32_t exptime

uint8_t data[0]

MCHUNK_TAG_BTREE

uint16 magic

uint8 mclass

uint8 tag

uint64_t parent

uint8_t is_leaf

uint16_t nkeys

uint32_t keys[N]

uint64_t items[N+1]

MCHUNK_TAG_LABEL

uint16 magic

uint8 mclass

uint8 tag

uint32_t secid

uint32_t refcount

uint8_t value[0]

mchunk_t 構造体の定義(tag値による多様性を持つ)

Page 13: memcached + selinux engine

OSS Development Study Meeting-06 13

mbtree.c

� uint32_t型のキーと、uint64_t型の値からなるB+木構造

� uint32_t : 真のキーをハッシュ化した値

� uint64_t : ITEMやLABELチャンクへのオフセット値

� ハッシュと比べ、データ量が増えた時の再編コストが安い

� default_engine.so は、アイテム数に応じてハッシュスロットの数を増減する

V0 V1

K0VN-1 VN

KN-1

V0 V1

K0V3V2

K1 K2V0 V1

K0V3V2

K1 K2

V0

K0

V1

K1

V2

K2

V3 V0

K0

V1

K1

V2

K2

V3 V0

K0

V1

K1

V2

K2

V3 V0

K0

V1

K1

V2

K2

V3

null

MCHUNK_TAG_ITEM MCHUNK_TAG_LABEL

Page 14: memcached + selinux engine

OSS Development Study Meeting-06 14

mcache.c

� Key-Valueペアを表現するデータ構造

� tsid � パース済みの MCHUNK_TAG_LABEL

� mchunk � MCHUNK_TAG_ITEM へのポインタ

� データ構造の目的

� Key-Valueに対応するセキュリティラベルを毎度々々探索せずに済むように

� 最近使った Key-Value を疑似LRUで繋いでおく

� refcnt の操作によって、mmap(2)したページが Dirty にならないように

� Dirtyになると、ファイルをmmap(2)した時に I/O が発生するので。

mcache_t 構造体

int refcnt

mcache_t *next

bool is_hot

security_id_t tsid

mchunk_t *mchunk

mcache_t 構造体 mcache_t 構造体

mca

che ハッシュ表

MCHUNK_TAG_ITEM

MCHUNK_TAG_LABEL

Page 15: memcached + selinux engine

OSS Development Study Meeting-06 15

interface.c

� create_instance()で、コールバックの関数ポインタを登録

� イベントに応じて登録した関数が呼び出される

SETコマンド処理の例

process_update_command()

SETコマンドのパースクライアントからのデータ入力受付準備

->allocate() メソッド

入力データ用のItemバッファを確保

->store() メソッド

利用者の write 権限をチェックする新しいItemをB+木に追加

(必要なら)古いItemをB+木から削除

->release() メソッド

参照カウンタをデクリメントB+木に登録されていなければ、

Itemを開放する

complete_update_ascii()

データを読み込んだItemバッファをインデックスに登録する処理(必要なら古いItemを削除する)

確保したItemバッファに対してクライアントからのデータを入力

利用者に store() の実行結果を返却STORED/EXISTS/NOT_FOUND/...

本体側 モジュール側

Page 16: memcached + selinux engine

OSS Development Study Meeting-06 16

selinux.c

� アクセス制御を行う関数群

� interface.c 内の各メソッドから呼び出され、SELinuxにアクセス制御の問い合わせを行う。

� ‘denied’の結果が返却されれば、ERROR_EACCESSを呼出し元に返す

� Access Vector Cache (AVC)を用いて、システムコール回数を最小化

mselinux_check_write()

avc_has_perms()

on cache?

security_compute_av()

SELinux

securitypolicy

Yes

No

System-Call

Acc

ess

Control Decision

ERROR_SUCCESSor

ERROR_EACCESS

Query

Page 17: memcached + selinux engine

OSS Development Study Meeting-06 17

ベンチマーク

� Iteration of GET/SET mixture, 8threads-client, 4core server x 2, Gb-ether

� Less significant differences in same network environment

� Penalties in IPsec(AH) communication (~20%?)

0 100000 200000 300000

No IPsec

IPsec(AH)

IPsec(ESP)

number of commands in 30sec

default selinux

0 100000 200000 300000

No IPsec

IPsec(AH)

IPsec(ESP)

number of commands in 30sec

default selinux

251,485251,485

191,409191,409

Page 18: memcached + selinux engine

OSS Development Study Meeting-06 18

設定パラメータ

� filename=<fname>

� <fname> をストレージとして mmap(2) する。デフォルトは匿名マッピング

� size = <total_size>

� mmap(2)するサイズ。PageSizeの倍数でなければならない。

� use_cas = (true|false)

� Compare-and-Set操作をサポートするか否か

� selinux = (true|false)

� SELinuxサポート(アクセス制御)の有効化/無効化

� これを無効化すると、ただのストレージ付きMemcachedになってしまう

� reclaim = (true|false)

� 領域の不足時に、既存ItemをReclaimするか否か。

� debug = (true|false)

� デバッグ出力のON/OFF

Page 19: memcached + selinux engine

OSS Development Study Meeting-06 19

おしまい

�Twitterでの質問先� @kkaigai

�ソースコードの入手先% svn co http://sepgsql.googlecode.com/svn/trunk/memcached

% cd memcached

% autoconf

% env CPPFLAGS=-I/path/to/memcached/include ./configure

% make

% su –c ‘make install’

�情報源� Coming soon.... ドキュメントを書きましょう ☺