README
sn-proxy
Project Tin HTTP Reverse Proxy (formerly OhMeadhbh/kaeng)
Introduction
'sn-proxy' is a small package we use around the office to implement a simple tls-aware, hostname-based reverse proxy. This code will listen on ports 80 and 443 on a "real" network interface and proxy HTTP and HTTPS requests to ports on different ports on localhost based on the hostname in the request.
The current version is more or less just a wrapper around Nodjitsu's http-proxy, but this may change in the near future.
Installation
To install with NPM, issue this command:
npm install sn-proxy
Or, to get the (even more) bleeding edge code, use GIT:
git clone git://github.com/OhMeadhbh/sn-proxy.git
Configuration
Once you've downloaded the package, copy the proxyroutes-example.json
file to proxyroutes.json
and open it in your favorite editor. The
example file shows a configuration with three "zones": production, development
and secure. Each zone is an element in the JSON object in the proxyroutes.json
file.
{ "production": { "ssl": false, "port": 80, "router": { "local.example.com": "127.0.0.1:9000", "local.example.net": "127.0.0.1:9001", "local.example.org": "127.0.0.1:9002" } }, "development": { "ssl": false, "port": 8080, "router": { "local.example.com": "127.0.0.1:19000", "local.example.org": "127.0.0.1:19002" } }, "secure": { "ssl": true, "port": 443, "ciphers": "AES:!LOW:!MEDIUM:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!3DES", "router": { "local.example.com": "127.0.0.1:29000" "local.example.net": "127.0.0.1:29001" } } }
The first two zones (production and development) are non-secure (i.e. - non https.) You can see this because the "ssl" member of the zone object is "false". The "production" zone routes requests that come in from port 80 to local ports 9000, 9001 or 9002 depending on the hostname in the request.
If you wanted to deploy a service on local.example.com, you would build your service normally, but instead of listening on port 80, you would listen on port 9000 on the local interface (127.0.0.1).
The "secure" zone works the same way, except you have the option of adding "ciphers" and "secureProtocol" members that describe the ciphers you want to use and the version of TLS you want to support.
Before using the secure option, you must generate keys for each host specified
in the zone's router object. Keys are named
You'll also need a default key and cert called "localhost.key" and
"localhost.crt". The default key is used if an unknown host is specified, so
it's up to you to determine how secure this key (and cert) should be. We
frequently use self-signed certs for the default. (For a quick and easy way
to generate a self signed cert, the gssc
script in the
bin directory.
There is also a node.js program in the certs directory called
self-certs.js
. This program will scan
/etc/proxyroutes.json
(if it exists) or a resource
identified with the --config
option and generate
self-signed certificates for each entry in the file. This invocation
will extract hostnames from /etc/proxyroutes.json
:
node self-certs.js
while this invocation will extract hostnames from the file
proxyroutes.json
in the package's root directory:
node self-certs.js --config file://../proxyroutes.json
Deployment
Once you've configured your proxy, install the pre-requesite packages with the command:
make
Once that completes, you can start it with the command:
node sn-proxy.js --config file://proxyroutes.json
Deploying on a Debian Linux host
Assuming everything above works correctly and you're on a Debian-based system (including most recent versions of Ubuntu) you can install it as a self-starting service with the command:
make install-deb
This will copy the startup script from conf/sn-proxy
into
/etc/init.d/sn-proxy
and run update-rc.d
.
If you want to overwrite your existing
/etc/proxyroutes.jsonfile with a default set of routes, use this command:
make install-routes
This will create routes for localhost, your hostname, your fully qualified domain name, and the IP addresses for each of the attached network interfaces. Incoming traffic on port 80 will be redirected to port 9000 on the localhost interface (127.0.0.1). Incoming TLS traffic will be redirected to port 29000 on 127.0.0.1.
test-server and httpsify
Two scripts are included to facilitate https-only and testing environments.
The httpsify
script listens on a port and redirects all incoming traffic on
a http server to the eqivalent https URL. To start a httpsify server, simply
specify the local port to listen on as a parameter:
httpsify 9000
The test-server
exports a simple HTTP server on the specified port:
test-server 29000