More Related Content Similar to mod_auth_ticket - Bringing Single-Sign-On to lighttpd (20) More from Taisuke Yamada (20) mod_auth_ticket - Bringing Single-Sign-On to lighttpd2. lighttpd とは
apache nginx lighttpd thttpd
稼動に必要な
メモリやリソース △ ○ ○ ◎
機能や
モジュール資産 ◎ ○++ ○ △
おおまかな性能
(条件による) △ ◎ ○ ○
非サーバー的
使いやすさ × × × ○
モジュール開発
API 充実度 ○ ○ △ ×
モジュール間の
連携 ○ ○ △ ×
モジュール追加
容易性 ○ △ ○ ×
開発の活発度 ◎ ○ △ ×
3. こんな状況に最適
● マシンリソースは節約したい
●
そこそこ性能と機能は欲しい
● 自分で拡張したい
● 後からモジュール構成を
ちょこちょこいじりたい
普通のサーバーでも
使えますが、こういう HP t5730
シンクライアント転用の
自宅サーバーで使用中
Wyse S90
4. mod_auth_ticket
● OpenID などの SSO でサーバ全体を保護する
●
各種アプリでの対応は不要
(ユーザ管理をどうするかにより若干手を入れる必要はある)
IdP
mod_auth_ticket
認
静的ファイル 証
アプリ1 /PHP ブ
リ
アプリ2 /Perl ッ
ジ
アプリ3 /Ruby (RP)
5. mod_auth_ticket
● OpenID などの SSO でサーバ全体を保護する
●
各種アプリでの対応は不要
(ユーザ管理をどうするかにより若干手を入れることもある)
RP 発行の
トークンの IdP
破棄・更新
ベーシック mod_auth_ticket
認証相当に 認
見せかける 静的ファイル 証 各種 SSO 結果を
アプリ1 /PHP ブ m_a_t の対応形式で
リ 暗号化・署名して
アプリ2 /Perl ッ 保護ページに再度
ジ
アプリ3 /Ruby (RP)
リダイレクト
6. メリットとデメリット
メリット
●
どんなコンテンツ・ SSO 方式にも容易に対応
● 特別な設定なしにログにユーザ別の履歴が残る
● サーバ内アプリ間移動で再認証が不要で高速
● 対ユーザは Form 認証、対アプリは Basic 認証と
UI 構成や開発が楽な方向で見せかけられる
デメリット
● サーバの管理権限が必要
● その SSO 方式に対応済のアプリと干渉する
(そのアプリについては外さないと無駄な再認証が起きたり)
7. 設定例(と lighttpd の応用)
$HTTP["url"] =~ "^/login/" {
setenv.add-environment = ( RP の設定
"MAT_NAME" => mat_name,
"MAT_KEY" => mat_key
)
}
else $HTTP["url"] =~ "^/" { m_a_t の設定
auth-ticket.loglevel = 255
auth-ticket.override = 2
auth-ticket.timeout = 3600
auth-ticket.name = mat_name
auth-ticket.key = mat_key
auth-ticket.options = "path=/; httponly;"
auth-ticket.authurl = "/login/"
}
8. 設定例(と lighttpd の応用)
$HTTP["url"] =~ "^/login/" {
setenv.add-environment = (
"MAT_NAME" => mat_name,
"MAT_KEY" => mat_key
)
} 暗号化 IdP
else $HTTP["url"] =~ "^/" { ・
署名
auth-ticket.name = mat_name
auth-ticket.key = mat_key
}
ベーシック mod_auth_ticket
認証相当に 認
見せかける 静的ファイル 証 各種 SSO 結果を
常に m_a_t と RP の アプリ1 /PHP ブ m_a_t 指定の形式で
リ 暗号化・署名して
キー情報が一致する
アプリ2 /Perl ッ
ジ
保護ページに再度
必要がある アプリ3 /Ruby (RP)
リダイレクト
9. 設定例(と lighttpd の応用)
# generate "var.mac_name" and "var.mac_key"
include_shell "/.../lighttpd-make-mat-key.sh"
$HTTP["url"] =~ "^/login/" {
・・・以下先程の設定・・・
$ cat lighttpd-make-mat-key.sh
#!/bin/sh
md=$(dd if=/dev/urandom bs=1 count=16|md5sum)
set -- $md
ロード時にコマンドを
cat <<EOF 実行して、その結果を
var.mat_name = "CHID" 設定として取り込める。
var.mat_key = "$1" これで毎回変わる(※)
EOF 共通キーを自動生成
※ マシン起動時は同じになる問題が…
10. まとめ(1)
● アプリ/コンテンツ関係なしにサーバ全体を
SSO 認証下に置く mod_auth_ticket を作ってみた
● 複数アプリ雑居サーバの認証管理に便利
● 今のところ GoogleAccount でテスト(実利用中)
→ 他の SSO 方式にも RP ページ1枚で対応
● lighttpd は旬を過ぎた感もあるけど便利
公開中&今後の予定
● https://github.com/tai/mod-auth-ticket-for-lighttpd
● 互換モジュールを apache に移植するかも…
11. lighttpd モジュールの作り方
int
mod_auth_ticket_plugin_init(plugin *p) {
p->name = buffer_init_string("auth_ticket")
p->version = LIGHTTPD_VERSION_ID;
p->init = module_init;
p->set_defaults = module_set_defaults;
p->cleanup = module_free;
p->handle_uri_clean = module_uri_handler;
p->data = NULL;
init で初期化、
return 0; set_defaults で設定を読み込み、
} h_u_c で設定に基づいて処理して、
cleanup で終了処理
Apache や nginx に比べてシンプル(やや機能は↓)
12. lighttpd モジュールのデータ構造
init で生成し、以後受け渡されてゆくデータ構造
typedef struct { lighttpd.conf 内の {}
PLUGIN_DATA; コンテキスト毎に生成
される p_c のリスト
plugin_config **config;
plugin_config conf; 上のコンテキスト別の
設定を合成し、「今の
実行コンテキストで
array *users; 有効になっている」設定
} plugin_data;
※ 上は m_a_t の場合
具体的な plugin_config の中身は
モジュール毎に自由。 p_c は
コンテキスト毎に生成されるので
コンテキストに因らない情報なら
plugin_data に直接収容できる
13. モジュール作成での比較
apache nginx lighttpd
マルチプロトコル
対応 / フック多様性 ○ ○ ×
メモリ管理
階層型プール 階層型プール 単一バッファ
ap_*(p, ...) ngx_p*(p, ...) buffer_*(...)
ngx_buf_t,
libapr 参照 ngx_array_t, buffer, array,
ngx_list_t, stream 位?
提供される 汎用のものも
データ構造や API HTTP 特有のも、 ngx_hash_t,
ngx_rbtree_t, とにかく少ない
充実度は nginx
と apache は同格 ngx_url_t, &未整理な感じ
... 他多数
ステージ粒度や
モジュール連携の かなり細かい かなり細かい やや粗目
柔軟性
./configure Makefile.am 編集で
モジュールの apxs で 一括ビルド or
ビルド --add-module=
外部ビルド で静的リンク
同一ビルドオプションで
外部ビルド
14. まとめ( 2 )
● まとめてみると… lighttpd は手間かかる orz
●
apache 最強。しかし nginx もよく考えられてる
● nginx に DSO をロードするモジュールを
静的リンクしておくと幸せになれる気がしてきた
15. 困っていること
平文で送る mod_auth_cookie より
安全だが、 RP<->m_a_t の連携が
どの程度安全か実は図りかねてる
IdP
ココ
ベーシック mod_auth_ticket
認証相当に 認
見せかける 静的ファイル 証 各種 SSO 結果を
アプリ1 /PHP ブ m_a_t 指定の形式で
リ 暗号化・署名して
アプリ2 /Perl ッ 保護ページに再度
ジ
アプリ3 /Ruby (RP)
リダイレクト
16. 何をやっているか
● in→out の転送時に平文のままは NG
●
幸い、長さが短いので擬似乱数列と XOR している
● しかし、毎回同じだとモロバレ
● そこで、時刻 t を salt に使って乱数列を捻る
● 更に、同時刻でも in が違えば out が異なるよう
直前バイトとも XOR out(= 暗号化した状態)
in(= 認証結果の情報 )
mod_auth_ticket
認
静的ファイル 証
アプリ1 /PHP ブ
リ
アプリ2 /Perl ッ
ジ
アプリ3 /Ruby (RP)
17. 安全?な受け渡し(1)
function make_cookie($key, $data) {
$now = time();
$now = $now - $now % 5; # 5秒毎にキー変更
$tmp = md5($now . $key, TRUE);
$enc = bin2hex(
encrypt($data,$tmp,strlen($tmp)));# 暗号化
$sig = md5($key . $now . $enc); # 署名
return "crypt:" . $sig . ":" . $enc;
}
18. 安全?な受け渡し(2)
# 要は buf[i] = rand[i] ^ buf[i] ^ buf[i-1]
function encrypt($buf, $key, $keylen) {
$n = strlen($buf);
for ($i = 0; $i < $n; $i++) {
$c = ord($buf[$i]); #IV=0 なのが微妙↓
$c ^= ($i > 0 ? ord($buf[$i - 1]) : 0)
^ ord($key[$i % $keylen]);
$buf[$i] = chr($c);
}
return $buf;
}
19. まとめ( 3 )
● お遊びサーバならいいが…
●
こういうやつの「安全性」の評価方法は?
● 乱数列 +XOR 自体は安全、でも…
● それに時刻(=絞り込み可能)を加えたら?
● それを MD5 したら? MD5(rand) の乱数性は?
● IV=0 で折り畳み XOR した時の脆弱度は?
– 既知平文攻撃でアウトか…
先生、もっと知識(&想像力)が欲しいです…
※ そういうわけで、コメント大歓迎