Goブログ

モジュールミラーとチェックサムデータベースの公開

Katie Hockman
2019年8月29日

モジュールのミラーインデックス、およびチェックサムデータベースが本番環境で使用できるようになったことをお知らせできることを嬉しく思います!goコマンドは、Go 1.13モジュールユーザーに対して、デフォルトでモジュールミラーとチェックサムデータベースを使用します。proxy.golang.org/privacyでこれらのサービスに関するプライバシー情報、およびgoコマンドのドキュメントで設定の詳細(これらのサーバーの使用を無効にする方法や、異なるサーバーを使用する方法など)を参照してください。非公開モジュールに依存している場合は、環境設定に関するドキュメントを参照してください。

この投稿では、これらのサービスとその使用による利点について説明し、Gophercon 2019で行われたGo Module Proxy: Life of a Query講演のいくつかのポイントを要約します。講演全体に興味がある場合は、録画をご覧ください。

モジュールミラー

モジュールは、まとめてバージョン管理されるGoパッケージのセットであり、各バージョンの内容は不変です。その不変性は、キャッシングと認証の新たな機会を提供します。go getがモジュールモードで実行されると、要求されたパッケージを含むモジュールと、そのモジュールによって導入された新しい依存関係をすべて取得し、必要に応じてgo.modファイルとgo.sumファイルを更新する必要があります。バージョン管理システムからモジュールを取得することは、システムのレイテンシとストレージの点でコストがかかる可能性があります。goコマンドは、推移的な依存関係(ビルドされていない依存関係も含む)を含むリポジトリの完全なコミット履歴をプルダウンする必要がある場合があります。

解決策は、goコマンドのニーズにより適したAPIを使用するモジュールプロキシを使用することです(go help goproxyを参照)。プロキシを使用してモジュールモードでgo getを実行すると、必要なモジュールメタデータまたはソースコードのみを要求し、残りの部分は気にしないため、高速に動作します。以下は、goコマンドがプロキシをgo getで使用して、バージョンリストを要求し、最新のタグ付きバージョンのinfo、mod、zipファイルを要求する例です。

モジュールミラーは、独自のストレージシステムにメタデータとソースコードをキャッシュする特殊な種類のモジュールプロキシであり、元の場所では使用できなくなったソースコードを引き続き提供できます。これにより、ダウンロード速度が向上し、依存関係の消失から保護されます。詳細については2019年のGoモジュールを参照してください。

Goチームは、proxy.golang.orgで提供されるモジュールミラーを維持しており、Go 1.13以降、モジュールユーザーに対してgoコマンドがデフォルトで使用します。以前のバージョンのgoコマンドを実行している場合は、ローカル環境でGOPROXY=https://proxy.golang.orgを設定してこのサービスを使用できます。

チェックサムデータベース

モジュールは、go.sumファイル(最初にダウンロードされた各依存関係のソースコードとgo.modファイルのSHA-256ハッシュのリスト)を導入しました。goコマンドは、ハッシュを使用して、同じバージョンに対して異なるコードを提供するオリジンサーバーまたはプロキシによる不正な動作を検出できます。

このgo.sumファイルの制限は、最初の使用時に完全に信頼に基づいていることです。これまでに見たことのない依存関係のバージョンをモジュールに追加すると(既存の依存関係をアップグレードすることによって)、goコマンドはコードを取得し、その場でgo.sumファイルに行を追加します。問題は、これらのgo.sum行が他の誰かの行と照合されていないことです。プロキシが意図的にあなたをターゲットとした悪意のあるコードを提供したため、それらはgoコマンドが他の人に対して生成したgo.sum行と異なる可能性があります。

Goの解決策は、チェックサムデータベースと呼ばれるgo.sum行のグローバルソースであり、goコマンドが常に全員のgo.sumファイルに同じ行を追加することを保証します。goコマンドが新しいソースコードを受け取るときはいつでも、このグローバルデータベースに対してそのコードのハッシュを確認してハッシュが一致することを確認し、全員が特定のバージョンに対して同じコードを使用していることを保証します。

チェックサムデータベースはsum.golang.orgで提供され、透過ログ(または「Merkleツリー」)に基づいて構築され、Trillianによってサポートされています。Merkleツリーの主な利点は、改ざん防止であり、不正な動作が検出されないままになるような特性がないことです。これにより、単純なデータベースよりも信頼性が高くなります。goコマンドは、新しいgo.sum行をモジュールのgo.sumファイルに追加する前に、このツリーを使用して「包含」証明(特定のレコードがログに存在する)と「整合性」証明(ツリーが改ざんされていない)を確認します。以下は、そのようなツリーの例です。

チェックサムデータベースは、goコマンドがgo.sum行のリクエストと検証に使用できる一連のエンドポイントをサポートしています。/lookupエンドポイントは、「署名付きツリーヘッド」(STH)と要求されたgo.sum行を提供します。/tileエンドポイントは、タイルと呼ばれるツリーのチャンクを提供し、goコマンドは証明に使用できます。以下は、goコマンドがモジュールバージョンの/lookupを実行し、証明に必要なタイルを要求することによってチェックサムデータベースと対話する例です。

このチェックサムデータベースにより、goコマンドは、そうでなければ信頼できないプロキシを安全に使用できます。上に監査可能なセキュリティレイヤーがあるため、プロキシまたはオリジンサーバーは、検出されずに意図的、恣意的、または偶然に間違ったコードを提供し始めることができません。モジュールの作成者でさえ、変更が検出されない限り、タグを移動したり、特定のバージョンに関連付けられたビットを変更したりすることはできません。

Go 1.12以前を使用している場合は、gosumcheckを使用して、go.sumファイルをマニュアルでチェックサムデータベースに対してチェックできます。

$ go get golang.org/x/mod/gosumcheck
$ gosumcheck /path/to/go.sum

goコマンドによって行われる検証に加えて、サードパーティの監査者は、ログを反復して不正なエントリを探し、チェックサムデータベースを説明責任に問うことができます。彼らは協力して、ツリーの成長に伴う状態をゴシップし、それが安全な状態を維持するようにし、Goコミュニティがそれらを運用することを期待しています。

モジュールインデックス

モジュールインデックスはindex.golang.orgで提供され、proxy.golang.orgを通じて利用可能になる新しいモジュールバージョンの公開フィードです。これは、proxy.golang.orgで利用可能なものの独自のキャッシュを保持したり、人々が使用している最新のモジュールを最新の状態に保ちたいツール開発者にとって特に便利です。

フィードバックまたはバグ

これらのサービスがモジュールエクスペリエンスを改善することを期待しており、問題が発生した場合やフィードバックがある場合は、問題を報告することをお勧めします!

次の記事:Go 1.13がリリースされました
前の記事:Goモジュールへの移行
ブログインデックス