mikanmarusanのブログ

テクノロジーとかダイビングとか

iOS6.1の新機能「Advertising Identifierをリセット」を見てみる

はじめに

Advertising Identifierとは、文字通り広告識別子であるが、本機能は、iOS6.0から搭載されたAdvertising Identifierをリセットする機能のことらしい。

設定>一般>情報>アドバタイズ で設定をすることができる。

iOS6.0

iOS6.1

iOS6.0の時も「追跡型広告を制限する」というのがあるが、なぜ今回リセット機能が追加されたのかちょっと調べてみた(ググってみた)。

このIDの背景とか特徴とか

ざっくり言うと、このAdvertising Identifierの登場の背景と特徴は下記の通り。

[背景]

  • UDIDへのアクセスは原則禁止(iOS5から非推奨になってたはず)
  • UDIDの広告向けの代わりのIDとして、Advertising Identifier(スーパーCookie)が用意された

[特徴]

  • これはデバイス固有ですべてのアプリで同じIDとなる
  • 利用が許可されていればトラッキングに利用可能(デフォルトは利用許可になっている、なんてこったい)
  • どうも簡単に変更されないっぽい(揮発性があると書かれてるけど)

で、リセットの必要性は

スーパーCookieは怖い、これはグローバル識別子だから個人と簡単に紐づけることができる可能性(名寄せできる可能性)があるということだよね。

しかもユーザーが利用を許可していなくてもこのデータの取得自体はできるようなので、トラッキングが抑止される保証がないと推測できる(DNTの実情と似ているな)。

だからこのIDをユーザー自身がリセットできる機能が必要だったと思う。

identifierForVendorとは?

Advertising Identifierについて調べていたら、iOS6からidentifierForVendorなるIDもあるらしい。
これはTeamID(アプリの開発ベンダー)ごとに同一となるUDIDっぽいものらしい。

開発ベンダーごとだからといって「かんたんログイン」の識別子として利用すると多分危険。

まとめ

  • 「追跡型広告を制限する」をオフにしてもトラッキングされるかも
  • きになったらAdvertising Identifierを(定期的に)リセットするといい
  • identifierForVendorはベンダーごとに利用できるUDIDみたいなもの、ただし「かんたんログイン」的に利用していると、このIDの発行アルゴリズムがhackされると死ぬ

Cookieのexpireの扱いがブラウザによってちょっと異なる件

弊社のアプリが動かないという残念な問い合わせがいくつかあったので、1日ばかりずっと悶々と調べてみたりした。結局Cookieの挙動によるものだったんだけど、Cookieの有効期限の挙動がブラウザごとに違っているらしく、ちょっとハマッたので備忘録としてまとめてみた。

Cookieの仕様のおさらい

Cookieは、HTTP State Management Mechanism(HTTP 状態管理メカニズム)というタイトルで、RFC2965で定義されているみたいだが、各種ブラウザの実装は、Cookieを導入したNetscape Navigatorの実装に基づいているようだ。

ここでは、Cookieの仕様についての説明は割愛するが、超簡単にまとめると以下の通り。

  • サーバ
    • クライアントに保持してもらいたい状態情報を、HTTPレスポンスのSet-Cookieヘッダに乗せて送出する

Set-Cookie: NAME1=VALUE1; expires=DATE; path=PATH; domain=DOMAIN_NAME;
Set-Cookie: NAME2=VALUE2; expires=DATE; path=PATH; domain=DOMAIN_NAME;

  • クライアント
    • サーバから送られてきた状態情報を(有効期限内であれば)保持し、次回以降のリクエストにおいて、HTTPリクエストの"Cookie:"ヘッダに乗せて送出する

Cookie: NAME1=VALUE1; NAME2=VALUE2 ...

ここらへんは、Webサイトを構築するエンジニアは必須知識だと思う。

まずはCookieの動きを確認する

Net Applicationsによれば、2010年12月のブラウザ3大シェアは下記の通り。ということで下記3つのブラウザを調査対象とする。ちなみにクライアントはVista。あまり定評が良くないVista

