由于自签名证书,客户端和代理之间的通信不断失败

Communication between client and proxy keeps failing because of self-signed certificate

我有一个用 Javascript/Node.js 编写的代理应用程序,它使用 http-mitm-proxy 库。

我在另一台机器上也有一个 https 服务器,它将提供文件(目前它只回复 "hello world")。我为此使用了自签名根 CA 和自签名证书(详情如下)。

在第三台机器上,我尝试通过代理访问https文件服务器。我只是为此使用 Firefox(我已经使用我的代理机器的 IP 配置了代理设置)。

我想做的是拦截代理上的 https 流量(即文件)并缓存它(即解密它,将其存储在本地然后传递)。这基本上是中间人攻击。

问题是代理和客户端在通信过程中一直拒绝自签名证书。

我使用找到的步骤 here 生成了 rootCA 和自签名证书。如有必要,我可以提供确切的 values/details。

我在客户端计算机上的 Firefox 中导入了证书,并在代理应用程序代码中使用它们。 我还在客户端和代理机器上的主机文件中添加了适当的条目。

这是我的代码:

// HTTPS 文件服务器:

const https = require('https');
const fs = require('fs');

const options = {
  key:  fs.readFileSync('myupdateproxy.com.key'),
  cert: fs.readFileSync('myupdateproxy.com.crt')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

//代理服务器代码:

'use strict';

var port = 8081;

var path = require('path');
var Proxy = require('http-mitm-proxy');
var proxy = Proxy();


const fs = require('fs');

var chunks1 = [];
var chunks2 = [];

proxy.onCertificateRequired = function(hostname, callback) {
  return callback(null, {
    keyFile:  path.resolve('myupdateproxy.com.key'),
    certFile: path.resolve('myupdateproxy.com.crt')
  });
};

proxy.onError(function(ctx, err, errorKind) {
  // ctx may be null
  var url = (ctx && ctx.clientToProxyRequest) ? ctx.clientToProxyRequest.url : '';
  console.error(errorKind + ' on ' + url + ':', err);
});

proxy.onRequest(function(ctx, callback) {
  console.log('onRequest');
  callback();
});

proxy.onRequestData(function(ctx, chunk, callback) {
  console.log('onRequestData');
  chunks1.push(chunk);
  callback(null, chunk);
});

proxy.onRequestEnd(function(ctx, callback) {
  if (ctx.clientToProxyRequest.socket.remoteAddress !== undefined && 
      ctx.proxyToServerRequest.socket.remoteAddress !== undefined &&
      (Buffer.concat(chunks1)).length > 0)
      {
        console.log('From: ' + ctx.clientToProxyRequest.socket.remoteAddress);
        console.log('To: '   + ctx.proxyToServerRequest.socket.remoteAddress);
        console.log('Size: ' + (Buffer.concat(chunks1)).length);
        console.log('');
      }

  chunks1 = [];

  callback();
});

proxy.onResponse(function(ctx, callback) {
  callback(null);
});

proxy.onResponseData(function(ctx, chunk, callback) {
  chunks2.push(chunk);  
  callback(null, chunk);
});

proxy.onResponseEnd(function(ctx, callback) {
  var total_size=(Buffer.concat(chunks2)).length;

  if (ctx.serverToProxyResponse.socket.remoteAddress !== undefined && 
      ctx.proxyToClientResponse.socket.remoteAddress !== undefined &&
      total_size > 0)
  {
    console.log('From: ' + ctx.serverToProxyResponse.socket.remoteAddress);
    console.log('To: ' + ctx.proxyToClientResponse.socket.remoteAddress);
    console.log('Size: ' + total_size);
    console.log('');
  }

  console.log((Buffer.concat(chunks2)).toString());
  chunks2 = [];  
  callback();
});

proxy.listen({ port: port, sslCaDir: "/home/user/mycerts/" });
console.log('listening on ' + port);

我在代理应用程序中不断收到此错误:

onRequest
PROXY_TO_SERVER_REQUEST_ERROR on /: Error: self signed certificate
    at TLSSocket.onConnectSecure (_tls_wrap.js:1473:34)
    at TLSSocket.emit (events.js:311:20)
    at TLSSocket._finishInit (_tls_wrap.js:916:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:686:12) {
  code: 'DEPTH_ZERO_SELF_SIGNED_CERT'
}

客户端机器上的这条消息(在 Firefox 中):

PROXY_TO_SERVER_REQUEST_ERROR: Error: self signed certificate

有谁知道我做错了什么以及我该如何解决这个问题?

谢谢!

尝试建立从代理到应用的不安全 TLS 连接 - 将此代码段添加到您的代理代码中:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

或者尝试将您的自定义 CA 证书添加到您的系统(其中代理应用程序是 运行)CA 证书。确切的命令取决于使用的 OS.