Skip to content

Instantly share code, notes, and snippets.

@tjcrowder
Forked from andris9/README.md
Last active February 1, 2017 14:47
Show Gist options
  • Save tjcrowder/9971043 to your computer and use it in GitHub Desktop.
Save tjcrowder/9971043 to your computer and use it in GitHub Desktop.

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

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


2014-04-04 - TJC: This forked version rewrites the Location header on 3xx responses, changing the origin host to the request's host, so the client uses the appropriate host for follow-up requests.

"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
and optionally
* LOG_REQUESTS turns request logging to the console on/off (default on; "Y", "yes", "1",
or "true" enable logging, anything else disables it)
*/
var http = require("http"),
url = require("url");
var listenPort = process.env.PORT_LISTEN || 8080,
targetPort = process.env.PORT_TARGET || 9000,
targetHost = process.env.HOST_TARGET || "localhost",
origin = process.env.HOST_ORIGIN || "origin",
lcorigin = origin.toLowerCase(),
logRequests = !!(process.env.LOG_REQUESTS || "Y").toUpperCase().match(/^(?:y|yes|1|true)$/i);
var server = http.createServer(function(request, response){
var options, proxyRequest, user, requestHost;
requestHost = request.headers.host;
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) {
handleResponse(requestHost, proxyResponse, response);
// Log requests to console
if (logRequests) {
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);
});
function handleResponse(requestHost, proxyResponse, response) {
var headers;
// Rewrite location headers for 3xx responses
if (proxyResponse.statusCode >= 300 && proxyResponse.statusCode <= 399) {
headers = {};
Object.keys(proxyResponse.headers).forEach(function(name) {
var value = proxyResponse.headers[name];
var location;
if (name.toLowerCase() === 'location') {
location = url.parse(value);
if (location && location.hostname) {
if (location.hostname.toLowerCase() === lcorigin) {
location.hostname = requestHost;
delete location.host;
value = url.format(location);
}
}
}
headers[name] = value;
});
}
else {
headers = proxyResponse.headers;
}
response.writeHead(proxyResponse.statusCode, headers);
proxyResponse.pipe(response);
}
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