Skip to content

Instantly share code, notes, and snippets.

@GromNaN
Forked from andris9/README.md
Last active February 11, 2017 19:17
Show Gist options
  • Save GromNaN/07397732f2ce1a6be492bdb933cb2e77 to your computer and use it in GitHub Desktop.
Save GromNaN/07397732f2ce1a6be492bdb933cb2e77 to your computer and use it in GitHub Desktop.
Extremely simple HTTP proxy for changing Host: header Useful when proxying requests to virtual hosts that require Host: header to be set.

Setup reverse tunnel

Run the following in your client machine

ssh -R EXPOSED_PORT:localhost:SERVICE_PORT USER@HOST

Where

  • EXPOSED_PORT is the port exposed to the internet in the proxy server
  • SERVICE_PORT is the port your application is listening in your machine
  • USER is the username of the ssh user
  • HOST is the proxy server host
  • CORS_METHODS is the list of HTTP methods allowed in cross-domain
  • CORS_HEADERS is the list of HTTP headers allowed in cross-domain

EXPOSED_PORT is the same as PORT_TARGET in proxy.js

If proxying does not work, check if you have set the following line in your sshd config of the proxy server

GatewayPorts clientspecified

After you haved logged in to the ssh server, run the proxy

"use strict";
/*
Creates a HTTP proxy that rewrites Host: header to a predefined value
Useful when forwarding requests to Apache or Nginx virtual hosts
Usage:
PORT_LISTEN=123 PORT_TARGET=456 HOST_TARGET=127.0.0.1 HOST_ORIGIN="tere.ee" node proxy.js
Where
* PORT_LISTEN is the port the proxy should be listening for incoming requests
* PORT_TARGET is the port the target server is listening for
* HOST_TARGET is the hostname or IP where the target server is listening on
* HOST_ORIGIN is the value that is set for the Host: header
* CORS_METHODS is the list of HTTP methods allowed in cross-domain
* CORS_HEADERS is the list of HTTP headers allowed in cross-domain
*/
var http = require("http"),
url = require("url");
var listenPort = process.env.PORT_LISTEN || 9201,
targetPort = process.env.PORT_TARGET || 9200,
targetHost = process.env.HOST_TARGET || "localhost",
origin = process.env.HOST_ORIGIN || "localhost",
corsMethods = process.env.CORS_METHODS || "GET,HEAD,PUT,PATCH,POST,DELETE",
corsHeaders = process.env.CORS_HEADERS || "x-requested-with,content-type,content-length";
var server = http.createServer(function(request, response){
// Handle CORS preflight requests
if ("OPTIONS" === request.method) {
response.writeHead(204, {
"access-control-allow-origin": request.headers["origin"],
"access-control-allow-methods": corsMethods,
"access-control-allow-credentials": "true",
"access-control-expose-headers": corsHeaders,
"vary": "origin",
});
response.end();
return;
}
var options, proxyRequest, user;
request.headers.host = origin;
request.headers['x-forwarded-for'] = request.headers['x-forwarded-for'] || request.connection.remoteAddress;
options = url.parse("http://" + targetHost+(targetPort?":"+targetPort:"") + request.url);
options.method = request.method;
options.headers = request.headers;
proxyRequest = http.request(options);
proxyRequest.addListener("response", function (proxyResponse) {
proxyResponse.pipe(response);
var headers = proxyResponse.headers;
headers['access-control-allow-origin'] = '*';
response.writeHead(proxyResponse.statusCode, headers);
// Log requests to console
console.log("%s [%s] \"%s %s\" %s",
request.headers['x-forwarded-for'],
new Date().toISOString().replace(/T/, " ").replace(/\.\d+Z/i, ""),
request.method,
request.url,
proxyResponse.statusCode);
});
request.pipe(proxyRequest);
});
server.listen(listenPort, function(){
console.log("Proxy listening on port %s", listenPort);
console.log("Forwarding requests to http://%s as %s", targetHost+(targetPort?":"+targetPort:""), origin);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment