Linux 上の .NET 開発証明書の信頼設定
このスキルを使用するタイミング
以下の状況でこのスキルを使用します:
- Aspire で Redis TLS 接続が
UntrustedRootまたはRemoteCertificateNameMismatchで失敗する場合 dotnet dev-certs https --check --trustが終了コード 7 を返す場合- HTTPS ローカルホスト接続が証明書検証エラーで失敗する場合
dotnet dev-certs https --clean実行後に信頼を復元する必要がある場合- .NET HTTPS 開発用に新しい Linux 開発マシンをセットアップする場合
- Aspire ダッシュボードまたはサービス間 gRPC 呼び出しが TLS エラーで失敗する場合
- Aspire < 13.1.0 からアップグレードする場合(デフォルトでは Redis に TLS を使用していなかったため)
問題
Windows と macOS では、dotnet dev-certs https --trust がすべてを自動的に処理します。証明書を生成し、ユーザーストアにインストールし、システムトラストストアに追加します。Linux では、ほとんど役に立ちません。このコマンドは証明書を生成してユーザーストアに配置しますが、以下の処理を行いません:
- システム CA ディレクトリに証明書をエクスポートしない
- CA バンドルを再構築するために
update-ca-certificatesを実行しない - ブラウザのトラストストア(NSS/NSSDB)に証明書を追加しない
--trustフラグは静かに成功するが、証明書は信頼されないまま
つまり、dotnet dev-certs https --check が存在を報告しているにもかかわらず、.NET アプリケーション、OpenSSL、curl、ブラウザはすべて開発証明書を拒否します。
これが Aspire 13.1.0 以降で表面化する理由
Aspire 13.1.0 より前は、Redis 接続はプレーンテキストを使用していました。13.1.0 以降、Aspire はデフォルトで Redis に TLS を有効にします。開発証明書がシステムレベルで信頼されていない場合、Redis 接続はすぐに次のエラーで失敗します:
System.Security.Authentication.AuthenticationException:
The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Linux の証明書信頼の仕組み
アーキテクチャを理解することで、決め打ちのデバッグを防げます:
┌─────────────────────────────────────────────────────┐
│ アプリケーション (.NET、curl、OpenSSL) │
│ 読み取り先: /etc/ssl/certs/ca-certificates.crt │
│ (統合 CA バンドル) │
└──────────────────────┬──────────────────────────────┘
│ 構築元
┌──────────────────────▼──────────────────────────────┐
│ update-ca-certificates │
│ 読み取り元: │
│ /usr/share/ca-certificates/ (ディストリビューション CA) │
│ /usr/local/share/ca-certificates/ (ローカル CA) │
│ 書き込み先: │
│ /etc/ssl/certs/ca-certificates.crt (バンドル) │
│ /etc/ssl/certs/*.pem (個別シンボリックリンク) │
└─────────────────────────────────────────────────────┘
重要な洞察: .crt ファイルを /usr/local/share/ca-certificates/ に配置することは必要ですが、十分ではありません。統合バンドル /etc/ssl/certs/ca-certificates.crt は、update-ca-certificates を実行して再構築する必要があります。アプリケーションは個別のファイルではなく、バンドルを読み取ります。
5段階診断手順
これらのチェックを順番に実行します。最初の FAIL で停止し、修正を適用してから続行します。
チェック 1: 開発証明書の存在
dotnet dev-certs https --check
echo "Exit code: $?"
| 終了コード | 意味 | アクション |
|---|---|---|
| 0 | 証明書がユーザーストアに存在 | PASS — 続行 |
| 0以外 | 有効な開発証明書なし | dotnet dev-certs https を実行 |
チェック 2: システムトラストストア — 単一証明書、正しい権限
ls -la /usr/local/share/ca-certificates/ | grep -iE 'dotnet|aspnet'
| 結果 | 意味 |
|---|---|
dotnet-dev-cert.crt のみ、かつ -rw-r--r-- (644) | PASS |
複数の証明書ファイル、間違った権限、または古い aspnet* ファイル | FAIL |
以前のセッションからの一般的な古いファイル:
| ファイル | 問題 |
|---|---|
aspnetcore-dev.crt | 多くの場合 0600 権限で作成される(update-ca-certificates が読み取り不可) |
aspnet/https.crt | 古い規約、現在の開発証明書とは異なるフィンガープリントの可能性あり |
dotnet-dev-cert.crt で 0600 | 正しい名前だが権限が間違っている |
修正:
# すべての古い証明書ファイルを削除
sudo rm -f /usr/local/share/ca-certificates/aspnetcore-dev.crt
sudo rm -rf /usr/local/share/ca-certificates/aspnet/
# 開発証明書の権限を修正(存在する場合)
sudo chmod 644 /usr/local/share/ca-certificates/dotnet-dev-cert.crt
チェック 3: CA バンドルへの組み込み
これは最も頻繁に失敗するチェックです。証明書ファイルは存在しますが、バンドルに追加されたことはありません。
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/usr/local/share/ca-certificates/dotnet-dev-cert.crt
| 結果 | 意味 |
|---|---|
dotnet-dev-cert.crt: OK | PASS — 証明書が統合バンドルに存在 |
error 20 at 0 depth lookup: unable to get local issuer certificate | FAIL — バンドルが再構築されていない |
error 2 at 0 depth lookup: unable to get issuer certificate | FAIL — 同じ問題、異なる OpenSSL バージョン |
修正:
sudo update-ca-certificates
# 期待される出力には "1 added" などが含まれます
# 再検証
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/usr/local/share/ca-certificates/dotnet-dev-cert.crt
チェック 4: 環境変数のオーバーライド
SSL 環境変数は証明書の参照先をシステムバンドルからリダイレクトする可能性があります:
echo "SSL_CERT_DIR=${SSL_CERT_DIR:-<unset>}"
echo "SSL_CERT_FILE=${SSL_CERT_FILE:-<unset>}"
echo "DOTNET_SSL_CERT_DIR=${DOTNET_SSL_CERT_DIR:-<unset>}"
echo "DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=${DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER:-<unset>}"
| 結果 | 意味 |
|---|---|
すべて <unset> | PASS |
| いずれかの変数が設定されている | FAIL — 証明書参照がリダイレクトされている可能性あり |
修正: シェルプロファイル(~/.bashrc、~/.zshrc、~/.profile)から該当する変数を削除し、新しいシェルを起動します。
チェック 5: シンボリックリンクの整合性
以前に削除された証明書からの古いシンボリックリンクは OpenSSL を混乱させる可能性があります:
find /etc/ssl/certs/ -xtype l 2>/dev/null | head -5
| 結果 | 意味 |
|---|---|
| 出力なし | PASS |
| 壊れたシンボリックリンクがリストされる | FAIL |
修正:
sudo update-ca-certificates --fresh
# すべてのシンボリックリンクをゼロから再構築
完全復旧手順
複数のチェックが失敗した場合、またはクリーンな状態から始めたい場合は、この完全なシーケンスを実行します:
#!/usr/bin/env bash
set -euo pipefail
echo "=== .NET 開発証明書の信頼復旧 ==="
# ステップ 1: すべての古い証明書ファイルを削除
echo "--- 古い証明書ファイルを削除 ---"
sudo rm -f /usr/local/share/ca-certificates/aspnetcore-dev.crt
sudo rm -rf /usr/local/share/ca-certificates/aspnet/
sudo rm -f /usr/local/share/ca-certificates/dotnet-dev-cert.crt
# ステップ 2: 開発証明書をクリーンして再生成
echo "--- 開発証明書を再生成 ---"
dotnet dev-certs https --clean
dotnet dev-certs https
# ステップ 3: PEM としてエクスポートし、システムトラストストアにインストール
echo "--- システムトラストストアにインストール ---"
dotnet dev-certs https --export-path /tmp/dotnet-dev-cert.crt --format PEM --no-password
sudo cp /tmp/dotnet-dev-cert.crt /usr/local/share/ca-certificates/dotnet-dev-cert.crt
sudo chmod 644 /usr/local/share/ca-certificates/dotnet-dev-cert.crt
rm /tmp/dotnet-dev-cert.crt
# ステップ 4: CA バンドルを再構築(重要 — 最も見落とされがちな手順)
echo "--- CA バンドルを再構築 ---"
sudo update-ca-certificates
# ステップ 5: 検証
echo "--- 検証 ---"
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \
/usr/local/share/ca-certificates/dotnet-dev-cert.crt
echo "=== 完了!.NET アプリケーションを再起動してください。 ==="
これを ~/fix-devcert.sh として保存し、必要に応じて bash ~/fix-devcert.sh で実行します。
ディストリビューション固有の注意事項
Ubuntu / Debian
上記の手順は Ubuntu/Debian 向けに書かれており、そのまま動作します。
- CA ディレクトリ:
/usr/local/share/ca-certificates/ - バンドルコマンド:
sudo update-ca-certificates - バンドル出力:
/etc/ssl/certs/ca-certificates.crt - 証明書形式:
.crt拡張子の PEM が必要
Fedora / RHEL / CentOS
Fedora は update-ca-certificates の代わりに update-ca-trust を使用します:
# 証明書をエクスポート
dotnet dev-certs https --export-path /tmp/dotnet-dev-cert.pem --format PEM --no-password
# Fedora トラストストアにインストール(異なるディレクトリ!)
sudo cp /tmp/dotnet-dev-cert.pem /etc/pki/ca-trust/source/anchors/dotnet-dev-cert.pem
sudo chmod 644 /etc/pki/ca-trust/source/anchors/dotnet-dev-cert.pem
rm /tmp/dotnet-dev-cert.pem
# トラストバンドルを再構築
sudo update-ca-trust
# 検証
openssl verify /etc/pki/ca-trust/source/anchors/dotnet-dev-cert.pem
主な違い:
| Ubuntu/Debian | Fedora/RHEL | |
|---|---|---|
| CA ディレクトリ | /usr/local/share/ca-certificates/ | /etc/pki/ca-trust/source/anchors/ |
| 再構築コマンド | update-ca-certificates | update-ca-trust |
| バンドルパス | /etc/ssl/certs/ca-certificates.crt | /etc/pki/tls/certs/ca-bundle.crt |
| 拡張子 | .crt | .pem(どの拡張子でも動作) |
Arch Linux
Arch は Fedora と同じ update-ca-trust アプローチを使用します:
sudo cp /tmp/dotnet-dev-cert.pem /etc/ca-certificates/trust-source/anchors/dotnet-dev-cert.pem
sudo chmod 644 /etc/ca-certificates/trust-source/anchors/dotnet-dev-cert.pem
sudo update-ca-trust
WSL2
WSL2 は独自の証明書ストアを持つ実際の Linux カーネルを実行します — Windows ホストとは別です。標準的な Ubuntu/Debian の手順が機能しますが、以下に注意してください:
- 共有ファイルシステム (
/mnt/c/) — Windows ファイルシステム上の証明書ファイルは、644 ではない Windows 権限を持つ場合があります。常に最初にネイティブの Linux パスにコピーしてください。 - systemd が実行されていない — 一部の古い WSL2 セットアップでは systemd が実行されておらず、
update-ca-certificatesのフックがそれに依存する場合があります。コマンドがハングする場合は、代わりにsudo dpkg-reconfigure ca-certificatesを試してください。 - Docker Desktop 統合 — Docker Desktop の WSL2 バックエンドを使用している場合、コンテナは WSL2 ディストリビューションの CA バンドルを継承します。WSL2 で信頼を修正すると、コンテナでも修正されます。
Aspire 固有の考慮事項
Redis TLS(Aspire 13.1.0+)
Aspire 13.1.0 はデフォルトで Redis に TLS を有効にします。Redis 接続エラーで次のメッセージが表示される場合:
UntrustedRoot
開発証明書がシステムレベルで信頼されていません。上記の完全復旧手順を実行してください。
Aspire ダッシュボード HTTPS
Aspire ダッシュボードは HTTPS に開発証明書を使用します。ブラウザに証明書の警告が表示される場合、証明書がブラウザのトラストストアにありません。開発目的では、警告をクリックして通過することは許容されます — システムレベルの信頼(Redis、gRPC などに必要)が優先されます。
ASPIRE_ALLOW_UNSECURED_TRANSPORT
ASPIRE_ALLOW_UNSECURED_TRANSPORT=true を設定することは、修正ではなく回避策です。これにより、サービス間通信の TLS が無効になり、以下の影響があります:
- 根本的な信頼の問題を隠蔽する
- 本番環境の動作と一致しない
- 本番環境で見られるものとは異なるバグを引き起こす可能性がある
代わりに証明書の信頼を修正してください。
証明書のライフサイクル
開発証明書は作成から 1 年間有効です。期限が切れた場合:
dotnet dev-certs https --checkは有効な証明書がないと報告します- 完全復旧手順を実行して新しい証明書を生成します
/usr/local/share/ca-certificates/の古い証明書ファイルは置き換えられますupdate-ca-certificatesはバンドル内の古い証明書を新しいものに交換します
システムの再起動は不要です。 アプリケーションは次回の TLS ハンドシェイク時に新しいバンドルを取得します(アプリを再起動してください)。
自動化: CI/CD パイプライン
Linux ランナー上の CI/CD では、開発証明書はほとんど必要ありません(通常は実際の証明書に対してテストするか、テストハーネスで TLS 検証を無効にします)。ただし、統合テストで信頼された開発証明書が必要な場合:
GitHub Actions
- name: .NET 開発証明書を信頼
run: |
dotnet dev-certs https
dotnet dev-certs https --export-path /tmp/dotnet-dev-cert.crt --format PEM --no-password
sudo cp /tmp/dotnet-dev-cert.crt /usr/local/share/ca-certificates/dotnet-dev-cert.crt
sudo chmod 644 /usr/local/share/ca-certificates/dotnet-dev-cert.crt
rm /tmp/dotnet-dev-cert.crt
sudo update-ca-certificates
Azure DevOps
- script: |
dotnet dev-certs https
dotnet dev-certs https --export-path /tmp/dotnet-dev-cert.crt --format PEM --no-password
sudo cp /tmp/dotnet-dev-cert.crt /usr/local/share/ca-certificates/dotnet-dev-cert.crt
sudo chmod 644 /usr/local/share/ca-certificates/dotnet-dev-cert.crt
rm /tmp/dotnet-dev-cert.crt
sudo update-ca-certificates
displayName: '.NET 開発証明書を信頼'
よくある落とし穴
1. 証明書は配置されたがバンドルが再構築されていない
症状: /usr/local/share/ca-certificates/ に証明書ファイルが存在するが、openssl verify が失敗する。
原因: ファイルを配置した後に update-ca-certificates が実行されなかった。
修正: sudo update-ca-certificates
これは最も一般的なミスです。CA ディレクトリはバンドル生成プロセスへの入力であり、バンドル自体ではありません。
2. 権限が間違っている古い証明書ファイル
症状: update-ca-certificates は実行されるが、0 added と報告する。
原因: 0600 権限の証明書ファイルは、update-ca-certificates によって読み取れません(root として実行されますが、ワールドリード可能かどうかをチェックするプロセスを通じてファイルを読み取ります)。ファイルは 644 である必要があります。
修正: sudo chmod 644 /usr/local/share/ca-certificates/*.crt
3. 異なるセッションからの複数の証明書ファイル
症状: update-ca-certificates が複数の証明書を追加するが、アプリケーションはまだ失敗する。
原因: 以前の dotnet dev-certs https --clean / 再生成サイクルからの古い証明書ファイルが CA ディレクトリに残っている。古い証明書のフィンガープリントが現在の開発証明書と一致しない。
修正: すべての dotnet* および aspnet* ファイルを削除し、現在の証明書を再エクスポートします。
4. クリーン/再生成後のフィンガープリント不一致
症状: openssl verify は成功するが、.NET がまだ UntrustedRoot を報告する。
原因: /usr/local/share/ca-certificates/ の証明書が以前の開発証明書からエクスポートされた。dotnet dev-certs https --clean && dotnet dev-certs https の後、フィンガープリントが異なる新しい証明書が生成される。
修正: 古い証明書ファイルを削除し、現在の証明書を再エクスポートします(上記の完全復旧手順のステップ 3 を参照)。
5. DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
症状: 証明書がシステムレベルで信頼されているように見えるが、.NET HTTP クライアントが検証をバイパスする。
原因: DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=true は、.NET にシステムの OpenSSL 検証をバイパスさせる可能性があり、.NET が証明書の問題を検出できなくなる。
修正: この環境変数を設定しないでください。通常、内部テストでのみ使用されます。
まとめ
Linux 上の .NET 開発証明書の信頼管理は、プラットフォームのネイティブサポートがないため、手動の手順が必要です。このスキルは以下を提供します:
- 診断: 証明書の問題を特定する 5 段階のチェックリスト
- 修正: 環境をクリーンな状態にリセットする完全復旧スクリプト
- 理解: 証明書が Linux でどのように信頼されるかについての説明
- 移植性: 複数のディストリビューションと WSL2 をカバー
- 自動化: CI/CD パイプラインへの統合手順
この手順に従うことで、Aspire、.NET アプリケーション、およびすべての TLS 対応サービスが開発証明書を正しく信頼するようになります。