https.request를 사용하여 node.js에서 잘못된 자체 서명 SSL 인증서를 무시합니까?


308

로컬 무선 라우터 (Linksys)에 로그인하는 작은 응용 프로그램을 만들고 있지만 라우터 자체 서명 SSL 인증서에 문제가 있습니다.

wget 192.168.1.1을 실행하고 다음을 얻습니다.

ERROR: cannot verify 192.168.1.1's certificate, issued by `/C=US/ST=California/L=Irvine/O=Cisco-Linksys, LLC/OU=Division/CN=Linksys/emailAddress=support@linksys.com':
Self-signed certificate encountered.
ERROR: certificate common name `Linksys' doesn't match requested host name `192.168.1.1'.
To connect to 192.168.1.1 insecurely, use `--no-check-certificate'.

노드에서 발생하는 오류는 다음과 같습니다.

{ [Error: socket hang up] code: 'ECONNRESET' }

내 현재 샘플 코드는 다음과 같습니다

var req = https.request({ 
    host: '192.168.1.1', 
    port: 443,
    path: '/',
    method: 'GET'

}, function(res){

    var body = [];
    res.on('data', function(data){
        body.push(data);
    });

    res.on('end', function(){
        console.log( body.join('') );
    });

});
req.end();

req.on('error', function(err){
    console.log(err);
});

node.js가 "--no-check-certificate"와 동일한 기능을 수행하도록하려면 어떻게해야합니까?

답변:


599

싸고 안전하지 않은 답변 :

더하다

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

전화하기 전에 코드에서 https.request()

더 안전한 방법 (위의 솔루션은 전체 노드 프로세스를 안전하지 않게 만듭니다)이 질문에 대답합니다


2
나를 위해 매력처럼 일했다! 주 응용 프로그램 js 맨 위에 모든 것을 포함시킨 직후 에이 코드를 배치했습니다.
Xedecimal

이것은 NodeJS & SailJS 콤보에서도 작동했습니다. 나는 local.js의 상단에이를 추가
마이클 KORK.

38
프로덕션 환경에서는 모든 종류의 보안 검사를 사용할 수 없으므로 이것을 사용하거나 "rejectUnauthorized"를 사용하지 마십시오.
Jason Walton

3
자체 서명 된 https 노드 서버에서 mocha를 사용하여 테스트를 실행하는 데 문제가 있었고 설명 블록이 테스트를 통과하기 직전에 이것을 추가했습니다.
artis3n

이것은 아마도 문제를 해결하는 가장 안전한 방법은 아닙니다. 참조 stackoverflow.com/questions/20433287/...
매트 페닝 턴

166

요청 옵션에서 다음을 포함하십시오.

   var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },

나를 위해 일했다. 나는 restler를 사용하고 기본적으로 옵션을 전달하지 않았으므로 패치해야했습니다.
Olivier Amblet

2
이것이 작동하려면 사용자 지정 에이전트의 명시 적 인스턴스를 제공해야합니다. 옵션 오브젝트를 작성하고 에이전트를 설정하십시오. 'options.agent = new https.Agent (options);' 그런 다음 'https.request (options)'를 호출하십시오
최대

14
글쎄, 이것은 rejectUnauthorized옵션과 다른 것만으로 나를 위해 일했다
mcont

@ mcont 나는 단지 rejectUnauthorized다른 모든 것 ootb가 좋다는 것을 확인 했다. vs 코드 확장 내에서 사용. 더 나은 PEM 구성을 허용하지만 다음에 할 것입니다.
escape-llc

61

당신을 오도하려는 모든 사람들을 믿지 마십시오.

귀하의 요청에 다음을 추가하십시오.

ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})]

인증되지 않은 인증서를 켜면 전혀 보호되지 않으며 (ID 유효성 검사를 위해 MITM에 노출됨) SSL없이 작업해도 큰 차이가 없습니다. 해결책은 다음 스 니펫에 표시된대로 예상되는 CA 인증서를 지정하는 것입니다. 인증서의 공통 이름이 요청에서 호출 한 주소와 동일해야합니다 (호스트에 지정된대로).

당신이 얻을 것입니다 :

var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})],
      method: 'GET',
      rejectUnauthorized: true,
      requestCert: true,
      agent: false
    },

다음을 이해하려면 이 기사 (공개 :이 답변 작성자가 작성한 블로그 게시물)를 읽으십시오 .

  • CA 인증서 작동 방식
  • 프로덕션 환경을 시뮬레이션하기 위해 쉽게 테스트하기 위해 CA 인증서를 생성하는 방법

7
이것은 작동하며 "오류 : 인증서 체인의 자체 서명 된 인증서"문제를 해결하는 올바른 방법입니다.
RohanRasane

1
왜 fs.readFileSync를 문자열로 저장하지 않고 괄호 안에 넣습니까?
Lelo

Lelo : 대괄호는 배열로 바꿉니다. ca : 다양한 인증서가 필요합니다. 이 파일은 쉼표로 구분 된 인증서 목록이어야하며, 종종 사람들은 내부 기능을 사용하여 PEM 파일을 배열로 변환합니다. 자체 서명 된 cet의 경우 단일 인증서 "해야합니다".
JohnDavid

53

다음 환경 변수를 추가하십시오.

NODE_TLS_REJECT_UNAUTHORIZED=0

export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(후안 라 덕분에)


이것은 실행하려고 할 때 나를 위해 일했다webdriver-manager update
애슐리

3
Windows의 경우 NODE_TLS_REJECT_UNAUTHORIZED = 0으로 설정
Felipe SS

이것은 나의 개발 환경을위한 훌륭한 솔루션이었습니다
David

14

@Armand 답변에 추가 :

다음 환경 변수를 추가하십시오.

NODE_TLS_REJECT_UNAUTHORIZED = 0 예 : 내보내기시 :

수출 NODE_TLS_REJECT_UNAUTHORIZED = 0 (후안 라 덕분에)

Windows 사용의 경우 :

set NODE_TLS_REJECT_UNAUTHORIZED=0

감사합니다 : @ weagle08


12

기본 옵션으로 요청 인스턴스를 작성할 수도 있습니다.

require('request').defaults({ rejectUnauthorized: false })

3

meteorJS의 경우 npmRequestOptions로 설정할 수 있습니다.

HTTP.post(url, {
    npmRequestOptions: {
        rejectUnauthorized: false // TODO remove when deploy
    },
    timeout: 30000, // 30s
    data: xml
}, function(error, result) {
    console.log('error: ' + error);
    console.log('resultXml: ' + result);
});

1

또는 다음과 같이 로컬 이름 확인 ( 대부분의 운영 체제 hosts의 디렉토리 etc에 있는 파일 , 세부 사항이 다름) 을 추가 할 수 있습니다 .

192.168.1.1 Linksys 

그리고 다음

var req = https.request({ 
    host: 'Linksys', 
    port: 443,
    path: '/',
    method: 'GET'
...

작동합니다.


3
이것이 질문에 대답 할 수 있지만이 경우 다음 오류는 DEPTH_ZERO_SELF_SIGNED_CERT 일 것이라고 생각합니다.
Olivier Amblet

1
그래서 어떻게 DEPTH_ZERO_SELF_SIGNED_CERT를 얻습니까? 나는 지금 그것에 뛰어 들고있다.
reza

3
@ 레자 : 옵션에 추가 :rejectUnauthorized: false
오베이

1
나는 이것이 조금 오래되었지만 나중에 참조하기 위해 (올바른 방법으로) 자체 서명 된 인증서의 PEM 인코딩을 가져 와서 옵션을 CA로 옵션에 포함시켜야합니다 (당신은 분명히 필요합니다 에이전트 값을 설정하지만 false 일 수 있습니다. 인증서는 자체 서명되므로 자체 CA로 작동하므로 자체 확인에 사용할 수 있습니다. 그러나 펌웨어를 다운로드 할 수 있으므로 개인 키가 쉽게 손상 될 수 있기 때문에 라우터에서 실제로 가치가 있는지 여부도 의문입니다.
Jonathan Gray
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.