2011-11-17 21 views
17

Zajmuję się tworzeniem aplikacji serwera proxy node.js i chcę, aby obsługiwała ona protokoły HTTP i HTTPS(SSL) (jako serwer).Serwer proxy HTTPS w węźle node.js

obecnie używam node-http-proxy takiego:

const httpProxy = require('http-proxy'), 
     http = require('http'); 

var server = httpProxy.createServer(9000, 'localhost', function(req, res, proxy) { 
    console.log(req.url); 
    proxy.proxyRequest(req, res); 
}); 

http.createServer(function(req, res) { 
    res.end('hello!'); 
}).listen(9000); 

server.listen(8000); 

I konfiguracja moja przeglądarka używać HTTP proxy na localhost:8000 i to działa. Chcę również złapać żądania HTTPS (tj. Skonfigurować przeglądarkę do korzystania z localhost:8000 jako proxy HTTPS i przechwytywać żądania w mojej aplikacji). Czy możesz mi pomóc, jak mogę to zrobić?

PS:

Gdybym subskrybować upgrade przypadku httpProxy obiektu serwera można uzyskać żądania, ale nie wiem jak do przekazania żądania i wysłać odpowiedź do klienta:

server.on('upgrade', function(req, socket, head) { 
    console.log(req.url); 
    // I don't know how to forward the request and send the response to client 
}); 

Każda pomoc będzie doceniona.

Odpowiedz

2

Dokumenty na temat węzłów http-proxy zawierają przykłady. Poszukaj "Proxying to HTTPS from HTTPS" at https://github.com/nodejitsu/node-http-proxy Proces konfiguracji jest nieco inny w każdej przeglądarce. Niektóre mają opcję użycia ustawień proxy dla wszystkich protokołów; niektóre trzeba skonfigurować osobno dla proxy SSL.

7

Stworzyłem HTTP/HTTPS proxy przy pomocy modułu http-proxy: https://gist.github.com/ncthis/6863947

Kodeksu już teraz:

var fs = require('fs'), 
    http = require('http'), 
    https = require('https'), 
    httpProxy = require('http-proxy'); 

var isHttps = true; // do you want a https proxy? 

var options = { 
    https: { 
    key: fs.readFileSync('key.pem'), 
    cert: fs.readFileSync('key-cert.pem') 
    } 
}; 

// this is the target server 
var proxy = new httpProxy.HttpProxy({ 
    target: { 
    host: '127.0.0.1', 
    port: 8080 
    } 
}); 

if (isHttps) 
    https.createServer(options.https, function(req, res) { 
    console.log('Proxying https request at %s', new Date()); 
    proxy.proxyRequest(req, res); 
    }).listen(443, function(err) { 
    if (err) 
     console.log('Error serving https proxy request: %s', req); 

    console.log('Created https proxy. Forwarding requests from %s to %s:%s', '443', proxy.target.host, proxy.target.port); 
    }); 
else 
    http.createServer(options.https, function(req, res) { 
    console.log('Proxying http request at %s', new Date()); 
    console.log(req); 
    proxy.proxyRequest(req, res); 
    }).listen(80, function(err) { 
    if (err) 
     console.log('Error serving http proxy request: %s', req); 

    console.log('Created http proxy. Forwarding requests from %s to %s:%s', '80', proxy.target.host, proxy.target.port); 
    }); 
+1

Link do treści był nieaktualny. Zaktualizowałem go do https://gist.github.com/ncthis/6863947 – david

+1

@david Nieaktualny ponownie – fidev

+0

'httpProxy.HttpProxy nie jest funkcją' –

15

Solutions ledwo istnieje dla tego, a dokumentacja jest słaba w najlepszym wypadku do obsługi zarówno na jednym serwerze. Kluczem jest tutaj zrozumienie, że konfiguracje proxy klienta mogą wysyłać żądania https do serwera proxy HTTP. Dotyczy to przeglądarki Firefox, jeśli określisz serwer proxy HTTP, a następnie zaznaczysz "to samo dla wszystkich protokołów".

Możesz obsługiwać połączenia https wysłane do serwera HTTP, nasłuchując zdarzenia "połącz". Zauważ, że nie będziesz mieć dostępu do obiektu odpowiedzi w zdarzeniu connect, tylko gniazdo i bodyhead. Dane przesyłane przez to gniazdo pozostaną zaszyfrowane jako serwer proxy.

W tym rozwiązaniu nie trzeba tworzyć własnych certyfikatów, w wyniku czego nie będą występować konflikty certyfikatów. Ruch jest po prostu proxy, nie przechwytywane i przepisywane z różnych certyfikatów.

// Install npm dependencies first 
// npm init 
// npm install --save [email protected] 
// npm install --save [email protected] 

var httpProxy = require("http-proxy"); 
var http = require("http"); 
var url = require("url"); 
var net = require('net'); 

var server = http.createServer(function (req, res) { 
    var urlObj = url.parse(req.url); 
    var target = urlObj.protocol + "//" + urlObj.host; 

    console.log("Proxy HTTP request for:", target); 

    var proxy = httpProxy.createProxyServer({}); 
    proxy.on("error", function (err, req, res) { 
    console.log("proxy error", err); 
    res.end(); 
    }); 

    proxy.web(req, res, {target: target}); 
}).listen(8080); //this is the port your clients will connect to 

var regex_hostport = /^([^:]+)(:([0-9]+))?$/; 

var getHostPortFromString = function (hostString, defaultPort) { 
    var host = hostString; 
    var port = defaultPort; 

    var result = regex_hostport.exec(hostString); 
    if (result != null) { 
    host = result[1]; 
    if (result[2] != null) { 
     port = result[3]; 
    } 
    } 

    return ([host, port]); 
}; 

server.addListener('connect', function (req, socket, bodyhead) { 
    var hostPort = getHostPortFromString(req.url, 443); 
    var hostDomain = hostPort[0]; 
    var port = parseInt(hostPort[1]); 
    console.log("Proxying HTTPS request for:", hostDomain, port); 

    var proxySocket = new net.Socket(); 
    proxySocket.connect(port, hostDomain, function() { 
     proxySocket.write(bodyhead); 
     socket.write("HTTP/" + req.httpVersion + " 200 Connection established\r\n\r\n"); 
    } 
); 

    proxySocket.on('data', function (chunk) { 
    socket.write(chunk); 
    }); 

    proxySocket.on('end', function() { 
    socket.end(); 
    }); 

    proxySocket.on('error', function() { 
    socket.write("HTTP/" + req.httpVersion + " 500 Connection error\r\n\r\n"); 
    socket.end(); 
    }); 

    socket.on('data', function (chunk) { 
    proxySocket.write(chunk); 
    }); 

    socket.on('end', function() { 
    proxySocket.end(); 
    }); 

    socket.on('error', function() { 
    proxySocket.end(); 
    }); 

}); 
+0

Kochaj swój przykład. Zastanawiam się, w jaki sposób można go rozszerzyć, aby obsłużyć również uaktualnienia do sieci websocket – lzc

+0

@ y3sh czy proszę sprawdzić moje pytanie tutaj http://stackoverflow.com/questions/43908640/node-js-http-proxy-with-https? Myślę, że twój przykład może mi pomóc, ale nie wiem, jak to zaimplementować. – Valip

+0

Jak mogę dodać do tego uwierzytelnianie użytkownika i hasła, aby tylko przekazywać żądania ode mnie i mój dynamiczny adres IP? – koampapapa

Powiązane problemy