URL을 사용하여 jira 서버에서 파일을 다운로드하려고하는데 오류가 발생합니다. 오류 를 확인하기 위해 코드에 인증서를 포함시키는 방법
:
Error: unable to verify the first certificate in nodejs
at Error (native)
at TLSSocket.<anonymous> (_tls_wrap.js:929:36)
at TLSSocket.emit (events.js:104:17)
at TLSSocket._finishInit (_tls_wrap.js:460:8)
내 Nodejs 코드 :
var https = require("https");
var fs = require('fs');
var options = {
host: 'jira.example.com',
path: '/secure/attachment/206906/update.xlsx'
};
https.get(options, function (http_res) {
var data = "";
http_res.on("data", function (chunk) {
data += chunk;
});
http_res.on("end", function () {
var file = fs.createWriteStream("file.xlsx");
data.pipe(file);
});
});
답변
적절한 루트 인증서를 추가하십시오
이것은 무단 엔드 포인트를 맹목적으로 받아들이는 것보다 항상 훨씬 안전한 옵션이 될 것이며, 이는 마지막 수단으로 만 사용해야합니다.
이것은 추가하는 것만 큼 간단 할 수 있습니다
require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create();
응용 프로그램에.
SSL 루트 CA는 NPM 패키지 (로 여기에 사용)이 문제에 대한 매우 유용한 패키지입니다.
답변
또 다른 더러운 해킹으로 모든 요청이 안전하지 않게됩니다.
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
답변
nodejs의 첫 번째 인증서를 확인할 수 없으므로 무단 거부가 필요합니다.
request({method: "GET",
"rejectUnauthorized": false,
"url": url,
"headers" : {"Content-Type": "application/json",
function(err,data,body) {
}).pipe(
fs.createWriteStream('file.html'));
답변
다운로드하려는 서버가 잘못 구성되었을 수 있습니다. 브라우저에서 작동하더라도 캐시가 비어있는 클라이언트를 확인하는 데 필요한 모든 공용 인증서를 체인에 포함하지 않을 수 있습니다.
SSLlabs 도구에서 사이트를 확인하는 것이 좋습니다. https://www.ssllabs.com/ssltest/
이 오류를 찾으십시오.
이 서버의 인증서 체인이 불완전합니다.
이:
체인 문제 ………… 불완전
답변
unable to verify the first certificate
인증서 체인이 불완전합니다.
연결하려는 웹 서버가 잘못 구성되어 전송 한 인증서 체인에 중간 인증서가 포함되지 않았 음을 의미합니다.
인증서 체인
다음과 같이 보입니다.
- 서버 인증서-중간에서 서명 한 인증서를 저장합니다.
- 중간 인증서-루트가 서명 한 인증서를 저장합니다.
- 루트 인증서-자체 서명 된 인증서를 저장합니다.
중간 인증서는 서버 인증서와 함께 서버에 설치해야합니다.
루트 인증서는 소프트웨어 응용 프로그램, 브라우저 및 운영 체제에 포함되어 있습니다.
인증서를 제공하는 응용 프로그램은 완전한 체인을 보내야합니다. 이는 서버 인증서 자체와 모든 중간체를 의미합니다. 루트 인증서는 클라이언트가 알고 있어야합니다.
문제를 재현
https://incomplete-chain.badssl.com으로 이동브라우저를 사용하여 하십시오.
오류가 표시되지 않습니다 (주소 표시 줄의 자물쇠가 녹색 임). 브라우저가 체인을 완성하는 경향이
있기 때문입니다 가 서버에서 전송되지 않으면 입니다.
이제 Node를 사용하여 https://incomplete-chain.badssl.com에 연결 하십시오 .
// index.js
const axios = require('axios');
axios.get('https://incomplete-chain.badssl.com')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
로그 : ” 오류 : 첫 번째 인증서를 확인할 수 없습니다 “.
해결책
인증서 체인을 직접 작성해야합니다.
하기 위해서:
1 : 누락 된 중간 인증서를 .pem
형식으로 가져와야합니다.
A : 확장 노드에 내장 된 인증서 저장소를 사용 NODE_EXTRA_CA_CERTS
,
2b : 또는 ca
옵션을 사용하여 고유 한 인증서 번들 (중간체 및 루트)을 전달하십시오 .
1. 중간 증명서는 어떻게 받습니까?
사용 openssl
( Git for Windows 와 함께 제공 )
원격 서버의 인증서 세부 사항을 저장하십시오.
openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com | tee logcertfile
우리는 발급자를 찾고 있습니다 (중간 인증서는 서버 인증서의 발급자 / 서명자입니다).
openssl x509 -in logcertfile -noout -text | grep -i "issuer"
서명 인증서의 URI를 제공해야합니다. 다운로드 해:
curl --output intermediate.crt http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
마지막으로 다음과 같이 변환하십시오 .pem
.
openssl x509 -inform DER -in intermediate.crt -out intermediate.pem -text
2a. NODE_EXTRA_CERTS
크로스 환경 을 사용하여 package.json
파일 에서 환경 변수를 설정하고 있습니다.
"start": "cross-env NODE_EXTRA_CA_CERTS=\"C:\\Users\\USERNAME\\Desktop\\ssl-connect\\intermediate.pem\" node index.js"
2b. ca
선택권
이 옵션은 노드의 내장 루트 CA를 덮어 씁니다.
그렇기 때문에 자체 루트 CA를 만들어야합니다. ssl-root-cas를 사용하십시오 .
그런 다음 https
인증서 번들 (루트 및 중간)로 구성된 사용자 정의 에이전트를 작성하십시오 . axios
요청 시이 에이전트를 전달하십시오 .
// index.js
const axios = require('axios');
const path = require('path');
const https = require('https');
const rootCas = require('ssl-root-cas').create();
rootCas.addFile(path.resolve(__dirname, 'intermediate.pem'));
const httpsAgent = new https.Agent({ca: rootCas});
axios.get('https://incomplete-chain.badssl.com', { httpsAgent })
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
사용자 정의 https
에이전트 를 작성하여로 전달하는 axios
대신 https
글로벌 에이전트 에 인증서를 배치 할 수 있습니다 .
// Applies to ALL requests (whether using https directly or the request module)
https.globalAgent.options.ca = rootCas;
자원:
- https://levelup.gitconnected.com/how-to-resolve-certificate-errors-in-nodejs-app-involving-ssl-calls-781ce48daded
- https://www.npmjs.com/package/ssl-root-cas
- https://github.com/nodejs/node/issues/16336
- https://www.namecheap.com/support/knowledgebase/article.aspx/9605/69/how-to-check-ca-chain-installation
- /superuser/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file/
- .crt를 .pem로 변환하는 방법
답변
이것은 실제로 나를 위해 https://www.npmjs.com/package/ssl-root-cas 에서 해결했습니다.
// INCORRECT (but might still work)
var server = https.createServer({
key: fs.readFileSync('privkey.pem', 'ascii'),
cert: fs.readFileSync('cert.pem', 'ascii') // a PEM containing ONLY the SERVER certificate
});
// CORRECT (should always work)
var server = https.createServer({
key: fs.readFileSync('privkey.pem', 'ascii'),
cert: fs.readFileSync('fullchain.pem', 'ascii') // a PEM containing the SERVER and ALL INTERMEDIATES
});
답변
아래와 같이 요청 옵션을 수정하여이 작업을 수행 할 수 있습니다. 자체 서명 된 인증서 또는 누락 된 중개자를 사용하는 경우 strictSSL을 false로 설정하면 요청 패키지가 인증서의 유효성을 검증하지 않습니다.
var options = {
host: 'jira.example.com',
path: '/secure/attachment/206906/update.xlsx',
strictSSL: false
}