| @技術/プログラミング

Rust 製の全文検索システム Tantivy を Ruby から使える Tantiny を導入したことを書いた。

結構手軽に使えるのだがやはり日本語のトークナイズ(形態素解析)ができないのでいまいちなところがあった。 Tantivy には lindera-tantiby というものがあって、 Lindera は kuromoji のポートなので、これを使うと日本語や中国語、韓国語の形態素解析ができる。 Tantiny に導入できないか試してみたが、自分の Rust 力では到底無理だった。

ちなみに関連記事の表示でも日本語の形態素解析は行っている。

MeCab に neologd/mecab-ipadic-neologd を組み合わせてナウな日本語に対応させつつ形態素解析している。

この仕組みを作ってトークナイズは Ruby で自前で行い、 Tantiny および Tantivy にはトークナイズ済みの配列を食わせるだけにした( Tantiny はトークナイズ済みのテキストを受け付けることもできる)。トークナイズを自前で行うことで辞書ファイルで拾いきれないような固有名詞もカバーできる。例えば 山と道 なんかは MeCab と mecab-ipadic-neologd にトークナイズさせると に分割されてしまう。自前のトークナイザーで単語として認識させていている。おかげで「山と道」をちゃんと検索できるようになっている

なお、自前のトークナイザーはこんなコードになっている。

class Tokenizer
  attr_reader :text

  class << self
    def run(text)
      self.new(text).tokenize
    end
  end

  def initialize(text)
    @text = text
  end

  def cleansed_text
    @cleansed_ ||= text.
      gsub(/<.+?>/, '').
      gsub(/!?\[(.+)?\].+?\)/, '\1').
      gsub(%r{(?:```|<code>)(.+?)(?:```|</code>)}m, '\1')
  end

  def words_to_ignore
    @words_to_ignore ||= %w[
      これ こと とき よう そう やつ とこ ところ 用 もの はず みたい たち いま 後 確か 中 気 方
      頃 上 先 点 前 一 内 lt gt ここ なか どこ まま わけ ため 的 それ あと
    ]
  end

  def preserved_words
    @preserved_words ||= %w[
      山と道 ハイキング 縦走 散歩 プログラミング はてブ 鐘撞山 散財 はてなブックマーク はてな
    ]
  end

  def nm
    require 'natto'
    @nm ||= Natto::MeCab.new
  end

  def words
    @words ||= []
  end

  def tokenize
    preserved_words.each do |word|
      words << word if cleansed_text.match?(word)
    end

    nm.parse(cleansed_text) do |n|
      next unless n.feature.match?(/名詞/)
      next if n.feature.match?(/(サ変接続|数)/)
      next if n.surface.match?(/\A([a-z][0-9]|\p{hiragana}|\p{katakana})\Z/i)
      next if words_to_ignore.include?(n.surface)
      words << n.surface
    end

    words
  end
end

preserved_words が手製の辞書だ。 はてなはてブ も辞書登録しておかないと MeCab だとバラバラに分割されてしまって検索できなかった。

難点としては記事更新後に自動でインデックスの更新が行われず、 cron によるバッチ処理でインデックス更新を行っている1。なので検索インデックスにデータが反映されるまでにタイムラグがある。 Tantiny でやれれば記事作成・更新時のコールバックとして処理できるのでリアルタイムに変更を検索インデックスに反映させることができるが、個人の日記なのでタイムラグありでも大きな問題にはならない。

本当は Tantiny で lindera-tantiby を使えるようにして Pull Request がカッチョイイのだが、とりあえずは自分は目的が達成できたので満足してしまった。 5 年くらい前から Rust 勉強したいと思っているが、いつまでも経っても Rust を書けるようにはならない。


  1. mecab-ipadic-neologd を VPS 上でインストールできず(めっちゃメモリを使う)、手元の Mac で Docker コンテナ化して Docker Hub 経由でコンテナイメージを Pull して VPS 上で Docker 経由で動かしている(その辺について書いてる記事: ブログのコンテナ化を試みたけどやめた) 

