0

I want to create a simple proxy for requests to arbitrary websites with Node.js (http-node-proxy) (and TypeScript for my case). I know that several questions exist on this difficult topic, but none of them helped me so far. I tried:

import axios from 'axios';
import http from 'http';
import httpProxy from 'http-proxy';
import url from 'url';

async function mainHTTP() {
  // create the proxy
  const proxy = httpProxy.createProxy({});
  const server = http.createServer(function(request, response) {
    console.log([request.url, response.statusCode]);
    const requestURL = new url.URL(request.url!);
    const target = `${requestURL.protocol}//${requestURL.host}`;
    proxy.web(request, response, {target: target});
  });
  server.listen(8080);

  // make an example request
  const response = await axios.request({
    'url': 'http://www.example.org',
    'proxy': {host: 'localhost', port: 8080},
  });
  console.log(response);
}
mainHTTP();

And this works fine! But only for HTTP requests. So I tried the same thing "translated" to HTTPS:

// ...
import fs from 'fs';
import https from 'https';

async function mainHTTPs() {
  // create the proxy
  const proxy = httpProxy.createProxy({});
  const ssl = { // keys tested, they work in other situations
    'key': fs.readFileSync('key.pem'),
    'cert': fs.readFileSync('cert.pem'),
  }
  const server = https.createServer(ssl, function(request, response) {
    console.log([request.url, response.statusCode]); // error happens before this is executed!
    const requestURL = new url.URL(request.url!);
    const target = `${requestURL.protocol}//${requestURL.host}`;
    proxy.web(request, response, {target: target});
  });
  server.listen(8080);
  server.on('tlsClientError', (err) => console.log(err)); // added for debugging

  // make an example request
  const response = await axios.request({
    'url': 'https://www.example.org',
    'proxy': {host: 'localhost', port: 8080},
  });
  console.log(response);
}
mainHTTPs();

But now I get suddenly a "socket hang up" error. The debugging line gives me the following cryptic error:

"Error: 9356:error:1408F09C:SSL routines:ssl3_get_record:http request:c:\ws\deps\openssl\openssl\ssl\record\ssl3_record.c:322:".

Note that the error happens before the call to proxy.web, so I assume it should not be caused by the proxying itself.

Does anyone understand this error and can help me with getting rid of it?

Remirror
  • 692
  • 5
  • 14
  • Are you sure the used certificate and key are a valid HTTPS certificate for the domain the client tries to access through the proxy (e.g. matching domain name)? Have you added the certificate as trusted for the client application? – Robert Oct 12 '20 at 16:16
  • Actually, I am very new to HTTPs. I have generated the keys using OpenSSL (self-signed certificate). I am not sure how to assert that the certificates are valid for the domain to access because this domain varies from request to request. However, a browser is also able to do that, so it should be possible. – Remirror Oct 13 '20 at 07:24
  • 1
    I am sorry but if you don't understand how the web CA system works and how HTTP intercepting proxys come into play you should stick with an existing proxy that does this for you. I would recommend e.g. mitmproxy to you (Python based) it does handle the certificate generation for you, you just have to follow the tutorials. – Robert Oct 13 '20 at 07:31
  • Is it really that difficult? I actually thought my solution were close to working. I don't need extended capabilities, essentially just logging each request and response. – Remirror Oct 13 '20 at 07:38
  • I don't get why you have localhost as proxy; it should be a proxy IP – John Balvin Arias Oct 14 '20 at 18:31
  • The idea is to intercept all requests made in the browser locally, e.g. in order to log or even modify them. – Remirror Oct 14 '20 at 18:46

0 Answers0