2011-08-28 isucon に参加してきた。
iscon にチーム「いんふらえんじにあー」として馬場さん(@netmarkjp )、松鵜さん(@matsuu )の3人で参加してきました。
注意: チューニング云々の話は書いてません。忙しい人は見ないことをお勧めします。。
当日のパフォーマンス的な話は以下を
■ isuconとは? 
isucon とは、いい感じにスピードアップコンテスト、略して ISU Contest (Iikanjini Speed Up Contest) #isucon です。
椅子を投げないなどの特定の制限を設けた上で与えられたアプリケーションをチューニングする大会。1組は最大3人から構成され、10時から19時(18:00作業終了)まで持てる力全てを注ぐ。
■ 発端 
isucon 開催のお知らせから約一週間後、 馬場さんから連絡(DM)がありました。
ライブドアの #isucon 一緒にでません?もちろん SELinux はONで!松鵜さんにも声かけてますが、(略)
もちろん SELinux はONで!
もちろん SELinux はONで!
もちろん SELinux はONで!
もちろん SELinux はONで!
よろしいならば、Enforce だ。
むしろ、それしかできませんけど!
■ 作戦会議 
8月某日、ビールが旨い「渋谷 The Griffon」にて実施しました。
決定事項と言うか妄想事項は以下の4点でした。多分。
- Cherokee といういかした Webサーバがあるのでそれを使おう
- バックエンド通信は全て IPv6 でやろう
- 隙を見て会場にピザ頼もう
- 初めの2時間、ソーシャル・ネットワークを見てテンション上げる作戦
- 作戦会議中のグリフォンでたまたま流れていたため
ソーシャル・ネットワーク について @tnmtさんに話したところ「事前に見てこいよ」と一蹴されました。
■ 当日まで 
Facebook のメッセージで連絡を取り合っていましたが、今見なおすと、Cherokee の話しかしてませんでした。
参考: isucon 前日金曜日 松鵜さんの発言
Cherokeeを試すつもりが、いつのまにかcherokeeのGentooパッケージを作っていたでござる
GJ!
■ 当日(開場前) 
馬場さん: 壁際確保したよ!
松鵜さん: 【速報】ソーシャルネットワーク、すべて貸出中で借りられず。残念無念。
石川:
ほぎゃあああああ!!!
準備をしたら寝坊しました。すみませんでした。毛虫になりたい。
■ 当日(潜入後) 
所在なきプロジェクタ
BENQ MP515ST こいつの役目は終わりました。
と、いうことで初めから馬場さんの Mac に繋いで top の結果を表示するのに使いました。
やっぱり火急なトラブル対応などの時には共通認識を持つことが重要ですね。
ホワイトボード・プロジェクタ・大きなアナログ掛け時計などなど。
自分の仕事
私の仕事は SELinux を有効にした状態で全ての動作をさせる。でした。
折角なのでゆるーい Targeted では堅い Strict で動作させます。
Targeted は一部のデーモンを SELinux の制御におき、その他は unconfined という制御の及ばないドメインで動作します。
Strict は unconfined を除去したハードモード。
それより上は、MLS と呼ばれるルナティックモード。
こんな感じに作業を進めました。
- 状態の確認
- sestatus -> Disabled でした
- ポリシーパッケージのインストール
- # yum -y install selinux-policy-strict
- 有効化と再ラベル付け
- ユーザマッピングの設定
- # semanage login -a -s staff_u -r "s0-s0:c0.c1023" isucon
- /etc/sudoers の設定(ちょっとアレ…)
- isucon ALL=(ALL) NOPASSWD: ALL を変更
- isucon ALL=(ALL) ROLE=sysadm_r TYPE=sysadm_t NOPASSWD: ALL
- 観察
- boolean値の設定
- httpd_can_network_connect_db などを有効化
- ラベル付け
- それっぽいラベルを付ける
- SSH 用ポート開放
- このあたり参照: http://2done.org/index.php?id=14
- 足りないポリシーを作成(最終手段)
- # cat /var/log/audit/audit.log | audit2allow -M local
設定中の問題点など
- 作り込み部分
- 下位の挙動を抑えるに時間が足りない
- 色々あってTargeted に戻したものの、何故か unconfined_u がない
- 手元の環境にCentOS5.6 をインストールしてみたものの同じ。何これ。
- オペレーションとアプリケーションが同時に走っている
- 本来、拒否されなければならないものと許可したいもののログが混ざるため疲れる。
- コンソールが使えないのでミスったら試合終了
最後の最後まで Permissive で作業してましたが、測定前OSのリブート直前で Enforce にしました。
立ち上がるかどうかちょっと不安でしたがまあ、無事立ち上がり、最終結果、準優勝改め3位で終わりました。
ちなみに、作戦会議で決まった4つの事項はどれも手を付けませんでした。
マ(M)ジでル(L)ナティックなセ(S)キュリティ?
それとも、パラノイアモード?(^^;
(少なくとも CentOS 6 では)unconfined_t は全許可ではありません(幾つかの操作は拒否される)のでご注意を。
マ(M)ゾしかル(L)ナティックにす(S)すめないですw
今回は CentOS 5.6 でした。
CentOS 6 ではそうなんですね。
最近、F15を使っていますが、unconfined, unconfineduser モジュールを
止めているので、unconfined_t には縁がありません。。
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/elf.h>
static inline int uselib(const char *library)
{
return syscall(__NR_uselib, library);
}
static void make_elf_lib(void)
{
static const struct elf32_phdr eph = {
.p_type = PT_LOAD,
.p_offset = 4096,
.p_filesz = 1,
};
static const struct elf32_hdr eh = {
.e_ident = ELFMAG,
.e_type = ET_EXEC,
.e_machine = EM_386,
.e_phoff = sizeof(eh),
.e_phentsize = sizeof(eph),
.e_phnum = 1,
};
const int fd = open("/tmp/uselib", O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (fd != EOF) {
write(fd, &eh, sizeof(eh));
write(fd, &eph, sizeof(eph));
lseek(fd, 4096, SEEK_SET);
write(fd, "", 1);
close(fd);
}
}
int main(int argc, char *argv[])
{
make_elf_lib();
if (uselib("/tmp/uselib") == 0)
printf("OK\n");
else
printf("%d\n", errno);
return 0;
}
--------------------
というプログラムを CentOS 6 の targeted / enforcing で実行すると以下のようになります。 CentOS 5 では拒否されませんでした。
type=AVC msg=audit(1314530788.610:173): avc: denied { mmap_zero } for pid=4260 comm="a.out" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=memprotect
type=SYSCALL msg=audit(1314530788.610:173): arch=40000003 syscall=86 success=no exit=-13 a0=80486ec a1=1 a2=d08ff4 a3=8048620 items=0 ppid=4227 pid=4260 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=11 comm="a.out" exe="/tmp/a.out" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
# sesearch -A -C -s unconfined_t -t unconfined_t -c memprotect
の結果を見ると、デフォルトで無効化されている mmap_low_allowed を有効にすれば、アクセスが可能になるようです。
大きな権限は与えているものの、不要な権限はデフォルトで抑止しているといった感じでしょうか。