| @WWW

以前、以下の記事でこのウェブサイトへのアクセス元 User Agent について書いた。

そのとき Hatena::Russia::Crawler というのが謎だということを書いた。最近のアクセスログを見ても相変わらずこの User Agent からのアクセスが多い。またアクセス頻度も高く、同一の URL に対して何度もアクセスしている。

これはやはりはてなの名を騙った怪しいクローラーなのではないかと思い調べてみた。

まず Hatena::Russia::Crawler という User Agent からのアクセスの IP アドレスを調べてみたところ以下だった。

cat log/access.log | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f2 | sort | uniq -c | sort -nr
    434 remote_addr:52.68.0.227
    419 remote_addr:54.249.85.140
    417 remote_addr:54.92.97.59
    379 remote_addr:54.250.227.185

whois してみると AWS で運用されているものであることがわかるが、はてなのものかは断定できない。

もしこの IP からはてなブックマークやはてなアンテナなどの User Agent でのアクセスもあれば Hatena::Russia::Crawler ははてなのクローラーであると断定できるだろう。ということで調べてみたところこんな感じだった。

zcat -f log/access.log* | grep -E 'remote_addr:(52\.68\.0\.227|54\.249\.85\.140|54\.92\.97\.59|54\.250\.227\.185)' | cut -f13,2 | sort | uniq -c | sort -nr
  16687 remote_addr:54.250.227.185      useragent:Hatena::Russia::Crawler/0.01
  16448 remote_addr:54.92.97.59 useragent:Hatena::Russia::Crawler/0.01
  16370 remote_addr:54.249.85.140       useragent:Hatena::Russia::Crawler/0.01
  16272 remote_addr:52.68.0.227 useragent:Hatena::Russia::Crawler/0.01
     73 remote_addr:54.249.85.140       useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     60 remote_addr:54.250.227.185      useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     56 remote_addr:52.68.0.227 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     50 remote_addr:54.92.97.59 useragent:HatenaBookmark/4.0 (Hatena::Bookmark; Scissors)
     31 remote_addr:54.92.97.59 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.250.227.185      useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     31 remote_addr:54.249.85.140       useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     26 remote_addr:52.68.0.227 useragent:Hatena::Fetcher/0.01 (master) Furl/3.13
     19 remote_addr:54.92.97.59 useragent:Hatena::Scissors/0.01
     19 remote_addr:54.250.227.185      useragent:Hatena::Scissors/0.01
     16 remote_addr:52.68.0.227 useragent:Hatena::Scissors/0.01
      9 remote_addr:54.249.85.140       useragent:Hatena::Scissors/0.01

なんと、 IP アドレスで検索してはてなのその他のクローラーもヒットしてしまった。つまり Hatena::Russia::Crawler ははてなのクローラーということだ。

ただしググっても一切情報が出てこない。 Hatena::Russia::Crawler で検索してトップヒットするのは自分のブログだ。

改めて Hatena::Russia::Crawler による直近 30 日間のアクセス状況を調べてみるとこんな感じだ。

zcat -f log/access.log* | grep 'useragent:Hatena::Russia::Crawler/0.01' | cut -f5 | sort | uniq -c | sort -nr
  15697 request_uri:/index.atom
   9913 request_uri:/2022/04/20/integrate-charts-category-with-select-boxs
   9373 request_uri:/2022/05/04/reputation-and-interpretation
   8422 request_uri:/2022/05/11/fly-to-kamikochi-from-fukuoka
   7716 request_uri:/2022/05/16/using-tantivy-over-tantiny
   5906 request_uri:/2022/04/17/quit-using-hey
   5139 request_uri:/2021/12/29/thoughts-on-manga-subscription
   1308 request_uri:/2021/12/13/keep-a-stack-books-whether-reading-them-or-not
    787 request_uri:/2022/06/23/each-entry-title-should-be-marked-up-with-h1
    741 request_uri:/2021/12/13/keep-stack-books-whether-reading-them-or-not
    456 request_uri:/2022/06/24/if-you-feel-apple-musics-recommendation-is-awful
    100 request_uri:/2022/06/14/thoughts-on-hatena-bookmark
     46 request_uri:/2015/12/07/thoughts-on-rural-life
     46 request_uri:/2015/12/02/thoughts-on-t-on-t
     46 request_uri:/2015/12/02/thoughts-on-christmas-song
     45 request_uri:/2019/12/02/stop-drinking-outside-frequently
     16 request_uri:/2020/11/08/where-i-went-in-2019
     11 request_uri:/2015/12/05/omm-writer-music-is-nice-to-listen-to-while-writing
      5 request_uri:/2022/05/04/the-golden-maintenance-week
      2 request_uri:/2022/06/24/
      2 request_uri:/2022/06/24

