Communityコーディング&開発github.com

dotnet-devcert-trust

.NET HTTPS開発証明書の信頼問題をLinux上で診断・修正します。証明書の生成からシステムCAバンドルへの組み込みまで完全なライフサイクルをカバーし、Ubuntu、Fedora、Arch、WSL2向けのディストリビューション固有ガイダンスを提供します。

dotnet-devcert-trust とは?

このスキルは、Linux環境における.NET HTTPS開発証明書の信頼問題を解決するための包括的なガイドを提供します。WindowsやmacOSとは異なり、Linuxでは `dotnet dev-certs https --trust` がシステムレベルの信頼を自動的に設定しないため、証明書が信頼されず、Redis TLS接続やHTTPSローカルホストアクセスが失敗する問題が頻繁に発生します。このスキルは、証明書の存在確認、システムトラストストアへのインストール、CAバンドルの再構築、環境変数のオーバーライド、シンボリックリンクの整合性チェックという5段階の診断手順を提供し、各段階で失敗した場合の具体的な修正コマンドを示します。さらに、Ubuntu/Debian、Fedora/RHEL、Arch Linux、WSL2といった主要なLinuxディストリビューションごとに異なる証明書管理方法(ディレクトリやコマンドの違い)に対応しており、Aspire 13.1.0以降でデフォルト有効化されたRedis TLS接続の失敗にも効果的に対処できます。CI/CDパイプライン(GitHub Actions、Azure DevOps)での自動化手順も含まれており、開発者にとって実用的なトラブルシューティングツールです。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Aaronontheweb/dotnet-skills/tree/main/skills/dotnet-devcert-trust

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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 では、ほとんど役に立ちません。このコマンドは証明書を生成してユーザーストアに配置しますが、以下の処理を行いません:

  1. システム CA ディレクトリに証明書をエクスポートしない
  2. CA バンドルを再構築するために update-ca-certificates を実行しない
  3. ブラウザのトラストストア(NSS/NSSDB)に証明書を追加しない
  4. --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: OKPASS — 証明書が統合バンドルに存在
error 20 at 0 depth lookup: unable to get local issuer certificateFAIL — バンドルが再構築されていない
error 2 at 0 depth lookup: unable to get issuer certificateFAIL — 同じ問題、異なる 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/DebianFedora/RHEL
CA ディレクトリ/usr/local/share/ca-certificates//etc/pki/ca-trust/source/anchors/
再構築コマンドupdate-ca-certificatesupdate-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 の手順が機能しますが、以下に注意してください:

  1. 共有ファイルシステム (/mnt/c/) — Windows ファイルシステム上の証明書ファイルは、644 ではない Windows 権限を持つ場合があります。常に最初にネイティブの Linux パスにコピーしてください。
  2. systemd が実行されていない — 一部の古い WSL2 セットアップでは systemd が実行されておらず、update-ca-certificates のフックがそれに依存する場合があります。コマンドがハングする場合は、代わりに sudo dpkg-reconfigure ca-certificates を試してください。
  3. 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 年間有効です。期限が切れた場合:

  1. dotnet dev-certs https --check は有効な証明書がないと報告します
  2. 完全復旧手順を実行して新しい証明書を生成します
  3. /usr/local/share/ca-certificates/ の古い証明書ファイルは置き換えられます
  4. 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 開発証明書の信頼管理は、プラットフォームのネイティブサポートがないため、手動の手順が必要です。このスキルは以下を提供します:

  1. 診断: 証明書の問題を特定する 5 段階のチェックリスト
  2. 修正: 環境をクリーンな状態にリセットする完全復旧スクリプト
  3. 理解: 証明書が Linux でどのように信頼されるかについての説明
  4. 移植性: 複数のディストリビューションと WSL2 をカバー
  5. 自動化: CI/CD パイプラインへの統合手順

この手順に従うことで、Aspire、.NET アプリケーション、およびすべての TLS 対応サービスが開発証明書を正しく信頼するようになります。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

akka-hosting-actor-patterns

Patterns for building entity actors with Akka.Hosting - GenericChildPerEntityParent, message extractors, cluster sharding abstraction, akka-reminders, and ITimeProvider. Supports both local testing and clustered production modes.

akka-net-aspire-configuration

Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management integration, and Aspire orchestration patterns.

akka-net-best-practices

Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.

akka-net-management

Akka.Management for cluster bootstrapping, service discovery (Kubernetes, Azure, Config), health checks, and dynamic cluster formation without static seed nodes.

akka-net-testing-patterns

Write unit and integration tests for Akka.NET actors using modern Akka.Hosting.TestKit patterns. Covers dependency injection, TestProbes, persistence testing, and actor interaction verification. Includes guidance on when to use traditional TestKit.

api-design

Design stable, compatible public APIs using extend-only design principles. Manage API compatibility, wire compatibility, and versioning for NuGet packages and distributed systems.

aspire-configuration

Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.

aspire-integration-testing

Write integration tests using .NET Aspire

aspire-service-defaults

Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.

crap-analysis

Analyze code coverage and CRAP (Change Risk Anti-Patterns) scores to identify high-risk code. Use OpenCover format with ReportGenerator for Risk Hotspots showing cyclomatic complexity and untested code paths.

csharp-concurrency-patterns

Choosing the right concurrency abstraction in .NET - from async/await for I/O to Channels for producer/consumer to Akka.NET for stateful entity management. Avoid locks and manual synchronization unless absolutely necessary.

database-performance

Database access patterns for performance. Separate read/write models, avoid N+1 queries, use AsNoTracking, apply row limits, and never do application-side joins. Works with EF Core and Dapper.

dependency-injection-patterns

Organize DI registrations using IServiceCollection extension methods. Group related services into composable Add* methods for clean Program.cs and reusable configuration in tests.

dotnet-local-tools

Managing local .NET tools with dotnet-tools.json for consistent tooling across development environments and CI/CD pipelines.

dotnet-project-structure

Modern .NET project structure including .slnx solution format, Directory.Build.props, central package management, SourceLink, version management with RELEASE_NOTES.md, and SDK pinning with global.json.

dotnet-slopwatch

Use Slopwatch to detect LLM reward hacking in .NET code changes. Run after every code modification to catch disabled tests, suppressed warnings, empty catch blocks, and other shortcuts that mask real problems.

efcore-patterns

Entity Framework Core best practices including NoTracking by default, query splitting for navigation collections, migration management, dedicated migration services, and common pitfalls to avoid.

ilspy-decompile

Understand implementation details of .NET code by decompiling assemblies. Use when you want to see how a .NET API works internally, inspect NuGet package source, view framework implementation, or understand compiled .NET binaries.

mailpit-integration

Test email sending locally using Mailpit with .NET Aspire. Captures all outgoing emails without sending them. View rendered HTML, inspect headers, and verify delivery in integration tests.

marketplace-publishing

Workflow for publishing skills and agents to the dotnet-skills Claude Code marketplace. Covers adding new content, updating plugin.json, validation, and release tagging.

関連スキル