Skip to Content
新しいバージョン 12 を公開しました 🎉
LicensingFIPS 準拠

FIPS 準拠

Babel Licensing は FIPS が有効な Linux ホストで動作し、そのライセンス検証は FIPS が禁止するアルゴリズムに依存しません。このページでは、そのようなホストでのライブラリの動作、コンテナーで発生することのある起動時の問題、およびその解決方法を説明します。

背景

多くのお客様は、オペレーティングシステムが FIPS モードで動作するホストにデプロイしています。Linux では、これは /proc/sys/crypto/fips_enabled = 1 として示されます。このモードでは、プラットフォームの暗号化プロバイダー(Linux では OpenSSL)が、すべての暗号化操作を認定済みの FIPS モジュールを通じて処理することが求められます。

よくある問題は、コンテナーがホストの FIPS フラグを引き継いでいるのに、そのベースイメージに認定済みの OpenSSL FIPS プロバイダーが含まれていない場合に起こります。この場合、OpenSSL 3 は FIPS モードに入ろうとして FIPS プロバイダーモジュールの読み込みに失敗し、壊れた状態になります。この状態では、FIPS が通常禁止する操作だけでなく、ダイジェストと暗号の操作がすべて失敗します。典型的なエラーは次のとおりです。

Interop+Crypto+OpenSslCryptographicException: error:03000086:digital envelope routines::initialization error

これは環境に起因する状態であり、Babel Licensing の欠陥ではありません。Babel とは関係なく文書化されています。dotnet/dotnet-docker#5849  と dotnet/runtime#87884  を参照してください。ライセンス検証だけでなく、TLS(HttpClient、gRPC)を含め、プロセス内で OpenSSL を使用するすべての .NET 暗号化処理に影響します。

ライセンス検証での現れ方

OpenSSL のレイヤー全体が使用できないため、起動時に最初に実行される暗号化操作で障害が現れます。ライセンスに有効期限がある場合、Babel Licensing は、期限の追跡と時計の巻き戻しの検出に使用する小さなローカルストアを開きます。最新の .NET では、ストアの初期化時にプラットフォームのプロバイダーを通じて ID ハッシュが計算されますが、FIPS が壊れたホストではここで例外がスローされます。この障害は次のように報告されます。

Babel.Licensing.BabelLicenseException: Internal error ---> ...OpenSslCryptographicException: error:03000086:...

強化(Babel Licensing 11.7.x 以降):ライセンスストアが作り直され、プラットフォームの暗号化スタックが壊れていてもライセンス検証が失敗しなくなりました。ストアは完全なマネージド実装に透過的にフォールバックし、ライセンス検証は失敗せずに、機能を縮小して継続します。正常なホストでは動作は変わりません。それより前のビルドでは、後述の環境の修正を適用してください。

コンテナーでの解決

コンテナー内で OpenSSL を使える状態にします。次のどちらのオプションでも、ライセンス検証の症状に加えて、プロセス内で OpenSSL を使用するほかのすべての操作の問題も解消されます。

オプション 1:コンテナーで FIPS に自動的に入らないようにする

Ubuntu ベースの .NET イメージでは、OpenSSL は環境変数 OPENSSL_FORCE_FIPS_MODE に従います。これを 0 に設定すると、OpenSSL は、イメージに含まれていないプロバイダーで FIPS モードに入ろうとしなくなります。

docker-compose.yml では、licensing サービスの environment に追加します。

environment: # Do not auto-enter FIPS mode using a provider the image doesn't ship OPENSSL_FORCE_FIPS_MODE: 0

または、Dockerfile に記述します。

ENV OPENSSL_FORCE_FIPS_MODE=0

この方法は、コンテナー自体が FIPS 検証済みである必要がない場合に使用します。ホストは FIPS が有効なままで、このコンテナーの OpenSSL だけが、壊れた FIPS の自動有効化を回避します。

オプション 2:認定済みの FIPS プロバイダーを含むベースイメージを使用する

コンテナーの内部で FIPS 準拠が求められる場合は、検証済みの FIPS プロバイダーを含むベースイメージで実行してください。そうすれば、暗号化レイヤーは失敗せずに正しく初期化されます。

  • Azure Linux 3.0 の .NET イメージ(mcr.microsoft.com/dotnet/aspnet:8.0-azurelinux3.0 など)。Microsoft の FIPS 認定済み SymCrypt プロバイダーが含まれています
  • Red Hat UBI 9 ベースの .NET イメージ(registry.access.redhat.com/ubi9/dotnet-90 など)
  • FIPS 認定済みの OpenSSL パッケージを備えた Ubuntu Pro

FIPS ホストでの Babel Licensing Service

Babel Licensing Service は、イメージに FIPS プロバイダーモジュールが実際に含まれている限り、FIPS が有効なホストで動作します。Microsoft の FIPS 認定済み SymCrypt プロバイダーを .NET イメージに含む Azure Linux 3.0 で、FIPS を強制した状態で、ライセンスのワークフロー全体について次の点を検証済みです。

  • サービスが起動し、自身のライセンスを検証する
  • ライセンステンプレートと RSA 署名付きライセンスが作成される
  • クライアントが gRPC 経由でライセンスをアクティベートし、検証する
  • ノードロック、アクティベーショントークン、ハートビート、アクティベーション解除がすべて機能する

FIPS モジュールがない場合に起こること

重要な違いは、「FIPS がオンかオフか」ではなく、FIPS モードが必要とするプロバイダーモジュールが存在するかどうかです。

OpenSSL 3 は、アルゴリズムを自身では実装せず、プラグイン形式のプロバイダーから読み込みます。FIPS モードの構成では、すべてのアルゴリズムを認定済みの FIPS プロバイダー(fips.so モジュール)から取得する必要があります。標準の Debian/Ubuntu の .NET イメージのように、このモジュールがイメージにインストールされていない場合、OpenSSL はどの要求にも応えられないため、FIPS 自体が許可しているものを含め、すべてのアルゴリズムが失敗します。

Linux 上の .NET は暗号化処理をすべて OpenSSL に委ねているため、影響はハッシュと暗号にとどまりません。

.NET の操作fips.so がない場合の結果
SHA256 / SHA1error:03000086 ...initialization error
Aeserror:0308010C ...unsupported
RandomNumberGeneratorerror:12000090 ...unable to fetch drbg

乱数生成さえ失敗するため、このようなホストでは ASP.NET Core アプリケーションはまったく起動できません。起動時に乱数(データ保護キー、TLS)が必要になるためです。これは Babel Licensing Service に限らず、すべての ASP.NET Core アプリケーションに影響します。原因は環境の構成ミスで、FIPS を提供できないイメージに FIPS が要求されています。前述のオプション 1 またはオプション 2 で解決してください。

環境の検証

コンテナー内で次のように簡単に確認すると、OpenSSL が正常かどうかがわかります。

# Fails on a broken-FIPS host, succeeds once fixed echo test | openssl dgst -sha1
  • error:03000086(または fips.so を読み込めないというメッセージ)で失敗する場合:OpenSSL は壊れた状態です。オプション 1 または 2 を適用してください。
  • 通常の SHA1(stdin)= ... の行が出力される場合:OpenSSL は正常で、Babel Licensing は通常どおり動作します。

ライセンス検証が強化されていても、OpenSSL の環境は修正することをお勧めします。修正しないと、プロセス内で OpenSSL を使用するほかの操作(特に Babel Licensing Service への TLS 接続)は引き続き失敗します。

Last updated on