ここで、検証に利用する予定のSet-Cookieするサーバ側のアプリケーションをさらしておく(PHPerですみません)。有効期限が600秒(=10分間)のtestcookieという名前のCookieを、phpのsetcookie関数で発行する単純なプログラムである。

[cookieを生成するサーバアプリケーション] http://192.168.1.101/setcookie.php
  1 <?php
  2     $currentTime = time();
  3
  4     $cookieName   = "testcookie";
  5     $cookiePath   = "/";
  6     $cookieDomain = $_SERVER['SERVER_NAME'];
  7     $cookieValue  = strval($currentTime);       // value is issue time (Unix Time)
  8     $cookieExpire = strval($currentTime + 600); // expire is 10 minutes after issuing cookie
  9
 10     setcookie($cookieName,
 11               $cookieValue,
 12               $cookieExpire,
 13               $cookiePath,
 14               $cookieDomain);

ついでにサーバ情報はこんな感じ。

  • ホスト
    • 192.168.1.101 (プライベートIPでごめんなさい)
  • OS
  • 各種アプリ

ここでは、上記cookie発行プログラム(http://192.168.1.101/setcookie.php)にリクエストを送り、そのレスポンスヘッダとブラウザ側に蓄積されるcookie情報をブラウザごとに観察してみる。

Internet Explorer

通常のIEだとヘッダとかcookieの参照とか非力すぎて死ぬ。ヘッダ情報にはieHTTPHeadersCookieの参照にはInternet Explorer Developer Toolbar を導入した。Internet Explorer Developer ToolbarはMS純正。

  • ヘッダ情報

予想通り、Dateヘッダの10分後のExpireが設定されているtestcookieが発行され、それがブラウザにも保存されているようだ。当たり前か。

FireFox

FireFoxでヘッダの情報を確認するには、Live HTTP HeadersのAddonを導入。

  • ヘッダ情報

予想通り、Dateヘッダの10分後のExpireが設定されているtestcookieが発行され、それがブラウザにも保存され(略

Chrome

Chromeは、Ctrl+Shift+i でcookieやらヘッダ情報やら全て見える。デフォルトで使えて便利便利。

  • ヘッダ情報

予想通り、Dateヘッダの10分後のExpireが設定されているtestcookieが発行され(略。しつこいですね、わかります。

クライアントとサーバの時刻を変えてみる

クライアントとサーバの時刻が同じとき(=同期しているとき)、CookieのExpire値の処理はブラウザを変えても変化はなかった。クライアントの時刻がサーバと同期されていない場合はどうだろうか?サーバの時刻が不正な場合なんて言語道断なので、クライアントの時刻を1時間早めた場合で検証してみる。検証内容は先ほどと同様で、10分間の有効期限を設定したcookieを発行したときのブラウザごとの挙動を確認してみる。

Internet Explorer
  • ヘッダ情報 (クライアントのリクエスト時刻 = Mon, 31 Jan 2011 14:15:13 GMT ※1時間進んでるから)

あれ、cookieが蓄積されていない。試しに同じドメインで別のHTMLをGETするときのリクエストヘッダを見てみる。もしCookieが有効ならば"Cookie:"ヘッダがサーバに向けて付与されているはずである。

  • リクエストヘッダ情報

やっぱり、"Cookie:"ヘッダは送出されていない。この結果から推測されることは、IEでは"Set-Cookie:"のExpires値がそのまま評価され、クライアントのシステム時刻と比べて有効期限切れ(有効期限が過去の時刻になっている)と判断し、cookieに保存されなかったのではなかろうか?

FireFox
  • ヘッダ情報 (クライアントのリクエスト時刻 = Mon, 31 Jan 2011 14:34:15 GMT ※1時間進んでるから)

FireFoxcookie情報が蓄積されているようだ。しかもクライアント側のリクエスト発行時刻+10分間の有効期限が設定されていることに注意したい。また、IEの場合と同様に別のHTMLをGETするときのリクエストヘッダを観察してみる。cookieの有効期限の10分間を意識して、cookie発行から10分以内と10分経過後を比べてみた。

  • リクエストヘッダ情報(リクエスト時刻=cookie発行から10分以内)

  • リクエストヘッダ情報(リクエスト時刻=cookie発行から10分経過後)

この結果から推測されることは、Firefoxではサーバの意図したcookieの有効期限(=10分)がクライアント側の時刻に変換されてcookieに保存されるようである。おそらくレスポンスヘッダのDateヘッダとSet-CookieのExpires値の差分(=10分)を取得し、クライアントのシステム時刻(ただし今回は1時間進んでいる)に加えていると思われる。

Chrome
  • ヘッダ情報 (クライアントのリクエスト時刻 = Mon, 31 Jan 2011 14:50:17 GMT ※1時間進んでるから)

Chromeは、IEと同じ挙動をするようだ。

まとめ

3大ブラウザのCookieのexpires値の処理
  • Internet Explorer/Chrome
    • HTTPレスポンスに含まれるSet-Cookieヘッダーのexpiresの値を厳密に利用しているようだ。
  • Firefox
    • FireFoxは少し複雑な処理をしているように見受けられる。
      • 1) HTTPレスポンスに含まれるDateヘッダとSet-Cookieのexpiresの差を計算しサーバ側で意図したcookieの有効期限を計算しているのだろう。
      • 2) クライアントのシステム時刻に1)で取得した有効期限を足した値をexpireとしているように見受けられる。