index.atom はフィードの URL なので除外するとして、特定の記事に対して数千回もアクセスがある。 30 日間で 9000 回ということは一日あたり 300 回だ。 1 時間あたり 12.5 回である。何のためにこんなに高頻度でクローリングしているのだろうか。

とここまで調べたところほかの Bot 系アクセスはどうなのかと改めて User Agent 毎のアクセス数を調べてみたらこんな感じだった。

zcat -f log/access.log* | cut -f13 | sort | uniq -c | sort -nr | head -10
 124894 useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
  65794 useragent:Hatena::Russia::Crawler/0.01
  58274 useragent:Ruby
  31493 useragent:Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Mobile/15E148 Safari/604.1
  29454 useragent:Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)
  21492 useragent:Tiny Tiny RSS/21.11-7cfc30a (https://tt-rss.org/)
  20351 useragent:Slackbot 1.0 (+https://api.slack.com/robots)
  18765 useragent:Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)
  18395 useragent:Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)
  17942 useragent:Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

bingbot からのアクセスの方が Hatena::Russia::Crawler からのアクセスの 2 倍近くあった。ただし bingbot は検索エンジンのクローラーらしく、サイト全体をまんべんなくクローリングするような挙動で、特定の URL に一ヶ月間で数千回アクセスするような感じではない。

zcat -f log/access.log* | grep 'useragent:Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)' | cut -f5 | sort | uniq -c | sort -nr | head -25
    571 request_uri:/robots.txt
    352 request_uri:/
    205 request_uri:/category/misc
    160 request_uri:/2007/01/13/732
    156 request_uri:/2005/10/28/129
    150 request_uri:/2009/03/23/1010
    148 request_uri:/category/music
    146 request_uri:/archives
    144 request_uri:/category/www
    143 request_uri:/2016/07/
    143 request_uri:/2009/08/31/1074
    139 request_uri:/2010/07/05/1140
    138 request_uri:/category/photo
    138 request_uri:/2009/02/
    137 request_uri:/2006/09/09/658
    136 request_uri:/tags/netatmo
    136 request_uri:/2010/07/17/1145
    136 request_uri:/2006/07/23/611
    135 request_uri:/2014/03/
    134 request_uri:/?page=32
    134 request_uri:/2007/02/09/747
    133 request_uri:/category/shopping
    133 request_uri:/2021/07/26/how-to-get-to-kamikochi-from-fukuoka
    133 request_uri:/2011/11/03/finally-got-hhkpro2
    132 request_uri:/2006/01/

Hatena::Russia::Crawler は同一 URL に数千回もアクセスして何をしているのだろう? 謎は深まるばかりだ。

| @技術/プログラミング

ブログ過去記事の閲覧 UI にはこだわりがある。これまで何度か記事を書いた。

このブログの維持管理で一番時間を割いているのが Archives ページだ。しかしアクセスログを見ると自分以外はほとんど利用していない。完全に自己満なのだが、過去の自分を振り返ることができてとても自分には有意義なページだ。

