Notify President Madagascar
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    http-host-proxypublic

    HTTP Host Proxy

    HTTP(s) proxy with host based routing to front servers, with optional SSL or authentication

    NOTE: as of version 1.0.0 this module no longer uses Passhash for user authentication - it has been replaced with HashP which has a different file format that is not backwards compatible.

    Installation

    First, install Node.js. Then:

    [sudo] npm install -g http-host-proxy
    

    Example

    First create a router file

    example-router.json

    {
      "test1.com": "localhost:8080",
      "test2.com": "127.0.0.1:8081",
      "test3.com": {
        "host": "192.168.1.15",
        "port": 8000
      },
      "daveeddy.com": "daveeddy.com",
      "google.com": "google.com:80",
      "github.com": {
        "host": "github.com",
        "port": 80
      }
    }

    This file maps incoming host headers, to the endpoint the server will proxy. Any of the above forms are permitted in the config.

    Basic

    Now, we can fire up the server:

    $ http-host-proxy -r example-router.json
    listening on http://0.0.0.0:8080
    

    By default, the server listens on HTTP, host 0.0.0.0, port 8080

    In a second terminal, we can trigger some requests to the server

    $ curl -i localhost:8080
    HTTP/1.1 404 Not Found
    Date: Thu, 14 Nov 2013 22:14:59 GMT
    Connection: keep-alive
    Transfer-Encoding: chunked
    
    no route found for host: localhost:8080
    $ curl -i -H 'host: daveeddy.com' localhost:8080
    HTTP/1.1 200 OK
    server: nginx
    date: Thu, 14 Nov 2013 22:15:12 GMT
    content-type: text/html
    content-length: 18692
    last-modified: Tue, 12 Nov 2013 23:58:31 GMT
    connection: keep-alive
    accept-ranges: bytes
    
    <!doctype html>
    <html>
    .... SNIPPED ....
    

    In the first request, you can see that we are thrown a 404 from the proxy itself, because it doesn't have a route defined for the host header localhost:8080. In the second request however a manual host header is set to daveeddy.com, which matches a route in the router. The request is proxied to http://www.daveeddy.com, and the response headers and the body are delivered directly through the proxy.

    On the server end, you can see Apache style logs, prefixed with the host header.

    $ http-host-proxy -r example-router.json
    listening on http://0.0.0.0:8080
    [localhost:8080] 127.0.0.1 - - [14/Nov/2013:17:14:59 -0500] "GET / HTTP/1.1" 404 - "-" "curl/7.30.0"
    [daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:15:12 -0500] "GET / HTTP/1.1" 200 18692 "-" "curl/7.30.0"
    

    Default Route

    You can specify the following in the router file to create a default route for unmatched host headers:

    {
      "*": "google.com"
    }

    With the above in place, any successful request will be proxied to google

    SSL

    Enabling ssl is easy. You need to already have a certificate and key file, or generate your own. To generate your own you can run:

    openssl genrsa -out my.key 4096
    openssl req -new -x509 -days 1826 -key my.key -out my.crt
    

    These 2 commands will create my.key and my.crt in your current directory. Now, just fire up the server with the following options to listen securely.

    $ http-host-proxy -r example-router.json --ssl -k my.key -c my.crt
    listening on https://0.0.0.0:8080
    [daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:25:19 -0500] "GET / HTTPS/1.1" 200 18692 "-" "curl/7.30.0"
    

    And to generate a request, just change curl to use https, and supply -k if the certificate is self-signed.

    $ curl -k -i -H 'host: daveeddy.com' https://localhost:8080
    HTTP/1.1 200 OK
    server: nginx
    date: Thu, 14 Nov 2013 22:26:03 GMT
    content-type: text/html
    content-length: 18692
    last-modified: Tue, 12 Nov 2013 23:58:31 GMT
    connection: keep-alive
    accept-ranges: bytes
    
    <!doctype html>
    <html>
    .... SNIPPED ....
    

    Authentication

    Authentication can also be done by the proxy; It will use basic HTTP auth before proxying any requests. The file format for the authentication database file can be thought of as a stronger version of htpasswd, and can be found in the HashP Node Module.

    First, we can create a passhash authentication database by running the following commands:

    $ npm install -g hashp
    $ echo -n 'password' | hashp username > passhash.txt
    $ cat passhash.txt
    username:QLZ6oPKVhm:swQfzk8F6gVhPrA3k2/1CTzitYo+LdZ8Qx+pmwBV7CFk/pZwsiunjYxmgzkXpJK+22mF4fvqI7t3neFXBi6SpQ==:89
    

    Or optionally visiting http://bahamas10.github.io/node-hashp/

    Now, we start the server with this file

    $ http-host-proxy -r example-router.json -a passhash.txt
    listening on http://0.0.0.0:8080
    

    Make a few requests, first without authorization, then with it supplied

     $ curl -i -H 'host: daveeddy.com' localhost:8080
     HTTP/1.1 401 Unauthorized
     WWW-Authenticate: Basic realm="Auth Required"
     Date: Thu, 14 Nov 2013 22:51:30 GMT
     Connection: keep-alive
     Transfer-Encoding: chunked
    
     $ curl -i -H 'host: daveeddy.com' --user username:password localhost:8080
     HTTP/1.1 200 OK
     server: nginx
     date: Thu, 14 Nov 2013 22:51:42 GMT
     content-type: text/html
     content-length: 18692
     last-modified: Tue, 12 Nov 2013 23:58:31 GMT
     connection: keep-alive
     accept-ranges: bytes
    
     <!doctype html>
     <html>
     .... SNIPPED ....
    

    And on the server we see:

    $ http-host-proxy -r example-router.json -a passhash.txt
    listening on http://0.0.0.0:8080
    [<empty>@daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:51:30 -0500] "GET / HTTP/1.1" 401 - "-" "curl/7.30.0"
    [username@daveeddy.com] 127.0.0.1 - - [14/Nov/2013:17:51:42 -0500] "GET / HTTP/1.1" 200 18692 "-" "curl/7.30.0"
    

    In the logs you can see username@daveeddy.com, the username is automatically prepended to the host header when authentication is enabled.

    NOTE: The authorization header is stripped out by the proxy before being sent to the destination.

    Usage

    usage: http-host-proxy [options] -r routefile.json
    
    HTTP(s) proxy with host based routing to front servers, with optional SSL or authentication
    
    required options
      -r, --routes <file.json>      [env HTTPHOSTPROXY_ROUTES] a JSON file of host based routes
    
    authentication options
      -a, --auth <authfile>         [env HTTPHOSTPROXY_AUTH] enable basic http authorization
                                    and use <authfile> as the `hashp` file
      -f, --fail-delay <seconds>    [env HTTPHOSTPROXY_FAIL_DELAY] delay, in seconds, before sending a response to a client
                                    that failed authentication, defaults to 2
    
    ssl options
      -c, --cert <certfile>         [env HTTPHOSTPROXY_CERT] the SSL cert file to use when `--ssl` is switched on
      -k, --key <keyfile>           [env HTTPHOSTPROXY_KEY] the SSL key file to use when `--ssl` is switched on
      -s, --ssl                     [env HTTPHOSTPROXY_SSL] enable ssl, requires `--key` and `--cert` be specified
    
    socket options
      -H, --host <host>             [env HTTPHOSTPROXY_HOST] the host address on which to listen, defaults to 0.0.0.0
      -p, --port <port>             [env HTTPHOSTPROXY_PORT] the port on which to listen, defaults to 8080
    
    options
      -b, --buffer                  [env HTTPHOSTPROXY_BUFFER] buffer log output, useful if this webserver is heavily used
      -d, --debug                   [env HTTPHOSTPROXY_DEBUG] print verbose logs, defaults to false
      -h, --help                    print this message and exit
      -u, --updates                 check for available updates on npm
      -v, --version                 print the version number and exit
    

    Configuration

    • process.env.HTTPHOSTPROXY_AUTH - same as -a or --auth
    • process.env.HTTPHOSTPROXY_BUFFER - same as -b or --buffer
    • process.env.HTTPHOSTPROXY_CERT - same as -c or --cert
    • process.env.HTTPHOSTPROXY_DEBUG - same as -d or --debug
    • process.env.HTTPHOSTPROXY_FAIL_DELAY - same as -f or --fail-delay
    • process.env.HTTPHOSTPROXY_GID - group ID to drop privileges to after server has started
    • process.env.HTTPHOSTPROXY_HOST - same as -H or --host
    • process.env.HTTPHOSTPROXY_KEY - same as -k or --key
    • process.env.HTTPHOSTPROXY_PORT - same as -p or --port
    • process.env.HTTPHOSTPROXY_ROUTES - same as -r or --routes
    • process.env.HTTPHOSTPROXY_SSL - same as -s or --ssl
    • process.env.HTTPHOSTPROXY_UID - group ID to drop privileges to after server has started

    Send a SIGHUP to the process to reload the router file

    Authors

    License

    MIT License

    Keywords

    none

    install

    npm i http-host-proxy

    Downloadslast 7 days

    9

    version

    1.0.0

    license

    MIT

    repository

    github.com

    last publish

    collaborators

    • avatar