本文へスキップ
ecdsa.com
curl (OpenSSL backend)curl

エラーメッセージ

curl: (60) SSL certificate problem: self-signed certificate

別の表記

  • curl: (60) SSL certificate problem: self signed certificate
  • curl: (60) SSL certificate OpenSSL verify result: self-signed certificate (18)

OpenSSL 3.0 以降は「self-signed certificate」、OpenSSL 1.1.1 は「self signed certificate」と出力します。新しい curl のリリース(ecdsa.com のテストでは 8.22.0)では「SSL certificate OpenSSL verify result: self-signed certificate (18)」と表記されます。CA のチェーンが存在し、信頼されていないルートで終わる「self-signed certificate in certificate chain」と混同しないでください。

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT (18)

このエラーの意味

サーバーは自身の鍵で署名された(発行者とサブジェクトが同じ)証明書を 1 枚だけ提示しましたが、curl のトラストストアにはその証明書そのものがありません。curl が参照できる CA が背後に存在しないため、検証は深さ 0 で止まります。これは開発用サーバーやアプライアンスでは普通のことで、中間証明書をインストールしても決して解決しません。

発生する理由

修正方法

  1. 1.

    確認したうえで、この証明書だけを信頼する

    社内のエンドポイントが 1 つだけなら、証明書を保存し、信頼できる経路(機器のコンソールや、証明書を作成した管理者)で SHA-256 フィンガープリントを確認してから、--cacert で渡してください。これで curl は、その呼び出しではこの証明書だけを受け入れ、ほかは一切受け入れません。

    bash
    # Fetch the certificate once, compare its fingerprint out of band, then trust exactly that file
    openssl s_client -connect api.example.com:8443 -servername api.example.com </dev/null 2>/dev/null \
      | openssl x509 -out api.example.com.pem
    openssl x509 -in api.example.com.pem -noout -fingerprint -sha256
    curl --cacert api.example.com.pem https://api.example.com:8443/
  2. 2.

    開発環境:ローカル CA から証明書を発行する

    ローカル CA(mkcert、step-ca、または自作のルート)を使えば、1 つのルートを一度信頼するだけで、いくつもの開発用ホストに証明書を発行できます。証明書は自己署名ではなくなるため、ルートがインストールされているすべての環境でエラーが解消されます。

    bash
    # mkcert creates a local CA, installs it into the system and browser stores,
    # and issues certificates signed by it (no longer self-signed)
    mkcert -install
    mkcert api.example.test localhost 127.0.0.1
  3. 3.

    公開ホスト:パブリック CA の証明書をインストールする

    ほかの人やサードパーティのクライアントがアクセスするものはすべて、公的に信頼された CA の証明書を提示すべきです。certbot、lego、Caddy などの ACME クライアントは、証明書を自動的に取得・更新します。

    bash
    # Public names: get a certificate from a public CA, e.g. with certbot (ACME)
    sudo certbot certonly --nginx -d api.example.com
  4. 4.

    一時的な診断:検証を無効にしてサービスを確認する

    -k を付けると curl は証明書のチェックを省略するため、200 が返れば、欠けているのは信頼だけだと確認できます。このオプションを残したままにしてはいけません。確認せずに受け入れた自己署名証明書は、いつでも攻撃者の証明書にすり替えられる可能性があり、curl はそれに気づきません。

    bash
    # Diagnostic only: confirms the service answers when certificate checks are skipped
    curl -sS -k -o /dev/null -w '%{http_code}\n' https://api.example.com:8443/

関連するエラー

署名エラーデータベースをすべて見る