Configuration

Config files

Pushpin has two primary configuration files: pushpin.conf and routes. The pushpin.conf file refers to the routes file via the routesfile field:

[proxy]
routesfile=routes

If a relative path is used, then the file is looked up relative to the location of pushpin.conf.

pushpin.conf file

It is generally not necessary to edit pushpin.conf. You’ll spend more time with the routes file. However, if you need to change bind addresses or ports, or global settings that affect all routes, then this is the file to work with.

The pushpin.conf file is an INI-style formatted config file with four sections: global, runner, proxy, and handler. Below are descriptions of the public fields:

Global:

Runner:

When you run the pushpin executable, you’re invoking a runner that simply runs other programs. The runner program uses the runner section of pushpin.conf to know what to launch and how.

Proxy:

Configuration used by the pushpin-proxy program.

Handler:

Configuration used by the pushpin-handler program.

Spec templating:

For IPC specs, you can use template parameter {rundir} to be substituted with the Pushpin run directory. For example, if the run directory is /var/run/pushpin, and you specify an IPC spec as ipc://{rundir}/foo, then it will be resolved to ipc:///var/run/pushpin/foo during use.

routes file

The routes file is a text file where each line specifies a proxying route. Here is an example file with three routes defined:

example.com 192.168.1.100:80
example.net 192.168.1.101:80
* 192.168.1.102:80

The first part of each route is the route condition, which may be a full domain or an asterisk to indicate any domain.

Using the above routes, if an incoming request’s Host parameter matches example.com or example.net, then one of the domain-specific routes will be used. Otherwise, the last route will be used as a catch-all. Partial wildcards (e.g. example.*) are not supported. Note that the ordering of the lines does not matter. The following file would produce the same results:

example.com 192.168.1.100:80
* 192.168.1.102:80
example.net 192.168.1.101:80

Further, there is only ever one possible route for a given incoming request, and Pushpin will prefer more-specific routes over less-specific routes. If two or more routes conflict with each other, then only the first will be used and the rest will be ignored.

To understand how to write routes, see Routes.

Routes

The format of a Pushpin route is a condition and then one or more routing targets, all separated by spaces.

For example, here’s a simple routes file containing one line:

* localhost:8000

This single route means proxy any incoming HTTP request or WebSocket connection to a server running on port 8000 of the same machine. The route condition may be a full domain or an asterisk to indicate any domain.

You can also specify more than one target. In that case, the later targets will be attempted for delivery if the earlier ones fail.

* target1:8000 target2:8000 target3:8000

Routing conditions and targets may contain optional parameters. For example:

example.com,ssl=yes target1:443,ssl,insecure
* target2:80

The above line would mean to route incoming HTTPS or WSS requests for example.com to target1, and the proxying should be done with SSL as well, but the certificate of the target server should not be checked. Requests for domains other than example.com, or non-SSL requests for example.com, would route to target2. For further details about parameters, see the Condition Parameters and Target Parameters sections below.

Below are some more route examples.

Route HTTP traffic to port 8000 and WebSocket traffic to port 9000:

*,proto=ws localhost:9000
* localhost:8000

Since the most specific route is always preferred, every incoming WebSocket connection will use the first route.

Route non-SSL traffic to port 8000 and SSL traffic to port 8001:

*,ssl=yes localhost:8001
* localhost:8000

Route HTTP/HTTPS traffic to ports 8000/8001 and WebSocket (WS/WSS) traffic to ports 9000/9001:

*,proto=ws,ssl=yes localhost:9001,ssl
*,proto=ws localhost:9000
*,ssl=yes localhost:8001,ssl
* localhost:8000

Same as above, but more verbose:

*,proto=ws,ssl=yes localhost:9001,ssl
*,proto=ws,ssl=no localhost:9000
*,proto=http,ssl=yes localhost:8001,ssl
*,proto=http,ssl=no localhost:8000

Same as above, but don’t use SSL to communicate with the targets:

*,proto=ws,ssl=yes localhost:9001
*,proto=ws localhost:9000
*,ssl=yes localhost:8001
* localhost:8000

In addition to normal HTTP/WebSocket targets (indicated using the form host:port), Pushpin can route to ZeroMQ targets as well. The protocol used is ZHTTP, which supports PULL/SUB and REQ/REP modes. Use a target of the form zhttp/spec for PULL/SUB and zhttpreq/spec for REQ/REP.

For example, here’s how to route via REQ/REP:

* zhttpreq/ipc://httphandler

Pushpin binds to the address spec. Handlers connect to it. ZeroMQ targets can be useful if you want to implement a push service without a web server.

Condition Parameters

Target Parameters

Proxying

X-Forwarded headers

Pushpin lets you manipulate the X-Forwarded-For header using instructions specified in the x_forwarded_for and x_forwarded_for_trusted fields in the proxy section of pushpin.conf. Each field contains a comma-delimited list of instructions. If the request is determined to be from a trusted client (because the request’s Grip-Sig header validates with the configured upstream_key) then the x_forwarded_for_trusted field is used for the request. Otherwise, the x_forwarded_for field is used.

There are two instructions available. The order they appear doesn’t matter.

For example, if you set up Pushpin so that clients can directly access it, but you want to know the IP addresses of incoming clients, then you might want to use a configuration like this:

[proxy]
x_forwarded_for=truncate:0,append

This will completely replace the X-Forwarded-For header to contain just the requesting client’s true IP address. The reason for the truncate is because we cannot trust this header if the client provides it.

On the other hand, if you set up Pushpin behind a layer 7 load balancer (such as HAProxy) that already manipulates the X-Forwarded-For header in a similar fashion, then you can trust its value and simply append to it:

[proxy]
x_forwarded_for=append

You could also not bother appending to it, since usually only the leftmost IP address is interesting to backends anyway.

Pushpin can also interpret X-Forwarded-Proto as well as set it when proxying, depending on the accept_x_forwarded_protocol and set_x_forwarded_protocol settings.

WebSocket-over-HTTP

When Pushpin receives a WebSocket connection, it can proxy to the backend using a WebSocket connection, or it can send a series of HTTP requests that wrap WebSocket events. When using WebSockets, it is recommended to convert to HTTP so that the backend can service the connection statelessly. This is activated using the over_http target parameter.

Also see the WebSocket-over-HTTP spec.

SSL

Incoming client connections are handled by Condure (or Mongrel2 in older setups). To listen for SSL connections, set the https_ports field in the runner section of pushpin.conf. For example:

[runner]
http_port=8000
https_ports=4430

The above configuration will instruct Pushpin to configure Condure to use two ports, one for SSL and one for non-SSL. Additionally, you need to provide default certificate files for each SSL port being listened on. In the above case, Condure will expect the files default_4430.crt and default_4430.key to exist in the runner/certs directory. Both files should use PEM format, with the first file containing a concatenation of all certificates in the chain (minus the root cert) and the second file containing the private key of the primary certificate.

Server Name Indication (SNI) is supported. You can add additional certs named after the domains of the certs. For example, to support “example.com” via SNI, you’d want to put example.com.crt and example.com.key in the runner/certs directory. For wildcard subdomains, put files named _.example.com.crt and _.example.com.key in the directory.

When proxying to targets, Pushpin will connect using SSL if the route has the ssl target parameter set.