通常の利用がなされる場合には、両者の挙動にはまったく違いが見られないが、サーバとクライアントで時刻が異なる特殊なケースの場合に挙動が異なる可能性が出てくる。

クライアントとサーバの時刻が同期されていないとき

例としてクライアントが1時間時計を進めている時に、有効期限10分のcookieを発行した場合を考える。

  • サーバ時刻
    • Mon, 31 Jan 2011 10:00:00 GMT
  • クライアント時刻
    • Mon, 31 Jan 2011 11:00:00 GMT (1時間進んでる)
  • cookie発行プログラムのレスポンス
    • Date: Mon, 31 Jan 2011 10:00:00 GMT
    • Set-Cookie: testcookie=1296481564; expires=Mon, 31-Jan-2011 10:10:00 GMT; path=/; domain=192.168.1.101

この場合は下記の挙動となる

  • Internet Explorer/Chrome
    • Set-CookieのExpire値(expires=Mon, 31-Jan-2011 10:10:00 GMT;)とクライアントのシステム時刻を比較
    • 過去の有効期限のCookieと判断され、Cookieは保存されない。
  • Firefox
    • DateとSet-CookieのExpire値からサーバ側が意図したCookieの有効期限(=10分)を割り出す
    • システム時刻と有効期限を加えて、有効期限が Mon, 31 Jan 2011 11:10:00 GMT であるようなCookieを蓄積する

結論

通常利用ではブラウザによるSet-CookieのExpire値の挙動に変化はないが、クライアントとサーバの時刻が同期されていないときは注意が必要かもしれない。

石垣島ファンダイビング

2010/6/5〜2010/6/6に石垣島ファンダイビングに行ってきた(人生初沖縄)。前回ライセンスを取ってから半年も経ってしまったのでorz、リフレッシュダイブをかねて行ってきた、わはーい。


写真の一部は、「海へ」さんの当日のブログよりお借りしてます^^;

今回ガイドをお願いしたショップは、嫁がx年前にもお世話になったという「海へ」というショップ。きょうのワンコにも出たというガジロウがお出迎え。

6/5(1日目)

初日は3Dive!

  • コメント
    • 初のボートダイブ(船酔い)
      • 内関というつぼで船酔いが解消、これはすごい
    • 初のバックロールエントリー
    • スチールタンクは重い
      • ので、以前と同じウエイトつけて潜水したら海底ではぜのようになった→砂埃迷惑→ウエイト減らした
      • 中性浮力がわかってきたような希ガス
    • 船上での八重山そばは本当にうまい
