Home

Awesome

Bouncer (TCP)

Bouncer is an open source (Apache License, Version 2.0) Java network proxy. Do not require any external lib.

Current Stable Version is 2.2.11


DOC

Schema about Forward / Port Redirector (you need ONE bouncer):

Forward / Port Redirector

  1. Machine-A (Client) init connection to Machine-B (Bouncer)
  2. Machine-B init connection to Machine-C (Server)
  3. Done: Machine-A is able to speak with Machine-C
Notes about security:

Schema about Reverse Tunneling (you need TWO bouncers):

Reverse Tunneling

Machine-A and Machine-B are Bouncers in Client-Server configuration.
  1. Machine-A (MUX-OUT) init connection to Machine-B (MUX-IN)
  2. Machine-D (Client) init connection to Machine-B
  3. Machine-B request to Machine-A new SubChannel over MUX (Tunnel).
  4. Machine-A open connection to Machine-C (Server).
  5. Done: Machine-D is able to speak with Machine-C
Notes about security:

System Properties (optional)

# To redir stdout/stderr to (auto-daily-rotated) files you can use:
-Dlog.stdOutFile=/var/log/bouncer.out -Dlog.stdErrFile=/var/log/bouncer.err
# To log to stdout too:
-Dlog.stdToo=true 
Filenames are a base-pattern, output files they will be: bouncer.xxx.YEAR-MONTH-DAY (bouncer.xxx.2014-12-01)

Config (bouncer.conf)

Config file must be in class-path ${BOUNCER_HOME}/conf/, general format is:

# Forward / Port Redirector
# <listen-addr> <listen-port> <remote-addr> <remote-port> [opts]

# Reverse Tunneling (Bouncer 2.x syntax)
# <mux-in|tun-listen> <mux-name> <listen-addr> <listen-port> [opts]
# <mux-out|tun-connect> <mux-name> <remote-addr> <remote-port> [opts]

# Note: <remote-addr> can be a coma separated list of addresses, like "srv1,srv2,192.168.1.1"

# Clustering Config
# <cluster-listen> <cluster-id> <listen-addr> <listen-port> [opts]
# <cluster-peer> <cluster-id> <remote-addr> <remote-port> [opts]
Options are comma separated:
Notes about LB policies:
Notes about security:
Example config of Forward / Port Redirector (rinetd style):
# <listen-addr> <listen-port> <remote-addr> <remote-port> [opts]
0.0.0.0 1234 127.1.2.3 9876
127.0.0.1 5678 encrypted.google.com 443 LB=RR,STICKY=MEM:24:128:300,TUN=SSL
127.0.0.1 8443 encrypted.google.com 443 TUN=ENDSSL,ENDSSL=server.crt:server.key,TUN=SSL
Example config of Reverse Tunnels (equivalent ssh -p 5555 192.168.2.1 -R 127.0.0.1:8080:192.168.1.1:80)
Machine-A (MUX-OUT):
### Bouncer 1.x legacy syntax ###
# <remote-addr> <remote-port> <remote-tun-addr> <remote-tun-port> MUX-OUT
192.168.1.1 80 192.168.2.1 5555 MUX=OUT

### Bouncer 2.x syntax, with support for multi-port ###
# <mux-out|tun-connect> <mux-name> <remote-addr> <remote-port> [opts]
mux-out mux1 127.0.0.1 5555
tun-connect mux1 192.168.2.1 80 TUN_ID=1
tun-connect mux1 192.168.2.1 22 TUN_ID=2
Machine-B (MUX-IN):
### Bouncer 1.x legacy syntax ###
# <listen-tun-addr> <listen-tun-port> <listen-addr> <listen-port> MUX-IN
192.168.2.1 5555 127.0.0.1 8080 MUX=IN

### Bouncer 2.x syntax, with support for multi-port ###
# <mux-in|tun-listen> <mux-name> <listen-addr> <listen-port> [opts]
mux-in mux1 192.168.2.1 5555
tun-listen mux1 127.0.0.1 8080 TUN_ID=1
tun-listen mux1 127.0.0.1 2222 TUN_ID=2
Same example config of Reverse tunnels but SSL/TLS
Machine-A (MUX-OUT):
### Bouncer 1.x legacy syntax ###
# <remote-addr> <remote-port> <remote-tun-addr> <remote-tun-port> MUX-OUT
192.168.1.1 80 192.168.2.1 5555 MUX=OUT,MUX=SSL,SSL=peerA.crt:peerA.key:peerB.crt

