たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
As already announced at changelogs, an information disclosure vulnerability was found in Tree Style Tab 2.0-3.0.13 and Multiple Tab Handler 2.0-3.0.6.
Technically detailed description is already published at a GitHub issue. It was a spec bug around APIs for communication with other addons. In short: the API design was not matched to the security model of WebExtensions API itself.
tabs.Tab
objects got via WebExtensions API with their own permissions, and they contained full tab data from both regular and private windows, including title, URL, and FavIcon, without any confirmation. To be honest, I forgot that those properties are not accessible without tabs
which is a non-default permission.browser.runtime.sendMessage()
, and any addon can call browser.runtime.sendMessage()
with no special permission.Currently there is no report about actual such an "attacker" addon. This vulnerability was found by a self-check.
However, it existed for a long time (from initial releases of their versions 2.0 at 2017), and might be known axiomatically with public API documents - attackers might find it out when he read the API spec carefully. If you found any actual attacker example, please tell them me.
I already contacted to community managers of Mozilla, so I will update this announcement if any progress.
Why I did such a terrible mistake? I think there are mainly two reasons.
First, TST and MTH were originally developed as XUL addons.
In old days, all XUL addons had same permissions: they were allowed to access any data on Firefox. Old API of these addons were also designed on the policy same to XUL addons themselves - there was no concept like permissions for each client addon.
On the other hand, there are some known concepts of WebExtensions: isolated namespaces and secure permission model based on declarations. So users just need to be careful about safety for each addon simply. And, there is one more self-evident (but I missed that) fact: my addons TST and MTH may be allowed to read sensitive data, but other API client addon may not.
This means that it was required that updating the concept of my APIs following to the security model of WebExtensions API itself. But regrettably I forgot to do that - I concentrated to migration of their features and missed this point. As the result, TST and MTH were became like a bigmouth: they got sensitive information out of Firefox and blabbed to others carelessly.
Second, I misunderstood the power of the tabs
permission.
The permission name tabs
looks like required to do anything around tabs, for example getting a list of tabs. So, because APIs of TST and MTH require id
of tabs as their parameter, I thought that "client" addons must have the tabs
permission and there was no problem to return full tab information.
But that was misunderstanding. Actually, many WebExtensions API around tabs are callable regardless the addon has no tabs
permission, and the permission just appends extra sensitive properties to tab objects. I added tabs
to required permissions on very early days of my WebExtensions addon development experience and it was left there for a long time, thus I had no chance to correct such a misunderstanding. Possibly I might specify tabs
permission for other addons even if it is unnecessary.
Please remind my mistake as a lesson, if you plan to design callable API for other addons. You need to be careful to treat any data got via WebExtensions API as sensitive, as:
permissions
in manifest.json
. Don't put needless permissions, and keep it mind that you should make effort to minimize the list of permissions
anytime.既にTwitter等でお知らせしていますが、ツリー型タブのバージョン2.0~3.0.13とマルチプルタブハンドラのバージョン2.0~3.0.6に脆弱性がありました。
詳細な説明はGitHubのissueに日本語でも記載していますが、端的に言うと「他のアドオンと連携するために独自に提供していたAPIの仕様がガバガバだった」という事になります。
tabs.Tab
のオブジェクトに基づいて、それとの互換性を保つようにしていたため、その中に無条件でタブのタイトル、URL、アイコン、およびプライベートウィンドウのタブの情報が含まれていた。これらの情報が、本来は取得するために特別な権限が必要な物であるという事を失念していた。browser.runtime.sendMessage()
というWebExtensions APIを使って呼び出す物だが、browser.runtime.sendMessage()
の呼び出しには特別な権限は要らない。一応、この「脆弱性」を使って悪さをするアドオンとしてこういう物が実際にある、というような報告はまだ受けていません。あくまで、作者が自主的に行った仕様の再チェックで脆弱性が見つかったという事になります。
が、「誰も気付かないような所、仕様の穴を突いたイリーガルな使い方をすると情報を盗み出せる」というような物ではなく、技術情報としてドキュメントも公開しているAPIを堂々と使って、WebExtensionsのアドオンごとの制限を突破して情報を取得できる、しかもその情報自体は実は2017年のバージョン2.0リリースの時から1年半以上もの間ずっと公知だったという、我ながら書いていて情けなくなるお粗末な状況なので、この脆弱性を利用した悪意あるアドオンが既に存在していても、全くおかしくはないと思っています。
ということで、もしそのようなアドオンを見つけた方がいらっしゃいましたら、お手数ですがどうかタレコミをお願いします。
折良く(?)、Mozillaのアドオンコミュニティの担当者の方からおすすめアドオンの件について連絡を頂いたので、ついでにこの件についても相談してみました。何か進展があったらまた告知すると思います。
それにしても、何故こんなにお粗末な事をやらかしてしまったのか。理由はいくつか考えられます。
まず1つは、XULアドオン時代の設計思想を引きずってしまっていたこと。
元々、XULアドオン時代にはFirefoxのアドオンはすべての情報にフルアクセスというのが当たり前でした。なので、TSTやMTHのAPIには、呼び出し元ごとに返す情報に差を付けないといけないという考えが全くありませんでした。聞かれた事はなんでも返していい、何故ならどうせ呼び出し元のアドオンだって、それらにアクセスしようと思えばいくらでもできるんだから。これがXULアドオン時代の考え方でした。
他方、WebExtensionsでは、各アドオンは事前に許可された範囲の情報しかアクセスできないので、ユーザーは各アドオンの権限だけを気にすれば良いという事になっています。この事ばかりが強く印象に残っていたことと、とにかくXUL版から機能を移植するという事にばかり気を取られていたために、アドオン同士の間ですらもアクセスできる情報の範囲に差があるという事が、頭の中からすっかり抜け落ちていたのだと思います。
「アドオン同士の権限に差がある」というWebExtensionsの世界に合わせるには、TSTやMTHのAPIにもその考え方を反映しないといけなかったんですね。自分のアドオンが正当な手順でWebExtensions APIから入手した情報は、相手のアドオンにとっても同様に正当な手順で入手できる情報だ、とは限らないのです。それを忘れて呼び出し元の求めに応じてなんでも返してしまっていたというのは、「内緒にするから教えて」と言って教えてもらった情報を、他人にホイホイ言いふらすようなものです。実に嘆かわしいです。
2つ目の理由は、permissions
で宣言する権限の影響範囲を正しく把握しきっていなかったこと。
tabs
という権限の名前からはいかにも、タブに関する事なら何をするのにも、例えばタブの一覧を取得するのにすらも必須であるような印象を受けます。TSTやMTHのAPIを呼ぶには呼び出し側のアドオンがタブのIDを知っている必要があり、タブのIDを知っているなら当然tabs
の権限も持っているはず、ならタブのプロパティ全部渡しても問題無いはず(どうせ呼び出し側のアドオンが自分でも同じ情報を取得できるんだから)。というのが、これらのAPIを作った時点での自分の認識だったのだと思います。
しかし実際には、tabs.query()
などのWebExtensions APIはtabs
の権限無しでも呼ぶ事ができます。tabs
/activeTab
の権限の有無は、タブの一覧を取得できるかどうかではなく、返されるタブの情報にタイトルやURLなどのセンシティブな情報が含まれるかどうかという点にだけ影響します。TSTやMTHをWebExtensionsで実装するにあたって、まだWebExtensionsの仕様への理解が浅かったかなり初期の時点でtabs
の権限を設定したきりだったために、この勘違いがずっと正されないまま今に至ってしまっていたのでしょう。他のアドオンを作る時にも、自分はひょっとしたらtabs
の権限が不要なのに要求してしまっているという例があるかもしれません。
今回のことから得られた教訓は、以下のようにまとめることができると思います。
permissions
には列挙する。僕のように「他のアドオン向けのAPI」を提供するアドオンを作ろうと思っている方は、どうか僕と同じ過ちを犯さないように、他山の石として下さい……
自分は「ご苦労様」というフレーズが「目上の人に使うのは失礼な言葉だ」「代わりに『お疲れ様』なら言ってもいい」と言われるようになった過程を見てきた世代の人間なので、「お疲れ様」が今「目上の人に使うのは失礼な言葉だ」と言われるようになっているという話を見かけて、まあ驚きましたね最初は。
「ご苦労様」が咎められていた頃にも「そもそも、目上の人に『ご苦労様』と言う例は昔からあった」とか色々反論は目にしましたが、結局みんな馬鹿馬鹿しいとは思いつつも、それで失礼だと言われたら怖いとビビって「ご苦労様」を目上の人には使わなくなったと思うので、「お疲れ様」もそのうちみんなビビって使わなくなるのかもしれません。
捏造マナーを広めてマッチポンプで仕事を作り出す失礼クリエイター(自称「ビジネスマナー講師」)に踊らされるのは癪だなあと思いつつ、しかし、お疲れ様もご苦労様も目上の人に言うのは失礼だというのは案外当を得ているのではないか?という気がする部分もあります。
というのも、「お疲れ様」が目の敵にされるようになった時にも「それは目上の者が目下の者の労をねぎらう時の言葉だからだ」と説明されていて、今回の「お疲れ様」でも同様の言われ方をしているようなので、そもそも「労をねぎらう」というのが「上から目線」の行為という事なのではないだろうか、だとしたら、目下の側からねぎらいの言葉が発される事自体が失礼扱いされるのは致し方ないのでは、と思ったのですね。
現代で「お疲れ様です」が発されるのってどういう場面なんでしょうか。「労をねぎらう」と一言で言ってしまっているケースでも、分析してみると実は色々なコンテキストがあるんじゃないでしょうか。
相手が労を割いてくれたという事だと、「ありがとうございます」という表現がより適切な気がします。
相手が尻拭いをしてくれたという事だと、「ご迷惑をおかけして済みません」の方が適切に思えます。
自分の関係ない所でその人がした事に対して、何も言わないのは失礼だから何か言いたいという時は、「素晴らしいお仕事です」とか「敬服致します」とか言える気がします。
見るからに疲れている様子なら、「お疲れのご様子なので今日はどうぞお帰り下さい」とかなんとか。
すれ違いざまの挨拶だと、その日の初回の遭遇だったら「おはようございます」「こんにちは」「こんばんは」が適切な気がします。2回目以降の遭遇では、どうなんでしょう。自分は「会釈」「黙礼」でいいと思いますが。ちなみに、最近読んでる「総務部総務課 山口六平太」では、典型的な日本型大企業の中で平社員が社長に遭遇したという場面では平社員が黙礼するだけという描写が多い印象があります。
こうして改めて「お疲れ様」「ご苦労様」の言い換えを考えてみると、他の言葉がより適切な場合もあるし、そもそも適切な・しっくりくる他の表現が無い場面もある、という気がしてきました。
「ご苦労様」って、かなり広い場面で使えるユニバーサルな言葉という気が僕はするのですよね。「それさえ言っておけばまあ大丈夫」というカテゴリの言葉というか。語彙力が無いと、それだけで全部済ませたくなっちゃうというか。だとすると、個別のコンテキストに応じた適切な言葉の使い分けを面倒臭がって、万能のフレーズ1つであらゆる場面を済ませてしまう怠惰さは、言われた相手の側にするといい気がしない、というのは一理ある気がします。少なくとも自分は、「自分のためにわざわざありがとうございます」「自分の不始末でご迷惑をおかけしてすみませんでした」等が適切な場面で「お疲れ様です」と言われたら、「なに他人事みたいに言うてんねん」とイラってなりそうです。「お疲れ様」が失礼となるケースがもし現実にあるとしたら、そういうケースが該当していそうな気がします。
そうでなく、しっくりくる表現が他に無いから「お疲れ様」が使われているというケース、挨拶やメールの書き出しのような場面が問題だとするなら、そもそも「ねぎらいのフレーズ」を無関係の場面に流用したのが間違いだった、ということはないでしょうか。言った側は「流用したフレーズを以て挨拶しただけ」のつもりが、相手はそれを流用ではなく本来の意味の使われ方すなわち「目上の者が目下の者に対して言う言葉」と捉えたために、失礼と感じられた、という事だったりしないでしょうか。
だとしたら、もういっそのこと、既存の言葉を流用しないでその場面に適した言葉を新しく作った方が建設的ではないでしょうか。例えばこんな感じで。
「ランダム 文字列」で検索したら任意の文字数のひらがなの文字列を自動生成できるページが見つかったので、これで作った文字列を造語として流行らせてみると面白いのではないかという気がしています。社内で流行らせた結果、うっかり社外の人にまで使ってしまうとどうなるか分かりませんが……もしかしたら案外世間で流行るかもしれないですよね。「拝承」みたいに。
僕がとある人にあまり良い印象を持っていない事の理由の1つに、商業媒体で連載の無告知中断を2回もしていて、2つ目は中断から数年経過しているのに自己紹介ではそれを現在進行形の連載としてアピールしており、自分のような第三者視点では「最初のは苦労して連載しても紙媒体でバズらなくて旨味が少ないと思って切ったのかな、次のもマンガ家という肩書きが手に入った後は放置ということなのかな」と見えているから(いや、その人にはその人の事情があって、自分は知らないだけでちゃんと双方で話の付いてる事なんだろうとは思うのですけれど)……というのがあるんですが、そういう風に他人の事をどうこう咎められる資格が自分にあるのかというと、自分の方こそ酷い不義理をやらかしているのですよね。
そういう仕事関係の不義理の中でも自分の中で最大の物は、フォクすけブログで1回か2回やったきりでぶん投げっぱなしにしてしまったブラウザの歴史に関する「連載」だと思ってます。
今から12~13年前。Mozilla Japanに半常駐でマーケティング関係のお手伝いをしていた頃、フォクすけというファンシーなキャラクターを掲げて「見た目ゆるく、でも中身は実用性高く」という意気込みでコンテンツを充実させていこうと思っていた僕は、フォクすけのブラウザ歴史年表を作るために色々調べて知識が増えた事に驕って、「Firefoxの他に無い価値の1つはその歴史にあると言えるはず。Webブラウザとインターネットの歴史をMozillaを軸に語ると面白いのでは?」みたいに考え、そのネタでドキュメンタリー風に連載をやってみますよ!と大言壮語をぶちかましたのでした。単発の技術解説記事や日経LinuxでのOpenOffice.orgの連載などで文字書きの経験はしていたので、まあできるでしょ、と思いまして。
で、いざ書き始めてみたのですが、ところがこれが全然書けないんですよ。当然です、取材もせずに数冊本を読んだ程度のカウチポテトで、生の体験をしていない僕ごときが、自分以外の視点で歴史を魅力的な読み物として書ける訳が無いんですよね。「誰々がこの時、こう言った」みたいなヒキの強いフレーズ、出てくる訳が無いんです。だってその場に居合わせてない、知らないんだもの。ロクな取材もしてないんだもの。
はっきりと〆切を設定した訳でもなく、また、依頼された訳でなく自分で言いだした事で、自分の気が向いたら書ける時に書きますくらいの表明の仕方だけに留めるという卑怯な逃げを打っていた事もあって、「なかなか筆が乗らないンすよね……」とグズグズしているうちに<ruby>一月<rt>ひとつき</rt></ruby><ruby>二月<rt>ふたつき</rt></ruby>と日は過ぎていって、気が付けばもう何の宣言もなくずうっと放ったらかしという訳です。
趣味の同人活動ならまだいいですよ、ぶん投げた所で自分の信用が損なわれるだけだから。でも仮にも仕事として始めた物でそれをやっちゃう訳ですよ。読者に対する裏切りであるだけでなく、「半常駐でマーケティングのお手伝いをする」という仕事の直接のお客さんであるところのMozilla Japanさんに対する裏切りでもあった訳ですよ。酷い、全く酷い。
仕事のやらかしでは他にも、シス管系女子の連載で原稿を落とした事が、この8年間で1回だけありました。設定された〆切をぶっちぎるのが常態化、校了ギリギリまでかけてやっと納品、という綱渡りを繰り返しているうちに、どうしても間に合わせられなかった事が1回。初期から連載を追ってこられた方がどれだけいるか分かりませんが、「あれ、今月載ってないの?」と思われた時があったと思います。それです、その時です。
実を言うと、この綱渡りは今も続いてるんですよね。ギリギリの納品は常態化したままで、だから毎回編集さんにはご迷惑をおかけしてます。申し訳ない事をしています。
やると言って引き受けた仕事で、約束を守らないって最悪じゃないですか。「原稿落としちゃいました、ヘラヘラ。これで自分も並み居る先輩作家大先生達に並んじゃいましたね、ヘラヘラ」なんて自慢してる場合じゃないです。酷い事ですよ。信用されるもクソもない、尊敬になんてまるで値しない。それで「なんで自分は人望が無いんだろう、人に誘われないんだろう、声かけてもらえないんだろう」と嘆くなんて、どういう神経してるんですかって話です。
最近こんな話を見かけました。
学生のごさいだったころ、学生間でごみの持ち帰りについて議論したことがあった。ポイ捨てしない派が多数で、怒った「する派」の学生が「出先でごみ箱がなかったらどうするんだ!」といったところ、しない派の学生が「え?袋に入れて持ち帰るよね」と全員鞄から畳んだビニール袋を出した。
- mago (@mago106) 2019年5月7日
その時の愕然とした「する派」の人の顔が忘れられない。「しない派」の学生全員が袋を持っていたのは全くの偶然で、袋を出した本人たちも驚いていた。
- mago (@mago106) 2019年5月7日
こうなると完全に生育歴を含んだ文化の違いで、社会性や思いやりとかの問題じゃない。
この議論は学生間の雑談から自発的に出てきたもので、学校が用意した課題ではなかった。そのため「する派」の学生にとってショッキングな議論運びになってしまった。たぶん「する派」は「公的にはしないことになってるけど、みんなやってるのが当たり前」という認識で成人まで暮らしてきたんだと思う。
- mago (@mago106) 2019年5月7日
そう、まさしく「公的にはしないことになってるけど、みんなやってるのが当たり前」という認識でいるから、不義理をしてしまえるのですよね。「自分は特別だから許される」なんて思ってはさすがにいなかったと思っていますが、だからこそ「みんなやってるんだから、自分もやっていいでしょ」と思っていたわけです。「当たり前じゃない」と人から叱られるまで、それが自分には分かっていませんでした。
これを読んだ人は、約束は守るから約束なんだ、という事だけとりあえず覚えて帰って下さい。今年37歳になるおじさんから後進へできるアドバイスは、以上です。
(2019年7月10日追記:fttを追加)
現時点で把握してる、Tree Style Tab(ツリー型タブ)以外の物をまとめた。ボタンでポップアップが表示されるタイプの物を除外した、サイドバー常時表示型の物だけです。
ツリー表示できる物
グループ化できる物
縦置きだけ
じっくり使い込んだわけではないけど、これらの中ではSideberyがぱっと見の出来がいいように見えた。
(2019年7月10日追記)また、新顔のfttも興味深い。TSTと同様に他のアドオンとの互換性を維持することを目標に置きつつ、WebExtensionsのタブ関係のAPIをもう一層ラップするライブラリを用いて、安定性を損ねる原因となっている複雑な非同期処理を排除しているらしい。多機能ではないシンプル路線での有望株だと思う。
TSTをWebExtensionsに移行したときは、その時点でも既に結構な数の縦型タブバーアドオンがあったので、「縦型タブバーとしては後発だ」と認識してたんだけど、その後もまだまだ新しい物が作られてるというのは興味深いです。というのも、これらのアドオンが依存するサイドバーAPIはGoogle Chromeには存在せずFirefoxやOperaなどでしか使えないため、ブラウザのシェア的にはそこで頑張っても社会的にはあまり報われませんので。以前、アドオンの勉強会でFirefoxのWebExtensionsに固有のAPIを紹介した時に「Chromeで使えないなら使わない」という反応をもらった事を考えると、まだまだ自分の他にもへそ曲がりがいるものなんだなあ、とちょっと嬉しくなってしまいます。
それにしても、これらの中で最もユーザー数が多いTab Center Reduxでも1万2千人で、TSTの約13万人とは10倍の開きがあって、なんでこんなにTSTのユーザー数が多いのか?と我ながら不思議に思ってしまう。単純に歴史が古いから(XUL時代を含めると12年)だけでしょうか。先行者利益というか残存者利益というか。
古くからあるから出来が良いのかっていうと別にそんな事ないんですけどね。実際、1000とかメチャクチャ大量のタブがある状態で試してみると、ここに挙げたアドオンはどれもTSTに比べると圧倒的に起動が速かったし。というかTSTが桁外れにクソ遅かった(これは僕が動作速度や処理効率に比較的無頓着なせいだと思ってる)。TST 3.0でだいぶ高速化はしたつもりだけど。
(と、情報提供のフリして数字を出してせこい自慢をするだけのエントリなのでした)
会社で新しくWindows 10 PCをメイン環境として使い始めようとしていて、セットアップするのになんやかや詰まったので記録を残しておきます。
何も考えずにMicrosoftアカウントで使い始めると、例えば shimoda.hiroshi
みたいなMicrosoftアカウントだったら C:\Users\shimo
みたいな適当にぶった切られた名前でホームディレクトリができてしまう。C:\Users\piro
みたいに任意の名前のホームディレクトリにするためには、以下の手順を踏まないといけない。
C:\Users\shimo
とか)を管理者権限で削除する。コンピューター名はWindowsの通常使用だと意識する事はあまりなくて、LAN内で参照する時に使う程度だけど、WSLでホスト名として常時目にする事になる。これがランダムっぽい名前だと結構いらつくので、最初に変えておく。(以後はWSLでも勝手にこの情報を参照してくれる)
WSLを有効化してストアからUbuntuをインストールした後にやること。
"source": "Windows.Terminal.Wsl"
をコメントアウトして、代わりに "commandline": "wsl.exe ~ -d Ubuntu"
と書いておく。Windowsのファイルシステム上でWSLのファイルのパーミッションを保存できるようにするために、 sudo vim /etc/wsl.conf
で設定ファイルを開いて以下の内容を保存する。
[automount]
options = "metadata,umask=22,fmask=111"
マウントした既存のファイルや新たに作成したファイルが全部実行権限付きで認識されるとGitを使うのに不便なので、maskを指定して実行権限がつかないようにしておく。
LxssManager
を探し、再起動する。これで、上記の設定が反映される。ln -s /mnt/c/Users/username/Destop ~/Desktop
、ln -s /mnt/c/Users/username/Documents ~/Documents
、ln -s /mnt/c/Users/username/Downloads ~/Downloads
、ln -s /mnt/c/Users/Public ~/Public
などとして、WSLでよく使うWindowsのフォルダにシンボリックリンクを作っておく。シェルでよく使う基本の設定をする。
~/.bashrc
に以下の内容を加えて、コマンド履歴の逆方向検索に Ctrl-S を使えるようにする。
stty stop undef
stty start undef
~/.bashrc
に以下の内容を加えて、複数のシェルでコマンド履歴を共有するようにする。
function share_history {
history -a
tac ~/.bash_history | awk '!a[$0]++' | tac > ~/.bash_history.tmp
[ -f ~/.bash_history.tmp ] && mv ~/.bash_history{.tmp,} && history -c && history -r
}
PROMPT_COMMAND='share_history'
shopt -u histappend
export HISTSIZE=99999
~/.bashrc
に以下の内容を加えて、よく使うエイリアスを使えるようにする。
export LESS='--no-init --RAW-CONTROL-CHARS --LONG-PROMPT --shift 4'
alias grep!='grep --color=always'
alias jq!='jq --color-output'
alias cd='pushd > /dev/null'
SSHの秘密鍵を設置して、他のホストにSSHで接続できるようにする。 基本方針として、WSLのsshクライアントから直接秘密鍵を触らずに、Windows 10に最初から入ってるOpenSSHのssh-agentに鍵を読み込ませて、必ずrupor-github/wsl-ssh-agent経由で利用することにする。
C:\Program Files (x86)\wsl-ssh-agent\
あたりに置く。wsl-ssh-agent-gui.exe
へのショートカットを C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
(全ユーザー向けの場合)か、%AppData%\Microsoft\Windows\Start Menu\Programs\Startup
(自分のみの場合。Win-Rで shell:startup
を実行して開かれるスタートアップフォルダ)に作る。-socket "%temp%\ssh-agent.sock"
と起動オプションを付け足す。これで、毎回起動時にssh-agentのためのソケットが作られるようになる。wsl-ssh-agent-gui.exe
が起動していないので、ショートカットをダブルクリックして起動する。~/.bashrc
に export SSH_AUTH_SOCK=/mnt/c/Users/$USER/AppData/Local/Temp/ssh-agent.sock
という行を足す。これで、WSLの環境に入ると自動的にWindows側のssh-agentと繋がるようになる。source ~/.bashrc
を実行して設定を反映する。~/.ssh
(秘密鍵、公開鍵、設定ファイル)を持ってくる。chmod 700 ~/.ssh
で、ディレクトリのパーミッションを他のユーザーから参照不可能なようにする。ssh-add ~/.ssh/(秘密鍵)
を実行し、秘密鍵を ssh-agent に読み込ませる。(以下は、Windows 10のOpenSSHを使うようになるまで使ってた、PuTTYのPageantに鍵を読み込ませて、必ずweasel-pageant経由で利用する場合の手順。歴史的資料として残す。
C:\Users\username\.ssh
(/mnt/c/Users/username/.ssh
)を作成し、旧環境からファイルをコピーする。puttygen.exe
で秘密鍵のid_rsa
をインポートして、PuTTY形式の秘密鍵 id_rsa.ppk
として保存する。shell:startup
を実行してスタートアップフォルダを開き、pageant.exe
のショートカットを作成する。pageant.exe
を起動して、先の id_rsa.ppk
を読み込ませる。C:\Program Files (x86)\wsl-pageant
に置く。chmod +x /mnt/c/Program\ Files\ \(x86\)/weasel-pageant/weasel-pageant /mnt/c/Program\ Files\ \(x86\)/weasel-pageant/helper.exe
で明示的に実行権限を設定する。echo 'eval $(/mnt/c/Program\ Files\ \(x86\)/weasel-pageant/weasel-pageant -r)' >> ~/.bashrc
で、weasel-pageantを自動起動するようにする。(weasel-pageantにどのようなオプションを設定するべきかについては、必ず最新の解説を参照すること。)mkdir ~/.ssh; chmod 700 ~/.ssh
で、設定ファイル等の置き場所を用意する。
ln -s /mnt/c/Users/username/.ssh ~/.ssh
でシンボリックリンクとして作成してしまうと、次項の設定をしてもSSH接続を受け付けられなくなってしまう(~/.ssh
のパーミッションを適切に設定できなくなる)ので、必ずここは普通のディレクトリとして作成しておく。)
openssh-server
が最初から入っているので、後は必要な設定をするだけで使える。
/mnt/c/Users/username/.ssh/
以下に公開鍵等もコピーできているはずなので、/mnt/c/Users/username/.ssh/authorized_keys
があるのであれば ~/.ssh/authorized_keys
にコピーする。なければ、/mnt/c/Users/username/.ssh/id_rsa.pub
を ~/.ssh/authorized_keys
にコピーする。chmod 600 ~/.ssh/authorized_keys
として、パーミッションを適切に設定する。sudo service ssh start
してsshdを起動する。ssh localhost
でログインできることを確認する。sudo service ssh stop
してsshdを停止する。(以後は、必要な時にだけ起動する)mkdir -p ~/local/bin
で、ユーザー固有のバイナリ置き場を用意する。echo 'export PATH="~/local/bin:$PATH"' >> ~/.bashrc
してパスを通しておく。peco_linux_amd64.tar.gz
を使った)。unar peco_linux_amd64.tar.gz
でファイルを展開する。peco
を ~/local/bin/
に移動し、chmod +x ~/local/bin/peck
で実行権限を設定する。echo 'source ~/peco-commands.sh' >> ~/.bashrc
で自動的に読み込むように設定する。bash-git-promptを使うようにする。
cd ~/
して git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth=1
で必要なファイルをローカルに用意する。以下の内容を ~/.bashrc
に追加して、機能を有効化する。
GIT_PROMPT_ONLY_IN_REPO=1
source ~/.bash-git-prompt/gitprompt.sh
GIT_PROMPT_THEME=Single_line_Ubuntu
時刻表示の部分が余計なので、以下のように編集する。
diff --git a/themes/Single_line_Ubuntu.bgptheme b/themes/Single_line_Ubuntu.bgptheme
index 7dd3a4f..542b259 100644
--- a/themes/Single_line_Ubuntu.bgptheme
+++ b/themes/Single_line_Ubuntu.bgptheme
@@ -15,7 +15,7 @@ override_git_prompt_colors() {
GIT_PROMPT_COMMAND_OK="${Green}✔ "
GIT_PROMPT_COMMAND_FAIL="${Red}✘ "
- GIT_PROMPT_START_USER="_LAST_COMMAND_INDICATOR_ ${White}${Time12a}${ResetColor} ${Cyan}${PathShort}${ResetColor}"
- GIT_PROMPT_END_USER="${ResetColor} $ "
- GIT_PROMPT_END_ROOT="${BoldRed} # "
+ GIT_PROMPT_START_USER="${Cyan}${PathShort}${ResetColor}"
+ GIT_PROMPT_END_USER="${ResetColor}\$ "
+ GIT_PROMPT_END_ROOT="${BoldRed}# "
sudo update-alternatives --config editor
でデフォルトのエディタをvim.basic
に切り替えておく。ここまででWSL上のrsyncが使えるようになっているので、旧環境から rsync -a xxx.xxx.xxx.xxx:~/path/to/directory/ ~/Public/
みたいにしてパーミッションの情報込みでファイルを持ってこれる。
(シンボリックリンクまで勝手に辿らせると大変なことになりかねないので、シンボリックリンクの先は個別に辿るのがよい気がする。)
今回は移行元がハードウェア上にインストールされたUbuntuだったけれども、移行元がWindows 10マシンの場合も上記の要領であらかじめsshdを起動しておけば、同様にrsyncでファイルを持ってこれる。
最近のMozillaBuildとmozilla-centralはよくできてて、だいたい一発で環境ができあがる。以下、前半は会社のブログに書いた手順の通り。
c:\mozilla-build
にインストールする。C:\mozilla-source
の位置にフォルダを作る。Firefoxのソースコード一式はこの配下に置く事になる。c:\mozilla-build\start-shell.bat
を実行して、MozillaBuildのシェル(Bash)を起動する。echo 'export PATH=$PATH:~/.cargo/bin' >> ~/.bash_profile
を実行して、MozillaBuildのシェルを一旦終了し、c:\mozilla-build\start-shell.bat
で起動し直す。cd /c/mozilla-source
して、 hg clone https://hg.mozilla.org/mozilla-central
でmozilla-centralをcloneする。cd mozilla-central
してリポジトリに入り、./mach bootstrap
を実行する。これにより、Visual StudioやRustなどのビルドに必要なソフトウェア群が自動インストールされる。./mach build
して、ビルドできる事を確認する。./mach run
して、ビルドしたFirefoxを起動できる事を確認する。WSLとホームを共用してない関係でBashの設定が素のままなので、~/.bash_profile
に以下を追記する。
# Ctrl-Sで履歴を逆検索できるようにする
stty stop undef
stty start undef
# MozillaBuildの環境にはtacが無いので、関数で代用する
function tac {
exec sed '1!G;h;$!d' ${@+"$@"}
}
# 複数のシェルで履歴を共有する
function share_history {
history -a
tac ~/.bash_history | awk '!a[$0]++' | tac > ~/.bash_history.tmp
[ -f ~/.bash_history.tmp ] && mv ~/.bash_history{.tmp,} && history -c && history -r
}
PROMPT_COMMAND='share_history'
shopt -u histappend
export HISTSIZE=99999
Mozillaのサーバーに認証を求める時のユーザー名指定を省略できるようにするために、~/.ssh/config
に以下を追記する。
Host hg.mozilla.org
User yuki@clear-code.com
ssh hg.mozilla.org
してみて、認証できるかを確認する。(シェルには入れないでそのまま接続が切れるが、それでOK。)
tryserverを使うために、~/.hgrc
に以下を追記する。
[paths]
try = ssh://hg.mozilla.org/try
./mach try empty
で空のリクエストを送れるかどうか確認する。
hg grepfile
でワーキングコピーのファイルを対象に検索できるようにするために、hg-grepfileをインストールする。最近までWindows 10標準で仮想デスクトップ機能があるということを把握してませんでした。今回調べて初めて知りました。
Ubuntuではメインの作業画面とThunderbirdを使う(メールを読み書きする)画面とを分けていて、画面の端にカーソルでちょいっと触れると仮想デスクトップ切り替えの画面が出てくるようになってたんだけど、そういう事をできるようにするにはユーティリティが必要。タスクビューの切り替え画面を出すこと自体は、Windowsキー+Tabでできるので、任意のジェスチャでこのキー操作を代替すればよい。
マウスジェスチャーソフトの「MouseGestureL.ahk」でマウスホイールにWindows10の「タスクビュー」を割り当てる | PC ウェブログという記事を参考に、以下のようにした。
C:\Program Files
配下あたりに適当に置く。Setup.vbs
を実行する。screen-edge
CRB_
(画面右下角に接触)CLB_
(画面左下角に接触)screen-edge
以外すべて削除する。screen-edge
のアクションスクリプトを以下の通りに書く。
;キー操作を発生させる
Send, #{TAB down}{TAB up}
「その他」タブに切り替えて、「スタートアップに登録」で自動起動するようにする。
これで、画面の端に触れるだけで仮想デスクトップを切り替えられるようになる。
2020年5月1日追記。初期設定ではRB
(右ボタン)で始まるジェスチャがいくつか定義されてるんだけど、これがあると、Windows全体で右ボタンの動作に影響が及んでしまう。具体的には、window.addEventListener('mousedown', ...)
みたいな方法でマウスのボタンが押し下げられたことを検知しようとしても、右ボタンだけmousedownが取れなくなる(ボタンを放したときに初めてmousedownが発火するようになる)。自分はscreen-edge
をトリガーにした操作しか使わないので、RB
で始まるジェスチャは全部削除した。
Ubuntuではテキストを選択すると通常のクリップボードとは別の専用のバッファにテキストが格納されてミドルクリックで貼り付けるという動作になってた(これ自体はXの機能とのこと)んだけど、GNOME Terminal(端末)でコピー&ペーストのキーバインドが他のGUIアプリと違っていたこともあって自分でも驚くくらいに意外と多用していて、Windows環境でWSLを使っているとそのときの感覚が抜けなくてつい戸惑ってしまう。
代わりになりそうなものを探してみたらいくつか情報が見つかったんだけど、どれも今使うにはちょっと厳しい感じだった。
もうちょっと悪あがきしてみようと思って「Windows selection auto copy」という感じのキーワードで検索してみたら、AutoHotKey用のスクリプトの例が出てきた。自分は結局AutoHotKeyは入れずにMouseGestureL.ahkだけで使ってるんだけど、これの実態がほぼ同じ物のようで、MouseGestureL.ahkのインストール先にあるMG_User.ahk
のユーザー定義サブルーチンの所に以下のスクリプトを追加してMouseGestureL.ahkを再起動したら普通に使えた。
ただ、Ubuntuの時と違って専用のバッファが使われる訳ではないから、選択→Ctrl-Cでコピー→貼り付けたい箇所にある邪魔なテキストを選択→Ctrl-V という事をしようとすると、貼り付け先の邪魔なテキストの方がクリップボードに入ってしまうという難点があった。なので解説を見ながら試行錯誤して、クリップボードとは別のバッファを持つようなスクリプトを作ってみた。MouseGestureL.ahk単体版ではなくAutoHotKeyの方を使う場合は、上記の内容をSelectionClipboard.ahk
という名前で保存し、ファイル名を指定して実行→shell:startup
で開かれるスタートアップフォルダの中に置けばいいみたい。
で、しばらく試してみてたんだけど、以下の問題をどうしても解決できなかった。
Ctrl-Cでクリップボードへのコピーを試行するのが元凶なので、それ無しで選択範囲のテキストを取得できる方法があればいいんだけど、それはエディットコントロールに対してのみ動作する関数しか用意されてなくて、オフィシャルのサンプルの時点で「標準のエディットコントロール以外でも使えるのはCtrl-Cを使う方法だ」と紹介されてるレベルだったので、AutoHotKeyの制限事項としてどうにもならないというのが結論のようです。残念。
これ機能として欲しくなることが無くてまず誤爆で困るばかりなんですけど?
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
にDisallowShaking
というDWORDの値を作ってデータを1
にすると、この機能が無効化されるそうです。
そんなに頻繁にやるわけじゃなくて、数年に1回やる程度なので、
という風に思ってます。
毎月やるとか、まとめて10台くらいやるとか、そういう前提が出てきたら重い腰を上げてPowerShell覚えるかもしれないですね。
まだ後から書き足しそう。
(後日談:これとは別のPCについて行った、Bash on Ubuntu on WindowsからストアアプリのUbuntuへの環境引き継ぎの話。ここに書いた話を一部参照した。)
これはただの苦労話です。
2月末から3月末までをかけて、長らく懸案事項となっていたツリー型タブ(Tree Style Tab、TST)の大規模改修をやりました。具体的な変更の量としては、改修に取りかかる前の2.7.22からの差分 git diff 2.7.22
で約1MBありました。見た目は変えなかったのであまり代わり映えしませんし、挙動を決定づけるロジックもほぼそのままなのですが、それらが乗っかる基盤にあたる部分が入れ替わった感じです。
何を改修したのか、どういう成果があったのか、という事を説明するために、TSTのこれまでの歴史を振り返ってみます。WebExtensionsに移行した時の話ではあまり触れなかった、細かい実装の話が多めですが、誰の役に立つかは分かりません。
今やHDDより頑丈な「SSDの寿命」と耐久性の凄さ | ちもろぐを読んで「TBW」という指標の存在を初めて知り、自分が今使っている機材の寿命を知りたくなったので計算してみた。
現行機材にはSSDが2つマウントされてる。1つはシステムとデータが両方入ってるSamsung SSD 930 EVO 500GBで、公称値は200TBW。もう1つは仮想マシン置き場にしているSamsung SSD 680 EVO 250GBで、公称値は150TBW。CrystalDiskInfoで総書き込み量と使用時間を調べて計算したら、前者はだいたい残り2年9ヵ月の命、後者は使用頻度が低いせいで残り654年の命と出た。後者はともかく前者は機材更新に備えておかないといけない……
メーカー公称値のTBWとCrystalDiskInfoで表示される数字からの計算が面倒だったので、フォームを埋めるだけで計算してくれるような物を用意してみました。
1523784 - Set up analytics for https://extensionworkshop.com というbug(※bugzilla.mozilla.orgではシステム上でトラックされているタスクを一般的に「bug」と呼ぶ)でどうやら何かアドオン(拡張機能)作ってみましょう的なイベント?の準備が進められているらしいという事を、人から教えて頂いた。キャンペーンサイトの準備中バージョンらしき物を見てみると、絵が豊富で見た目とっつきやすそうな感じに仕上がってる印象で「ほほう」って思ったんだけど、アドオンの構造を図解してる部分でbackground script等の話が出てきてるのを見て、ちょっとキナ臭いというか不安というかそういう思いが頭をよぎった。
というのも、FirefoxのWebExtensionsというのはGoogle Chromeの拡張機能の現行の仕様(Manifest V2)をベースに作られてるわけだけど、他ならぬGoogleがManifest V3でbackground scriptの廃止などのかなり大きな変更をしようとしている状況で、この内容で大々的にリリース打って大丈夫なのか? と。
だって、このキャンペーンサイト(多分)の内容を素直に受け取ると「WebExtensionsのAPIを使ってアドオンを作ろう。他のブラウザにも移植しやすいよ。」というような話になってると思うんだけど、いやちょっと待ってくださいよ。Firefox向けにWebExtensionsでアドオン作っても、Google ChromeがManifest V3に移行しちゃったら、それ動かないじゃんすか。っていうかChromeがManifest V3に移行するってことは当たり前だけどChromiumもManifest V3になるってことで、ということは、Chromiumベースのブラウザも(各ベンダがどう思ってるかに関係なく、強制的に)全部Manifest V3に移行するってことじゃんすか。次期EdgeもOperaもVivaldiもKinzaもみんなManifest V3に行っちゃって、そしたらChromiumベースでないFirefoxだけ置いてけぼりじゃんすか。
つまり、ChromeのManifest V3移行は、ちょっと前に騒がれてた「Chromeの拡張機能の大量死」という影響だけでなく、Firefoxにとっては「大多数の開発者にとっての、(Manifest V2互換の)WebExtensionsでFirefox用アドオンを作る意義の消失」という影響を及ぼすのではあるまいか? という事に、遅まきながら気付いたわけです。
昨年のTokyo WebExtensions Meetupに参加されていた方が実装上困っておられた事について「Firefoxでは(Chromiumに無い独自拡張の)APIがあるから、Firefox向けにだけちょっと便利にするみたいなことはできるよ」的な話をしたら、「いやあ……Chromeで使えないんじゃ、その機能は使えないですね……」と敬遠された時に、改めて思い知ったのですよね。ああ、WebアプリやWebページを作る人達だけじゃなくて、ブラウザを拡張するという拡張機能を作る人達にとっても、いまや「ふつうはChrome」であって「Firefox対応はオマケに過ぎない」んだな、って事を……
FirefoxのWebExtensionsはいまのところManifest V3に追従する予定はないみたいな話をどっかで又聞きした気がしてますが、いやいやそんな悠長なこと言うとれんやないですか。ツリー型タブを実装できなくなるからManifest V3に完全移行はしないで欲しいけど、Firefox一人だけ置いてけぼりを食らわないためには、オプションとしてでもManifest V3に対応は絶対しなきゃいけないじゃないですか。
ほんとどうなるんだこれ。
難しい事は脇に置いて、「アドオンを作る人」「ベンダが提供しているUIに気に入らないところがあってイラッてなったときに自分で手を動かして解決したい人」という立場から「こうだったらいいのに」という事を書き留めておきますと、
という風な事を自分は思っています。
ちょっと前に話題になったChromeの拡張機能のAPIの新バージョンの案の概要を把握するために、変更点のまとめの部分だけを読んでみた。全訳するのも大変なので、適宜つまみながら。
APIや権限の仕組みに対して大規模な変更を行う物なので、マニフェストバージョンを3に上げる。拡張機能が実際に使用しているAPIや権限の中には、パフォーマンス、セキュリティ、プライバシー、および人間工学的な観点から、ユーザー体験を低下させている物が多数ある。新しいマニフェストバージョンではそういった負の影響を与える要素を一掃し、新しいAPIや機能だけを使えるようにする予定である。拡張機能の作者達に向け、移行を容易にするための明確な手順と、新基準に拡張機能を移行するに足る追加のインセンティブを用意するつもりである。
activeTab
スタイルの、実行時にのみアクセスが許可されるモデルへ移行する。permissions
配下でまとめて指定していたのを host_permissions
に分離する。webRequest
は、リソースの読み込みをブロックする使い方を制限する。declarativeNetRequest
を設ける。browserAction
と pageAction
を単一の action
APIに統合する。chrome://favicon
に関する権限をchrome.favicon
APIに移す。tabs
, pageCapture
, tabCapture
および desktopCapture
を単一のcapture
APIに集約する。以上、翻訳とメモの中間みたいな物でした。
この中で特に webRequest
と declarativeNetRequest
に関わる部分は、chromeの機能拡張の変更について | 280blockerで詳しく解説されている。
コンテンツのデータへのアクセスについて、<all_urls>
を廃止して、コンテンツに触れたければ必ずactiveTab
の権限の範囲でできる事だけに制限するというのは、かなり息苦しくなるなあという感じがある。例えば複数選択されたタブのそれぞれについてコンテンツの内容を収集してきてクリップボードにコピーする、みたいな事はできなくなるという事だろうか?
Promiseベースにするというのは、FirefoxのWebExtensionsが既にそうなっているし、ChromeのAPIをそのスタイルに合わせるためのPolyfillも既に広く使われているようなので、妥当だと思う。
総じて、Chrome開発チームが思う所の「こうあるべき」という思想を前面に押し出した案だなと感じた。元々、Firefoxの拡張機能がXULとXPCOMでなんでもできたのに対して、無害そう・使用頻度が高そうなニーズに応える機能だけ取捨選択してChromeの拡張機能APIとしてまとめたのが、今からほぼ10年前。10年を経てさらに取捨選択を進めると同時に、新たに明らかになってきたリスクを改めて潰し直すというのが、マニフェストV3でやりたい事なんだろう。Googleのやり方を強硬的で独善的だと非難する向きもあるようだけど、それは今に始まった事じゃない「Googleの社風」なんだと思う。
Googleが認めるやり方での広告ブロック以外は認められないという形に結果的になっているのは事実のようだけれど、巷で騒がれている「広告ブロックを禁止するための陰謀だ」みたいな見方は深読みしすぎだと思う。多分Googleの人達はそこまで考えてなくて、彼らはきっと、性能劣化がとにかく嫌で、それに繋がりうる物をなくしたら結果的にこうなった、という事なんだと僕は思ってる。やっかみ混じりで悪意に取ったとしても、せいぜい「は? 俺らが熟慮して『これで充分じゃん』って考えた物なんだから、これで完璧でしょ? 文句の付け所があるわけ?(キョトンとした顔で)」くらいの事なんじゃないかな。
サイドバーAPIを頑なに付けないのも、要はそういう「は? そんなもんいらんやろ? ブラウザは最低限の機能だけでええやん、常時表示するカスタムUIなんて無駄なだけやん(キョトンとした顔で)」みたいな感じなんじゃないのかなと僕は認識してる。僕はツリー型タブを「脳内ワーキングメモリが極めて貧弱な自分でも、Webのブラウズ履歴を視覚的にその場に残して常に全体をざっと眺められるようにできれば、ワーキングメモリの小ささを補って人並みの仕事ができる」という使い方をしてるけれども、優秀なGoogleの人達は(※やっかみ)ワーキングメモリが広大で、そんな風にツールで補う必要がきっと無いから、それで必要性を認めないんだろう、と僕は思ってる。
速度以外のセキュリティについても、セキュリティが担保されるなら利便性はどうでもいいというのが彼らの本音であるように思う。いや、セキュリティ第一であるべきというのは一般的にもちろん正しいし、一般ユーザー向けに「セキュリティより自由度を」なんて言ってる人がもしいたら、アホだとは思う。「よく分かってる人・開発者向けにだけ裏道を残しておけばいい」とは言っても、大抵の人は自分が何をしてるか分からないまま自分の足を撃ち抜きがちで、しかもその事に気付いてすらいないものだから、そういう「パワーユーザー向けにだけ解放」が絵空事でしかないというのも分かる。
これって何かに似てるなと思ったら、あれだ、アメリカの銃規制に似てるんだ。アメリカは銃を所持する事が自分の自由を守る事とセットだという建国の精神だから、いくら安全のためとはいっても銃を完全に社会からなくそうとすると強い反発が起こる、っていう。
銃乱射事件が起こる度に出てくる「全米ライフル協会『(被害者が)銃を持っていればこんな事件は防げた』」というジョークを見る度に「アホやなあ」と僕は思っていたけれど、それを笑っていた僕自身もまた、リスクに目を瞑って、危険な武器を自分が手にできる自由を声高に叫んでいた人の1人だったのだな、と。自分自身が「ただのユーザー」から「自分の使う道具を自分で作り替えられる開発者」にステップアップできる余地があったから(他にも理由はあったけど)、僕はMozillaを使っていたし、「Chromeと同じになってしまった」「Mozillaはアドオンを殺した」なんて言われた後の今でもSuccessor Tabs APIや コンテキストメニューのコンテキストのオーバーライドのように「安全」とのバランスを取りながら自由度を増す事に寛容な姿勢が垣間見えていて、方向性としてはまだそういう自由度を尊重してくれているように思えるので、それで僕はFirefoxを使い続けてるんだな。自分が独り立ちできた事の根底にあった「建国の精神」とガッチリ結びついてるから、僕は自由度をなるべく捨てたくないんだな。ということを、Chromeの拡張機能マニフェストV3のいざこざを見ていて改めて意識させられた。
そういう感じでなんかこうセンスというか目指すところが合わないので、僕は今後も当面Chromeに移ることは無いかなと思っているのでした。
「じゃあサイドバーAPI付きのChromiumベースのブラウザならどうなんよ、Operaとか」っていう疑問も当然浮かぶわけだけれど、ベースになってる物の設計思想が決定的に自分とマッチしてない(と僕は思ってる)以上、その上に組み上げられた物も自分にはマッチしないんじゃないかなあという見方をしてしまうし、それにChromeチームの意向で梯子を外されてOperaも他のChromiumベースの製品もみんなおじゃんになっちゃいましたみたいな未来もあるんじゃないかくらいに悲観的に考えてるので、やっぱりその路線も無しというのが今の自分の考えです。