過去記事を振り返るときには検索をしたくなる。タイトルのみであればページ内検索で探せるが、やっぱり本文込みで検索したい。 Lokka の検索はあるが、検索結果ページは 7 件ずつ(この値はカスタマイズできる)表示で全文表示される。自分は検索キーワードに関する記事が存在するか知りたい訳ではない。著者なのでキーワードに関連する記事があるかないかくらいわかってる。じゃなくて過去の自分がいつ頃どの密度でそのトピックについて書いていたかを知りたいのだ。

タグやカテゴリーで絞り込む手もある。しかしカテゴリーやタグは理想的な分類ではない。二つのカテゴリーを横断するような記事があるし、タグは設定し忘れていることが多い。全文検索が一番頼りになる。

SQL で全文検索的なことをやろうとするとパフォーマンスが良くないだろう。やっぱり全文検索システムが欲しい。

Tantivy と Tantiny

とはいえ、個人のブログで全文検索エンジンを導入するのはしんどい。確かに Apache Solr や Elasticsearch を個人ブログに入れるのはきつい。もっと手軽に使えるものはないか探していて、 Rust 製の全文検索システム Tantivy と、その Ruby クライアントの Tantiny を発見した。

これがめっちゃ簡単で昨日数時間サンデープログラミングをして導入できた。システム環境に適合するビルド済みのバイナリが GitHub にあれば Rust 環境のセットアップすら必要ない。 Gemfile に gem 'tantiny' と書いて bundle install するだけで使えてしまう。

うまくいかなかったもの

最初、同じ Rust 製で Wasm までセットで提供してくれる tinysearch を試した。 JSON 形式で全ファイルを書き出すだけで使えるやつだ。しかし残念なことに日本語では全く使えなかった。自然言語処理をやろうとしていてあるあるのパターンだ。日本語は MeCab などでトークナイズしてやる必要がある。

デフォルトのトークナイザーでもそこそこに優秀な Tantivy

Tantivy にもトークナイザーをカスタマイズできる仕組みはあるが、標準の Simple Tokenizer でもそこそこ精度が高い。固有名詞にちょっと弱いが、辞書ファイルがないので仕方ないだろう。

個人ブログでも全文検索できる時代

このブログは個人ブログだが、画像のリアルタイムリサイズサーバーを動かしている(おかげで S3 の転送量が安くて済んでいる)し、 TF-IDF で関連の高い記事も表示している。それに加えて全文検索まで入れてしまった。こういうのは大手のブログサービスを利用しないと使えない機能だったが、 OSS と新しいプログラミング言語( Go や Rust )のおかげで個人でもそこそこのスペックのサーバーでこれらを利用することができるようになってきた。 MovableType でサイトを構築していた時代から何も進歩していないようで実はとても進歩している。こういう文化の灯火が消えないようにしていきたい。

| @技術/プログラミング

松浦福島初崎海岸のドクロのような岩

Mac の Homebrew のライブラリ群を久しぶりにアップデートした。 tmux と fish のバージョンを上げたら tmux が動かなくなってめっちゃ焦った。いろんなものを同時にバージョンアップするとどっちに原因があるのかわからなくて困る。結局、 brew reinstall tmux で事なきを得た。

次に VPS の Ubuntu のバージョンが古くなっていたのでアップグレードした。ついでにいろいろ気になってたところ(ログローテートがうまく動いていないところとか Nginx の設定ファイルの配置など)を直して回った。

OS のアップグレードに伴って Ruby の再インストールが必要になり、 Ruby 再インストール後にアプリケーションを deploy しようとすると mimemagic gem が yank されていたりでライブラリのアップデートが必要になった( MimeMagic は脆弱性があって Mercel に変更しないといけなかったが、変え忘れていたところがあった)。これによって引きずられるように gem のアップデートが必要になり、うっかり capistrano3-puma を v5 系にしたところ、 puma の起動ができなくて困った。どうも puma の v5 ではデーモン化オプションが削除されているようで、 capistrano で puma を再起動させたりはできないようだった。いろいろ面倒くさそうなので capistrano3-puma も puma も v4 系に固定して凌いだ。

