About Archive Tags RSS Feed

 

My node-reverse-proxy is both stable and public

20 March 2011 21:50

I posted a brief snippet of code on Friday which was my initial stab at a reverse HTTP proxy in Javascript (using node.js).

Over the past couple of days I've tidied it up, added a command line parser, and made it flexible enough that it works for me.

My node reverse HTTP proxy is now both documented ( a little ) and available for further eyeballs.

Usage is pretty much:

$ node ./node-reverse-proxy.js --config ./path/to/config.file.js

The configuration file defines lists of virtual hosts along with the destination back-ends to proxy to - which is usually going to be a server running upon a high port on the loopback adapter, but might not be.

In addition to that we can perform rewrites such as:

/**
  * Handler for wildcard host: *.repository.steve.org.uk
  *
  */
'([^.]*).repository.steve.org.uk':
    {
        /**
         * Rewrites for static files - these will be handled via a
         * separate virtual host.
         */
        'rules': {
            '^/robots.txt':  'http://repository.steve.org.uk/robots.txt',
            '^/favicon.ico': 'http://repository.steve.org.uk/favicon.ico',
        },
     },

That says requests for http://chronicle.repository.steve.org.uk/robots.txt will be redirected to http://repository.steve.org.uk/robots.txt.

Alternatively we can invoke javascript for each request matching a pattern:

    /**
     * static.steve.org.uk will mostly proxy to 127.0.0.1:1008
     * but files beneath /private/ have an IP-based ACL.
     */
    'static.steve.org.uk':
    {
        host: 'localhost',
        port: '1008',

        'functions': {
            '/private': (function(orig_host, vhost,req,res) {
                var remote = req.connection.remoteAddress;;

                if ( ( remote != "80.68.85.46" ) &&
                     ( remote != "82.41.51.252" ) &&
                     ( remote != "89.16.161.34") &&
                     ( remote != "89.16.161.98" ) )
                {
                    res.writeHead(403);
                    res.write( "Denied access to " + req.url  + " from " + remote );
                    res.end();
                }
           }),
        }
    },

Fun stuff. It was live for my server, replacing apache, for a few hours today. I need to add some trivial HTTP Basic-Auth handling then it will go back.

Otherwise I hope it is vaguely useful to others, and that the provided examples explain things neatly.

ObQuote: "Only one thing alive with less than four legs can hear this frequency" - Superman.

| 4 comments

 

Comments on this entry

icon Bob at 14:10 on 20 March 2011

Hi,

I tried node.js recently, but I had problem with the packaged version in Debian: some of the examples from nodejs.org didn't worked well...

Is there a recommended version for this reverse proxy? Did you use the debian package? Did you compile it from sources?

Regards

icon Steve Kemp at 16:10 on 20 March 2011
http://www.steve.org.uk/

Because my server, and my desktop where I develop, is running the Squeeze version of Debian there is no nodejs package availabe.

The Debian nodejs package is only available for Wheezy/Unstable.

So I backported nodejs for Squeeze, and haven't run into any problems with it at all - it has successfully run both my own code and random samples of things I've attempted to run against it.

icon Justin Randell at 04:43 on 21 March 2011
http://drupal.org/user/38580

very nice. did you look at:

https://github.com/nodejitsu/node-http-proxy

not sure it supports rewrite rules, but i guess it would support patches to do so.

icon Steve Kemp at 11:10 on 21 March 2011
http://www.steve.org.uk/

No I didn't, though it looks like it does similar things when hooked up with the "proxytable".

Looks like mine is best for having rewrite facilities, and theirs is best for more activity.

I'll see how hard it is to merge in my code over the next few nights. In the meantime I'm fighting thttpd - but that is a post for another day.