Ignore invalid self-signed ssl certificate in node.js with https.request?
我正在开发一个登录到本地无线路由器(Linksys)的小应用程序,但是我遇到了路由器的自签名ssl证书问题。
我运行wget 192.168.1.1并得到:
1 2 3 4 | 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/[email protected]': 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'. |
在节点中,捕获的错误是:
1 | { [Error: socket hang up] code: 'ECONNRESET' } |
我当前的示例代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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"?
便宜又不安全的答案:
加
1 | process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; |
在代码中,在调用
在此问题中回答了一种更安全的方法(上述解决方案使整个节点进程不安全)
在您的请求选项中,尝试包括以下内容:
1 2 3 4 5 6 7 8 9 | var req = https.request({ host: '192.168.1.1', port: 443, path: '/', method: 'GET', rejectUnauthorized: false, requestCert: true, agent: false }, |
不要相信所有试图误导您的人。
在您的请求中,只需添加:
1 | ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})] |
如果您打开了未经授权的证书,那么您将完全不受保护(暴露于MITM以验证身份),并且在没有SSL的情况下进行工作也不会有太大的不同。解决方案是指定您期望的CA证书,如下面的代码片段所示。确保证书的通用名称与您在请求中调用的地址相同(在主机中指定):
然后您将获得:
1 2 3 4 5 6 7 8 9 10 | 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证书以模拟生产环境
添加以下环境变量:
1 | NODE_TLS_REJECT_UNAUTHORIZED=0 |
例如使用
1 | export NODE_TLS_REJECT_UNAUTHORIZED=0 |
(非常感谢Juanra)
添加到@Armand答案:
Add the following environment variable:
NODE_TLS_REJECT_UNAUTHORIZED=0 e.g. with export:
export NODE_TLS_REJECT_UNAUTHORIZED=0 (with great thanks to Juanra)
如果您在Windows上使用:
1 | set NODE_TLS_REJECT_UNAUTHORIZED=0 |
感谢:@ weagle08
您还可以使用默认选项创建请求实例:
1 | require('request').defaults({ rejectUnauthorized: false }) |
对于meteorJS,可以使用npmRequestOptions进行设置。
1 2 3 4 5 6 7 8 9 10 | 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 | 192.168.1.1 Linksys |
接下来
1 2 3 4 5 6 | var req = https.request({ host: 'Linksys', port: 443, path: '/', method: 'GET' ... |
将工作。