Archives ページの npm パッケージも古くなってたので、 React や React Router 、 Webpack 、 Babel など各種ライブラリのバージョンを上げた。 React Router の v5 系から v6 系へのアップデートは結構大変だった。以下を読みながらやった。

withRouter などは React Router から機能が消えるのでそれをラップする関数を自分で書いてコンポーネントに mixin するような感じだった。以前に比べたらマイルドになっているとはいえ、 JavaScript 界隈はアップデートについて行くのが厳しい。

職業プログラマーじゃなくなったので開発環境の維持管理などがおろそかになりがちだし、 Vim やシェルのショートカットを忘れてしまうことがある。 Vim やシェルの操作は特殊技能のようなものなので忘れるともったいない。たまに触って忘れないようにしておきたい。

そういえば温かくなって庭の雑草が伸びてきたので庭の草むしりもやった。ゴールデンメンテナンスウィークだ

| @技術/プログラミング

いろいろスパム対策は行っているもののやはりまだスパムが届くので NG ワードの設定を簡単に行えるようにした。こんな感じ。

NG ワード設定

これまで一つのテキストフィールドにカンマ区切りで入力しないといけなかったのを、フィールドを分けて単語ごとに入力できるようにした。

モダンなやり方はしてなくて全部サーバーサイドの Ruby でやってる。動的に新規登録フィールドを増やしたりはできない。新規登録したいときは都度都度フォームを保存する必要があるが、十分速いので実用上は全く問題ない。

同様に、スパマーの餌食になっている過去記事のコメント欄を閉鎖する機能も便利にした。

コメント欄を閉じる記事の設定

仕事では全然プログラミングしていないので久々にコードを書いた。

| @雑談

2020 年、時系列でふりかえるとこんな感じだった。

できたこと

ハワイ旅行

ハワイで最近の SUV に乗って Car Play に感動した。車の買い換えを検討するきっかけになった。ハワイ楽しかったのでまた行きたい。

Akaka Falls Cadillac XT4 Volks Wagen Atlas

ブログの ActiveRecord 化

脱 DataMapper できた。

ブログ UI 刷新

トップページの見た目、アーカイブページにグラフを表示するようにした。ブログ記事を書いてきた実績が可視化されるとやる気が出る。

ウッドデッキの塗り替え

サンドペーパーをかけて塗り直した。

ウッドデッキ塗り直し

庭で焼き鳥

バーベキューに飽きて焼き鳥おじさんになった。

焼き鳥

ハンモック入門

ウキグモ Light & ウンカイ Light 購入。

ハンモック

UL クッカー購入

アルコールストーブ、チタンカップ、メスティン、アルミフライパンなどなど。

アルコールストーブ

山で肉まん・焼売・炊飯

カップラーメンとおにぎりからの卒業。メスティンでの炊飯はめちゃ美味くて感動する。

焼売 メスティンで炊いた米でたまごかけご飯

車の買い換え

スバルインプレッサから Jeep Compass へ。ハワイ旅行でアメ車の SUV に乗って車に対する考え方が変わり、車を買い換えたくなった。国産車はディーラーとの交渉がわずらわしすぎて値引き交渉やオプションがほとんどない外車になってしまった。アメ車はアホみたいにガソリン喰って笑える。プラスチック部品の質が悪い(ゴルフ 2 を思い出す)。

Jeep Compass

ソロで脊振山・金山を縦走

2 年ぶりのソロ縦走。盛夏にソロで 20km 歩いてつら寂し楽しかった。

脊振山 猟師岩鼻

腕時計の買い替え

Pebble Time Round から Apple Watch へ。

Apple Watch

朝駆け登山

明け方前に出発して日の出を山頂で見るというやつをやった。

天山から見る日の出

友だちとキャンプ

家族以外とのキャンプは初めてだった。複数の男手がある状態でのキャンプは楽だった(力仕事を分散)。食事は taketin さんが作ってくれて超楽だった。

ピザを焼く taketin さん