(Dive6)竹富島南ムーミン谷 (Dive7)竹富島南ヨスジの根 (Dive8)竹富島南海底温泉
深度 12.4(AVE10.3)m 14.0(AVE10.2)m 18.2(AVE8.6)m
潜水時間 47分 49分 47分
気温 不明 不明 不明
水温 26.3℃ 26.3℃ 26.2℃
透明度 20m 20m 20m

6/6(2日目)

翌日飛行機に乗るので、2Dive!

  • コメント
    • サンゴの根の真上でホバリングができたので観察が超楽チンに
    • ミナミハコフグの幼魚が半端なくかわいい
    • おめでとう10タンク
(Dive9)竹富島南ジャガイモの根 (Dive10)竹富島南リトルクリーチャーズホーム
深度 13.7(AVE10.8)m 13.2(AVE11.4)m
潜水時間 48分 51分
気温 不明 不明
水温 29.2℃ 26.6℃
透明度 20m 20m

残念なのは島の北側のマンタスクランブルに波が出ていていけなかったこと、次こそは!

Ubuntu 8.04 LTS(hardy)にMySQL5.1をinstallする

はじめに

MySQLのパーティショニングとかQ4Mなどを試してみようと、Ubuntu 8.04 LTS(hardy)のMySQLのバージョンを確認したら、

mysql-server-5.0(5.0.51a-3ubuntu5.5) 

MySQLのマニュアルには5.1からの新機能とのことなのでバージョンをあげたいけれども、Ubuntuのパッケージを見ても無いっぽいので、いろいろやってみるテスト。

手順

本家にはない!こういう残念なときには、世界中のハカーにお願いするのが常識。LaunchpadのPersonal Package Archive(以下、PPA)にお世話になってみる。Ubuntu8.10で試している人がいるので、8.04でも動くだろうと思って試してみる。

1. /etc/apt/sources.list に以下を追記
deb http://ppa.launchpad.net/monty/ubuntu gutsy main universe restricted multiverse
deb http://ppa.launchpad.net/smurf/ubuntu gutsy main universe restricted multiverse
2. パッケージ情報更新
ubuntu% sudo apt-get update
ubuntu% sudo apt-cache show mysql-server-5.1

Package: mysql-server-5.1
Priority: optional
Section: misc
Installed-Size: 54168
Maintainer: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org>
Architecture: i386
Version: 5.1.22rc-2~ppa5
(以下略)

入っているっぽい!「This package includes the server and ndb-cluster binaries.」と書いてあるのでndbも今度試さなきゃ。

3. UpgradeとInstall
ubuntu% sudo apt-get upgrade
ubuntu% sudo apt-get install mysql-server-5.1

300個以上のパッケージのUpgrade。
1時間半ぐらいかかって mysqlのrootのパスワードの再設定を行って(といっても空にしたけど)インストール終了(`・ω・´)キリ!

ubuntu% mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.1.22-rc-Debian_2~ppa5-log Debian lenny distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

まとめ

  • Ubuntu 8.04 LTS(hardy)にはMySQL5.1を導入することができる
  • Ubuntuのパッケージリストに入っていないのでPPAにお世話になる(Launchpad最高)

【追記】Ubuntuのバージョンチェック

Linux Standard Base のファイル一覧を見てたら /usr/bin/lsb_release というバイナリが含まれているので、下記コマンドでバージョンチェックができるらしい...

ubuntu% /usr/bin/lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 8.04.1
Release:        8.04
Codename:       hardy

Ubuntuのバージョンチェック

これは完全な個人的メモ

RedHatとかCentOSあたりだとバージョンを確認するためには /etc/redhat-release を見ればよいんだけど、ってことはきっと /etc/ubuntu-release あたりだよなと思っていたら見事に違っていて /etc/lsb-release らしい。

ubuntu% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=8.04
DISTRIB_CODENAME=hardy
DISTRIB_DESCRIPTION="Ubuntu 8.04.1"

ちなみにlsbは、Linux Standard Baseらしい、へー。