/Paraglider

Golang based tool to convert any Linux host into a TCP load balancer using iptables

Primary LanguageGoGNU General Public License v2.0GPL-2.0

Paraglider

Paraglider is a golang based tool to convert any Linux host into a TCP load balancer using iptable rules. Paraglider can be used in situations where you do not want to use a heavy weight, full blown load balancer, but a minimalistic, lightweight TCP load balancer to load balance between given backends. One such use case for Paraglider can be lightweight IOT projects where the device which needs to serve as a load balancer is low end and less powerful.

Quick start

The following sections will show how to get quickly started with Paraglider.

Using prebuilt Paraglider binary

  • Download prebuilt Paraglider binary from here.
  • Unzip the tar file using tar xvf Paraglider-<version>.tar
  • Once uncompressed, you will find the paraglider binary file.
  • You can run paraglider using ./paraglider -config </path/to/config> <start|stop>

Building binary from source

  • Please make sure you have a golang setup and a go path is also set up.
  • Clone/Download this repo into your go path.
  • Navigate into the repo and cd into main.
  • Run go get .
  • After running the above go command run go build -o paraglider .
  • If the above commands run successfully, you will find the paraglider binary file generated.
  • You can run paraglider using ./paraglider -config </path/to/config> <start|stop>

Configuring paraglider

By default Paraglider expects to find the config file at /etc/paraglider/glider.yaml However it is possible to provide a configuration file using -config option while staring it.

Given below is a sample configuration file for Paraglider:

frontend:
  bind: 166.1.101.2:4444
  privateip: 172.19.0.4
  backends:
    - 172.19.0.2:5555
    - 172.19.0.3:5555
    - 172.19.0.6:5555

In the above sample yaml, frontend is the root object which contains the following properties:

  • bind: The address to which the load balancer will bind itself. The corresponding interface should be attached to the network to which the users/clients are connected to, i.e., the users should be able to reach this IP. Optionally this can be the same as the private IP.

  • privateip: This is the ip which should be reachable by the target backends. In other words this IP should correspond to the interface which is connected to the network to which the target backends are also connected. Optionally as already mentioned, this IP can be the same as the bind IP.

  • backends: List of target backends. Backends should be in the format <IP>:<PORT>. Paraglider will send traffic to these backends in round robin fashion.

Starting and Stopping Paraglider

Paraglider can be started using ./paraglider [-config] [config file] start

It can be stopped using ./paraglider [-config] [config_file] stop

How Paraglider works

Under the hood, Paraglider uses Linux iptable rules to manipulate how packets headed for bind IP are treated. This is done by adding DNAT rule in the NAT table in PREROUTING chain and SNAT rule in NAT table in POSTROUTING chain of the host where the load balancer is running.

So, when a packet arrives at the load balancer server and if its destination IP address is the bind ip and its destination port is the bind port, then Paraglider via iptables will change the destination ip and port to one of the target backend's IP and port.

Similarly, the packet which is now headed for one of the target backends must know that they must return back to the load balancer server and for this source natting is used. Before the packet leaves the load balancer host, the source address of the packet is changed to the privateip of the load balancer box. It is to be noted here that, there is nothing special with privateip. Any IP attached to the host and which is in the same network as the target backends can be used. It can even be same with the bind ip if the client, the load balancer host and the target backends all are in the same network.

The round robin packet distribution between target backends is achieved using the statistic module which comes along with iptables.