ジョギング再開

年末から走るようになった。Apple Watch でリング閉じたい病にかかった。走るときに聞くのは Podcast よりも音楽の方が良い( Podcast だと気が散る)。

一切れ 3000 円の肉を焼く

肉屋で ¥880/100g のリブロースを厚さ 3cm でカットしてもらった。良い肉を低温調理すると柔らかくなりすぎてブヨブヨになった。和牛は普通に焼いてうまくなるように育てられてるのかも知れない。

一切れ 3000 円の肉

Rebuild サポーターに登録

RAW エピソードと Extra エピソードが聞けて全文検索できるようになった。全文検索できると N さんが昔言ってたあの話をもう一回聞きたいというときに便利。サポーター向けの機能差別はもうちょいあってもよいのではと思ったけど( Rebuild を聞くに際してお金払わなくても困ることがない)、実利を得るためというより支援のためにみんな入っているのかな。

できなかったこと

こっちは箇条書きで。

  • Lokka の ActiveRecord 化を master に merge
    • あと一歩のところで燃え尽きてしまった
  • iOS / Mac のプログラミング
    • 毎年やりたいと思ってやれない
    • Xcode がでかすぎる&重すぎる
  • Rust の勉強
    • ちょびっとやってたけど難しくて途中でやめてしまった
  • 英会話の勉強
    • 会社の制度でレアジョブを始めたけどなかなか時間を捻出できない
    • 休みには休みたくなってしまう
  • ブログを 100 記事書く
    • 11 月に重めの翻訳記事を書いて燃え尽きてしまった
  • 庭の屏の塗り替え
    • ウッドデッキの流れで塗り替えたかったが梅雨入りして夏が来て冬になってしまった
  • 体重の維持
    • 前回リモートワークをしていたとき( Kaizen Platform 時代)はリモートワークしながら減量できたのに今回は太ってしまった
  • ソロでハンモック泊
    • ハンモックを買ったはいいが、ソロで山に泊まりに行けていない
  • 高い山に登る
    • 今年は標高 1500m 以上の山(ハワイーの Pu'u Kalepeamoa は除く)に登っていない
    • 火山規制が解除されたので阿蘇高岳に登りに行きたかったが、休日にソロでの外出はなかなか難しい
    • 年に一回は久住か祖母山、九州脊梁の山(標高 1700m 程度)に登りたい
  • 仕事でめざましい成果を残す
    • いつも通り

いつものようにあまりパッとしない一年だった。

| @Mac/iPhone

"Your Computer Isn't Yours" という記事が先週バズってた。

概略を説明すると、 Catalina の頃から Apple が Mac ユーザーのアプリ起動ログを勝手に収集していたが、 Big Sur の公開日にログ集約サーバーがダウンしてしまい、そのせいで Mac を使えなくなる人が続出して問題が発覚したというもの。 Rebuild の Episode 288 で触れられているので興味がある人は聞いて下さい。

この記事については日本語の翻訳もあってはてブで 500 ブックマークくらいついていたが、どうも機械翻訳されただけのようだったし、一部訳が違うのではと思われるところがあったので自分でも訳してみた。訳を原著者の Jeffrey Paul 氏にメールで送ったので恐らくそのうち本家に日本語訳が追加されると思う。

Your Computer Isn't Yours

2020-11-25 9:16 追記

日本語訳追加してもらいました。


起きていることをまとめると以下のような感じだ。

  1. Apple は Mac ユーザーのアプリ起動データを IP 付きで Apple のサーバーに集めている(ログ送信)
    • 各アプリの署名有効期限チェックやマルウェア対策のためということになっている
    • Mac から Apple への通信は暗号化されていない
      • ISP や CDN ( Akamai )、ネットワークを盗聴している他人が内容を確認可能
    • この通信はユーザーが自分の意思で無効化できない(「Mac解析を共有」をオフにしても送信される)
  2. Mac (特に Big Sur でしか動かない Apple Silicon Mac )を使いたければ利用ログ送信を甘受するしかない
    • Big Sur から、上述のログ送信や Apple 製のアプリは VPN やファイヤウォールを無視するようになった
    • OS の挙動を変更しようとすると Mac が起動しなくなる
  3. iCloud Backup は iMessage の秘密鍵も一緒にバックアップするので Apple がメッセージの内容を読むことができる
    • 自分自身が iCloud Backup 利用していなくても、メッセージの送信相手が iCloud Backup を使っていると自分が送ったメッセージが iCloud 上に保存される
  4. Apple はプライバシー保護を売りにしながらユーザープライバシーをなおざりにしている
    • iMessages/iCloud Backup のバックドアを放置している
    • 過去にアプリ開発者には HTTPS を強制しながら自分たちは OCSP の通信を平文で行っている
    • ログ送信の件について対応を発表したが、対応時期を明確にしていない

その結果、以下のような状況に陥ることが懸念されている。

  • Apple が集めている情報は NSA や FBI に筒抜けになる
    • Apple はアメリカ軍の諜報機関や FBI にユーザーログデータなどの閲覧を令状なしで認める協定を結んでいる
    • iCloud Photo や iMessage の内容を Apple だけでなく軍や FBI も見られるようになっている
  • ユーザー保護を隠れ蓑に Apple が力を増大させる
    • マルウェアから守る、を大義名分にして、ユーザーがどのアプリを動かせるかを Apple がコントロールできる可能性がある
    • 原理的には Apple が気に入らないアプリを起動できなくしてしまうことが可能

モバイルアプリの利用状況の収集は多分いろんなアプリがやっている。 Mac で Apple が集めている程度以上の情報を集めているアプリも多いだろう(位置情報を取得しているアプリなど)。なので最初この件については過剰に反応しすぎなのではないかと思っていたが、よくよく考えてみると自分の感覚の方が麻痺していたのかもしれない。アプリの利用履歴を IP アドレス付きで送るということは、どこで何をしているかがアプリ開発者に筒抜けだ。そしてそのログを公権力が自由に閲覧可能だとしたらいい気持ちはしない。

アプリと Apple の場合で決定的に異なるのは、アプリはそのアプリが起動している間(あるいはバックグラウンドでのログ送信を許可されている間)だけログを送信するが、 Mac に関して言うとずっーっと起動しっぱなしで使い続けるものなので、ログデータからユーザーの行動履歴・生活様式がわかってしまう。地図アプリで検索した場所の情報も送られていたということなので、 Jeffrey Paul 氏が書いているように、その人がこれから行く予定の場所もわかってしまう。

GDPR や様々なプライバシー保護は、アプリを作りサービスを運営する側としては正直厳しいなと思うところはあるけど、 Apple がアメリカ軍と結んでいる PRISM のような取り決めが存在すると、様々な個人情報が政府機関に流れてしまって、アメリカのサスペンスドラマのように個人の位置情報を携帯の使用履歴からいとも簡単に割り出せるようになってしまう。それはやはり恐ろしい世界だ。

プライバシーの侵害のみならず、プラットフォーマーである Apple の匙加減次第で、ユーザーが使えるアプリが決まるという状況も好ましくない。たびたび iOS の App Store で起こる Apple の恣意的な審査基準改変などはその一端だ。 Hey の件で Apple とやり合った DHH は痛烈に Apple を批判するとともに、かつて邪悪な Microsoft に対抗するための救いとも言えた Apple が以前の Microsoft 以上に邪悪になってしまったのが嘆かわしいと Twitter に書いていた。学生の頃、 Mac を広める活動をやって大学のクラスの半分の同級生のラップトップを Mac にしたというエピソードや、 Rails の開発でも Mac を激推ししたという話は胸熱だった。応援してきた Apple が Evil になってしまい、人一倍残念に思っているのだろう。

Apple はかつて "The computer for the rest of us" というコピーで Macintosh を宣伝していた。しかし今日、 Mac は彼らのコンピューターになってしまったのだ。