リーフ署名を検証できません


142

APIに到達するためにnode.js request.jsを使用しています。このエラーが発生しています

[エラー:UNABLE_TO_VERIFY_LEAF_SIGNATURE]

私の資格情報はすべて正確で有効であり、サーバーは問題ありません。郵便配達員にも同じ依頼をしました。

request({
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

このコードは、実行可能スクリプトexで実行されています。node ./run_file.js、それはなぜですか?サーバーで実行する必要がありますか?


これは長いショットですが、APIがノードプログラムによって渡されるユーザーエージェントを認識していない可能性がありますか?
ヘクターコレア


@HectorCorrea郵便配達で完全にAPIを読むことができました。ノードがそれをできないのはなぜですか?ユーザーエージェントを変更してみましたが、うまくいきませんでした。
ThomasReggi 2013年

回答:


157

:次のコードは危険であり、クライアントとサーバーの間でAPIコンテンツを傍受して変更することができます。

これもうまくいきました

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';


22
私はこれを更新し、回答してくれてありがとうございますが、あなたのセキュリティに積極的に有害です。以下の@ CoolAJ86の回答に従って、不足しているCAを追加する必要があります。
mikemaccana 2014年

4
私はと呼ばれるプラグインNodeJSを使用していますnodemailerし、nodemailer-smtp-transport同じ一般的なコマンドが働いていました。これをcreateTransportオブジェクトに追加する必要があります:tls:{rejectUnauthorized: false}
LukeP

3
@LukePはnodemailerでも同様に安全ではないと思います。名前に手掛かりがあります。Unが承認されていない場合、通常、定義により拒否します。必要なのは、それを正しく認証する方法を見つけることです(他の回答がすでに述べたように、CA証明書を適切に設定することによって)。
ブルーノ、

@Bruno同意します。証明書を使用して正しい方法で設定する必要があります。デモのクイックテストをセットアップしたいだけだったので、投稿したコードはすぐに修正されます。私はコメントでそれの前置きをつけるべきだった。
LukeP

1
@mikemaccanaリクエストが同じサーバー上にあり、あなたが唯一の所有者である場合、セキュリティ上の問題はありません。
Binar Web

89

これはアプリケーションの問題ではなく、中間CAによって署名された証明書の問題です。その事実を受け入れても続行したい場合は、以下を追加してオプションをリクエストします。

rejectUnauthorized: false

完全なリクエスト:

request({
    "rejectUnauthorized": false,
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

私は今、この問題を抱えています。SSLが正しく設定されていない可能性があることを伝えるITチケットを提出しました-私はクレイジーだと私に言いました。この問題を解決するために提供できる情報は他にありますか?
blakev 2013年

これは実際には正しくありません。CoolAJ86とhectorcorreaが言及しているように、証明書は有効ですが、中間CAによって署名されています。
mikemaccana 2014年

80

安全なソリューション

セキュリティをオフにする代わりに、必要な証明書をチェーンに追加できます。最初にnpmからssl-root-casパッケージをインストールします

npm install ssl-root-cas

このパッケージには、ブラウザーが信頼する多くの中間証明書が含まれていますが、ノードはそうではありません。

var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()

不足している証明書を追加します。詳細はこちらをご覧ください:

https://git.coolaj86.com/coolaj86/ssl-root-cas.js

また、次の回答をご覧ください


2
HttpクライアントはWindowsの信頼されたルート証明機関の証明書ストアを使用しませんか?
リチャードコレット14

1
ノードは、バイナリにバンドルされているMozilla証明書を使用し、独自のca配列を提供するたびにオーバーライドします。そのhttpモジュールがOSチェーンも参照するかどうかはわかりません。ただし、OS XのcurlはOSチェーンのみを使用し、手動で指定された証明書を許可しないようです。
coolaj86 14

これはプロセスごとに実行する必要がありますか、または一度実行して証明書をグローバルに更新できますか?
Joshua Snider

証明書は、2つの場所に格納される可能性があります。(1)node.jsバイナリに組み込まれている、(2)オペレーティングシステムのキーストア。証明書が古くなっている場合は、実行中のコードにこれを含める必要があります。ノードバイナリやオペレーティングシステムは変更されません。プロジェクトフォルダのみが変更されます。
coolaj86

1
@Sunkasそれはまさにエラーメッセージが言うことです。もっと簡単に説明する方法がわかりません。これは読み取り専用ファイルであり、編集できません。
coolaj86

45

CoolAJ86のソリューションは正しく、rejectUnauthorizedまたはを使用してすべてのチェックを無効にするなどのセキュリティを損なうことはありませんNODE_TLS_REJECT_UNAUTHORIZED。それでも、追加のCAの証明書を明示的に挿入する必要がある場合があります。

最初に、ssl-root-casモジュールに含まれているルートCAを試しました。

require('ssl-root-cas/latest')
  .inject();

私はまだUNABLE_TO_VERIFY_LEAF_SIGNATUREエラーに終わった。次に、COMODO SSLアナライザーによって接続しているWebサイトの証明書を発行した人物を見つけ、その機関の証明書をダウンロードして、その証明書のみを追加しようとしました。

require('ssl-root-cas/latest')
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

別のエラーが発生しました:CERT_UNTRUSTED。最後に、追加のルートCAを挿入し、「私の」(明らかに中間)CAを含めました。

require('ssl-root-cas/latest')
  .inject()
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

1
COMODO High-Assurance Secure Server CAが発行した証明書を使用してWebサイトに接続していました。ダウンロードページから証明書をダウンロードしました。
Ferdinand Prantl 2014

2
ありがとうございました!私の問題では、このエラーを回避するために証明書のチェーン全体を追加する必要がありました。他の参考のために、この投稿はFirefox経由で必要な
PEM

助けてくれてありがとう。私の場合、結局のところ、ノードではなくSSLサーバーの構成が不適切でした。すべての中間証明書がサーバーにインストールされたわけではありません。
Scott Jungwirth、2015

.cer実行として証明書を取得した場合、これopenssl x509 -inform DER -in YOUR_CERTIFICATE.cer -out YOUR_CERTIFICATE.crt.crt事前に変換します
0x1gene

8

以下のために作成するには、アプリに反応(このエラーがあまりにも発生し、この質問は、#1 Googleの結果です)、あなたはおそらく使用しているHTTPS=true npm startproxy(中package.json)の開発にいくつかのHTTPS API自己署名である自体、ときに行くました。

その場合は、次のproxyように変更することを検討してください。

"proxy": {
  "/api": {
    "target": "https://localhost:5001",
    "secure": false
  }
}

secure は、WebPackプロキシが証明書チェーンをチェックするかどうかを決定し、無効にすると、API自己署名証明書が検証されないため、データを取得できません。


4

非常に行うために誘惑することができるrejectUnauthorized: falseか、process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';それをしません!それはあなたを真ん中の攻撃の男にさらします。

他の答えは、問題が証明書が「中間CAによって署名されている」という事実にあるという点で正しいです。これには簡単な解決策があり、ssl-root-cas追加のCAをノードに挿入したり、ノードに追加したりするサードパーティのライブラリを必要としません。

ノードのほとんどのhttpsクライアントは、解決するリクエストごとにCAを指定できるオプションをサポートしていますUNABLE_TO_VERIFY_LEAF_SIGNATURE。以下は、ノードの組み込みhttpsモジュールを使用した簡単な例です。

import https from 'https';

const options = {
  host: '<your host>',
  defaultPort: 443,
  path: '<your path>',
  // assuming the bundle file is co-located with this file
  ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
  headers: {
    'content-type': 'application/json',
  }
};
https.get(options, res => {
  // do whatever you need to do
})

ただし、ホスティングサーバーでssl設定を構成できる場合、最適なソリューションは、中間証明書をホスティングプロバイダーに追加することです。この方法では、サーバー自体に含まれているため、クライアントリクエスターはCAを指定する必要がありません。個人的にはnamecheap + herokuを使用しています。私にとっての秘訣は、で1つの.crtファイルを作成することでしたcat yourcertificate.crt bundle.ca-bundle > server.crt。次に、このファイルを開き、最初の証明書の後に改行を追加しました。あなたはもっと読むことができます

https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl


このバグは主に本番環境ではなくローカル環境で発生するので、ローカルで実行する場合は問題ありません:process.env ['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
Vivex

@Vivex-SSL
証明書

2

誰かを助けるためにこれをここに置くだけで、私のケースは異なり、少し奇妙なミックスでした。私はこれをスーパーエージェント経由でアクセスされたリクエストで取得していました-問題は証明書(適切に設定されていた)とは何の関係もなく、非同期モジュールのウォーターフォールコールバックを通じてスーパーエージェントの結果を渡していたという事実とすべて関係がありました。修正するには:結果全体を渡すのではなくresult.body、ウォーターフォールのコールバックを渡すだけです。


2

同じ問題がありました。私は@ThomasReggiと@ CoolAJ86ソリューションをフォローし、うまく機能しましたが、ソリューションに満足していません。

「UNABLE_TO_VERIFY_LEAF_SIGNATURE」の問題は、認証設定レベルが原因で発生するためです。

私は@thirdenderソリューションが、あたりのその部分solution.As受け入れるnginxの公式サイトを、彼らは明らかに言及した証明書は、サーバ証明書とチェーン証明書の組み合わせでなければなりません。

ここに画像の説明を入力してください


1

次のようにstrictSSLfalseに設定して試すこともできます。

{  
   url: "https://...",
   method: "POST",
   headers: {
        "Content-Type": "application/json"},
   strictSSL: false
}

0

GoDaddy証明書をサブドメインにインストールした後、Apache設定に問題がありました。私は当初、ノードがサーバー名インジケーター(SNI)を送信しないことが問題であると考えていましたが、そうではありませんでした。https://www.ssllabs.com/ssltest/を使用してサブドメインのSSL証明書を分析すると、エラーチェーンの問題:不完全が返されました。

Apacheディレクティブgd_bundle-g2-g1.crtを介してGoDaddyが提供するファイルを追加した後SSLCertificateChainFile、NodeはHTTPS経由で接続でき、エラーは解消しました。


0

サーバーに中間証明書を含める必要があります。これにより、[エラー:UNABLE_TO_VERIFY_LEAF_SIGNATURE]が解決されます


0

これを安全に解決する別の方法は、次のモジュールを使用することです。

node_extra_ca_certs_mozilla_bundle

このモジュールは、Mozillaが信頼するすべてのルート証明書と中間証明書を含むPEMファイルを生成することにより、コードを変更することなく機能します。次の環境変数を使用できます(Nodejs v7.3以降で動作します)。

NODE_EXTRA_CA_CERTS

上記の環境変数で使用するPEMファイルを生成します。以下を使用してモジュールをインストールできます。

npm install --save node_extra_ca_certs_mozilla_bundle

次に、環境変数を使用してノードスクリプトを起動します。

NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js

生成されたPEMファイルを使用する他の方法は、次の場所にあります。

https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle

注:私は上記のモジュールの作成者です。


0

あなたはノードのpostgresを使用しているので、あなたがこのスレッドに来る場合は/ PGモジュールは、設定よりもよりよい解決策があるNODE_TLS_REJECT_UNAUTHORIZEDか、rejectUnauthorized安全でない接続につながります。

代わりに、tls.connectのパラメーターに一致するように「ssl」オプションを構成します。

{
  ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
  cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
  key: fs.readFileSync('/path/to/client-key.pem').toString(),
  servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}

私は次のように環境変数からこれらのオプションの構文解析を支援するために、モジュールを書いたPGSSLROOTCERTPGSSLCERTPGSSLKEY

https://github.com/programmarchy/pg-ssl


0

次のコマンドは私のために働きました:

> npm config set strict-ssl false
> npm cache clean --force

問題は、不正または信頼できないSSL [Secure Sockets Layer]証明書を使用して、リポジトリからモジュールをインストールしようとしていることです。キャッシュを消去すると、この問題は解決されます。後でそれをtrueにする必要がある場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.