Linux 用のセルフホスト

Chrome ユーザーが Chrome ウェブストアの外部でホストされている拡張機能をインストールできる唯一のプラットフォームは Linux です。この記事では、汎用ウェブサーバーから crx ファイルをパッケージ化、ホスト、更新する方法について説明します。Chrome ウェブストアでのみ拡張機能やテーマを配布している場合は、ウェブストアのホスティングと更新をご覧ください。

パッケージ

拡張機能とテーマは .crx ファイルとして提供されます。Chrome デベロッパー ダッシュボードを使用してアップロードする場合、ダッシュボードには crx ファイルが自動的に作成されます。個人用サーバーで公開する場合は、crx ファイルをローカルで作成するか、Chrome ウェブストアからダウンロードする必要があります。

Chrome ウェブストアから .crx をダウンロードする

拡張機能が Chrome ウェブストアでホストされている場合は、デベロッパー ダッシュボードから .crx ファイルをダウンロードできます。[リスティング] で拡張機能を探して [詳細] をクリックします。ポップアップ ウィンドウで、青い main.crx リンクをクリックしてダウンロードします。

デベロッパー ダッシュボードから .crx をダウンロードする

ダウンロードしたファイルは個人用サーバーでホストできます。拡張機能のコンテンツは Chrome ウェブストアによって署名されるため、これは拡張機能をローカルでホストする最も安全な方法です。これは、潜在的な攻撃や改ざんの検出に役立ちます。

ローカルで .crx を作成する

拡張機能ディレクトリは、拡張機能の管理ページで .crx ファイルに変換されます。アドレスバーの chrome://extensions/ に移動するか、Chrome メニューをクリックして [その他のツール] の上にポインタを置いて [拡張機能] を選択します。

拡張機能の管理ページで、[デベロッパー モード] の横にある切り替えスイッチをクリックしてデベロッパー モードを有効にします。次に、[拡張機能をパッケージ化] ボタンを選択します。

[デベロッパー モード] のチェックボックスをオンにして [拡張機能をパッケージ化] をクリックする

[拡張機能のルート ディレクトリ] フィールドで拡張機能のフォルダへのパスを指定し、[EXTENSION をパッケージ化] ボタンをクリックします。初回パッケージの場合は [秘密鍵] フィールドを無視します。

拡張機能のパスを指定し、[拡張機能をパッケージ化] をクリックします。

Chrome で .crx ファイルと .pem ファイルの 2 つのファイルが作成されます。このファイルには拡張機能の秘密鍵が含まれています。

パッケージ化された拡張機能ファイル

秘密鍵を紛失しないようにしてください。.pem ファイルは、拡張子を更新する際に必要となるため、秘密の安全な場所に保管してください。

.crx パッケージを更新する

manifest.json のバージョン番号を増やして、拡張機能の .crx ファイルを更新します。

{
  ...
  "version": "1.5",
  ...
  }
}
{
  ...
  "version": "1.6",
  ...
  }
}

拡張機能の管理ページに戻り、[拡張機能をパッケージ化] ボタンをクリックします。拡張機能ディレクトリのパスと秘密鍵の場所を指定します。

拡張機能ファイルの更新

このページには、更新されたパッケージ化された拡張機能のパスが表示されます。

拡張機能ファイルの更新

コマンドラインでパッケージ化する

chrome.exe を呼び出して、コマンドラインで拡張機能をパッケージ化する。--pack-extension フラグを使用して拡張機能のフォルダの場所を指定し、--pack-extension-key フラグを使用して拡張機能の秘密鍵ファイルの場所を指定します。

chrome.exe --pack-extension=C:\myext --pack-extension-key=C:\myext.pem

ホスト

.crx ファイルをホストするサーバーで、適切な HTTP ヘッダーを使用して、ユーザーがリンクをクリックして拡張機能をインストールできるようにする必要があります。

Google Chrome では、次のいずれかに該当する場合、ファイルをインストール可能とみなされます。

  • ファイルのコンテンツ タイプが application/x-chrome-extension である
  • ファイルの接尾辞は .crx で、次の両方に該当しています。
    • ファイルが HTTP ヘッダー X-Content-Type-Options: nosniff とともに提供されていない
    • ファイルが次のいずれかのコンテンツ タイプで提供されている
    • 空の文字列
    • "text/plain"
    • "application/octet-stream"
    • "unknown/unknown"
    • "application/unknown"
    • "\*/\*"

インストール可能なファイルを認識できない最も一般的な理由は、サーバーがヘッダー X-Content-Type-Options: nosniff を送信することです。2 番目に多い理由は、サーバーが不明なコンテンツ タイプ(前のリストにないタイプ)を送信することです。HTTP ヘッダーの問題を解決するには、サーバーの構成を変更するか、別のサーバーで .crx ファイルをホストしてみてください。

更新