### Bouncer 2.x syntax, with support for multi-port ###
# <mux-out|tun-connect> <mux-name> <remote-addr> <remote-port> [opts]
mux-out mux1 127.0.0.1 5555 MUX=SSL,SSL=peerA.crt:peerA.key:peerB.crt
tun-connect mux1 192.168.2.1 80 TUN_ID=1
tun-connect mux1 192.168.2.1 22 TUN_ID=2
tun-connect mux1 192.168.2.1 25 TUN_ID=3
Machine-B (MUX-IN):
### Bouncer 1.x legacy syntax ###
# <listen-tun-addr> <listen-tun-port> <listen-addr> <listen-port> MUX-IN
192.168.2.1 5555 127.0.0.1 8080 MUX=IN,MUX=SSL,SSL=peerB.crt:peerB.key:peerA.crt

### Bouncer 2.x syntax, with support for multi-port ###
# <mux-in|tun-listen> <mux-name> <listen-addr> <listen-port> [opts]
mux-in mux1 192.168.2.1 5555 MUX=SSL,SSL=peerB.crt:peerB.key:peerA.crt
tun-listen mux1 127.0.0.1 8080 TUN_ID=1
tun-listen mux1 127.0.0.1 2222 TUN_ID=2
tun-listen mux1 127.0.0.1 465 TUN_ID=3,TUN=ENDSSL,ENDSSL=server.crt:server.key
For Encryption Tunnels with AES (no SSL/TLS) you can use MUX=AES,AES=sharedsecret in both sides

Running (Linux)

./bin/bouncer.sh <start|stop|restart|reload|status>

Running (command line without config file)

java -jar bouncer-x.x.x.jar -- "...config.line.1..." "...config.line.2..."

Example:
java -jar bouncer-x.x.x.jar -- "0.0.0.0 1234 127.1.2.3 9876" "127.0.0.1 5678 encrypted.google.com 443 TUN=SSL"

Running (command line with remote config file)

java -jar bouncer-x.x.x.jar https://config.acme.com/bouncer.conf

RSA Key / X.509 Certificate Generation for MUX-SSL (optional)

./bin/bouncer.sh keygen <bits> <days> <CommonName> <filename-without-extension>

Enabling Strong Ciphers with BouncyCastleProvider

You can improve security, simply download bcprov-jdk15on-XXX.jar from BouncyCastle and copy jar file to ${BOUNCER_HOME}/lib/


TODOs

DONEs

MISC

Current harcoded values:


Latency Benchmark

<table> <tr align="right"> <th>microsecs</th> <th>Direct</th> <th>Forward</th> <th>MUX</th> <th>MUX-AES</th> <th>MUX-SSL</th> </tr> <tr align="right"> <th>min</th> <td>12</td> <td>38</td> <td>110</td> <td>125</td> <td>184</td> </tr> <tr align="right"> <th>max</th> <td>1468</td> <td>1016</td> <td>1351</td> <td>51036</td> <td>21771</td> </tr> <tr align="right"> <th>avg</th> <td>19</td> <td>46</td> <td>120</td> <td>153</td> <td>213</td> </tr> </table>

Throughput Benchmark

<table> <tr align="right"> <th>(transfers)</th> <th>Direct (x2)</th> <th>Forward (x4)</th> <th>MUX (x6)</th> <th>MUX-AES (x6)</th> <th>MUX-SSL (x6)</th> </tr> <tr align="right"> <th>Mbytes</th> <td>256</td> <td>128</td> <td>51</td> <td>17</td> <td>19</td> </tr> <tr align="right"> <th>Mbits</th> <td>2048</td> <td>1024</td> <td>408</td> <td>136</td> <td>152</td> </tr> </table>
All test run on localhost on a Laptop. Values are not accurate, but orientative. Latency { EchoServer, 1 byte write/read (end-to-end, round-trip), 100K iterations } Lower Better. Throughput { Chargen, 1024bytes read & write (full-duplex), total 512MBytes } Higher better.

Inspired in rinetd, stunnel and openssh, this bouncer is Java-minimalistic version.