ブラウザは、インストールされている拡張機能の更新 URL を数時間ごとにチェックします。それぞれについて、その URL にリクエストを行い、アップデート マニフェストの XML ファイルを検索します。

  • アップデート チェックで返されるコンテンツは、拡張機能の最新バージョンがリストされたアップデート マニフェストの XML ドキュメントです。

アップデート マニフェストに、インストールされているバージョンより新しいバージョンが記載されている場合、ブラウザは新しいバージョンをダウンロードしてインストールします。手動更新と同様に、新しい .crx ファイルは、現在インストールされているバージョンと同じ秘密鍵で署名する必要があります。

注: ユーザーのプライバシーを保護するため、Google Chrome は、自動更新のマニフェスト リクエストで Cookie ヘッダーを送信せず、これらのリクエストに対するレスポンスに含まれる Set-Cookie ヘッダーを無視します。

URL を更新

Chrome ウェブストア以外のサーバーでホストされている拡張機能については、manifest.json ファイルに update_url フィールドを含める必要があります。

{
  "name": "My extension",
  ...
  "update_url": "https://myhost.com/mytestextension/updates.xml",
  ...
}

マニフェストを更新する

サーバーから返されるアップデート マニフェストは XML ドキュメントである必要があります。

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>
    <updatecheck codebase='https://myhost.com/mytestextension/mte_v2.crx' version='2.0' />
  </app>
</gupdate>

この XML 形式は、Google のアップデート インフラストラクチャである Omaha で使用されている形式に基づいています。拡張機能システムは、アップデート マニフェストの <app> 要素と <updatecheck> 要素に次の属性を使用します。

appid
拡張機能 ID は、パッケージ化で説明されているように、公開鍵のハッシュに基づいて生成されます。拡張機能の ID は拡張機能の管理ページに表示されます。
コードベース
.crx ファイルへの HTTPS URL。
バージョン
クライアントが codebase で指定された .crx ファイルをダウンロードするかどうかを決定するために使用します。.crx ファイルの manifest.json ファイルにある「version」の値と一致する必要があります。

アップデート マニフェストの XML ファイルには、複数の <app> 要素を含めることで、複数の拡張機能に関する情報を含めることができます。

テスト

更新チェックのデフォルトの頻度は数時間ですが、拡張機能の管理ページの [拡張機能を今すぐ更新] ボタンを使用して強制的に更新できます。

拡張機能を今すぐ更新

これにより、インストールされているすべての拡張機能のチェックが開始されます。

高度な使用方法: リクエスト パラメータ

基本的な自動更新メカニズムは、静的 XML ファイルを Apache などのプレーンなウェブサーバーにドロップし、新しい拡張機能バージョンがリリースされたときにその XML ファイルを更新するだけで、サーバー側の作業が容易になるように設計されています。

複数の拡張機能をホストするデベロッパーは、アップデート リクエスト内の拡張機能 ID とバージョンを示すリクエスト パラメータを確認できます。これらのパラメータを含めると、静的 XML ファイルではなく、動的なサーバーサイド コードを実行する同じ URL から拡張機能を更新できます。

リクエスト パラメータの形式は次のとおりです。

?x=EXTENSION_DATA

ここで、EXTENSION_DATA は、次の形式の URL エンコードされた文字列です。

id=EXTENSION_ID&v=EXTENSION_VERSION

たとえば、2 つの拡張機能が同じ更新 URL(https://test.com/extension_updates.php)を参照しているとします。

  • 拡張機能 1
    • ID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    • バージョン: 1.1
  • 拡張機能 2
    • ID: "bbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    • バージョン: 0.4

拡張機能を個別に更新するリクエストは次のようになります。

https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1

and

https://test.com/extension_updates.php?x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4

一意の更新 URL ごとに、1 つのリクエストで複数の拡張機能を指定できます。上記の例では、ユーザーが両方の拡張機能をインストールしている場合、2 つのリクエストが 1 つのリクエストに統合されます。

https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1&x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4

同じ更新 URL を使用するインストール済み拡張機能の数が多すぎて GET リクエスト URL が長すぎる場合(2,000 文字を超える場合)、更新チェックは必要に応じて追加の GET リクエストを発行します。

高度な使用方法: ブラウザの最小バージョン

拡張機能システムへの API の追加に伴い、新しいバージョンのブラウザでのみ動作する拡張機能の更新バージョンがリリースされる可能性があります。Google Chrome 自体は自動更新されますが、ユーザーベースの大部分が新しいリリースに更新されるまでに数日かかることがあります。特定のアップデートを特定のバージョン以上の Google Chrome バージョンにのみ適用するには、アップデートのレスポンスの <app> 要素に「prodversionmin」属性を追加します。

<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
  <app appid='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>
    <updatecheck codebase='http://myhost.com/mytestextension/mte_v2.crx' version='2.0' prodversionmin='3.0.193.0'/>
  </app>
</gupdate>

これにより、Google Chrome 3.0.193.0 以降を使用している場合にのみ、バージョン 2 に自動更新されます。