Mallet - a TCP tunnel like VPN
Tags: linux, macos, network, vpn
Published: 2020-07-29 14:40:11

---
title: Mallet - a TCP tunnel like VPN
published: true
description: Mallet - a TCP tunnel like VPN
tags: #linux #macos #network #vpn 
//cover_image: https://direct_url_to_image.jpg
---

I've developed a TCP tunnel, called ["Mallet"](https://github.com/ryotarai/mallet), that works like VPN. It depends on [jpillora/chisel](https://github.com/jpillora/chisel) for TCP tunneling.
You just need to run a chisel server in a machine that you would like to get traffic through.

Mallet configures iptables (Linux) or pf (macOS) to redirect traffic to the TCP tunnel.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uevyne8zfyem9jnxpfsy.png)

## Features

* No admin privilege required in a server. You just need SSH as a normal user.
  * You still need sudo right in a client machine to redirect traffic.
* Encrypted connection (thanks to chisel)
* Performant (thanks to chisel)

## Installation

https://github.com/ryotarai/mallet#installation

## Usage

Assume that you have a server `a.example.com` and would like to get traffic to 10.0.0.0/8 through `a.example.com`:

```
Laptop --> a.example.com --> 10.0.0.0/8
```

First, install chisel to a.example.com by following https://github.com/jpillora/chisel#install and run chisel server:

```
a.example.com$ chisel server --port 8080
```
(Keep this chisel process running)

Then, run Mallet and connect to the chisel server:

```
$ sudo mallet start --chisel-server http://a.example.com:8080 10.0.0.0/8
```
(Keep this mallet process running)

Now, all TCP traffic to 10.0.0.0/8 is forwarded via a.example.com.

## Usage with SSH

In this example, we will run Mallet via SSH port forwarding.

Assume that you have a server `a.example.com` and would like to get traffic to 10.0.0.0/8 through `a.example.com`:

```
Laptop --SSH--> a.example.com --> 10.0.0.0/8
```

First, install chisel to a.example.com by following https://github.com/jpillora/chisel#install

Second, launch chisel server on a.example.com and forward a port to the server:

```
$ ssh -t -L 8080:127.0.0.1:8080 a.example.com chisel server --host 127.0.0.1 --port 8080
```
(Keep this ssh process running)

Then, start Mallet:

```
$ sudo mallet start --chisel-server http://127.0.0.1:8080 10.0.0.0/8
```
(Keep this mallet process running)

Now, all TCP traffic to 10.0.0.0/8 is forwarded via a.example.com.

## Comparison

There is a similar project, [sshuttle](https://github.com/sshuttle/sshuttle). sshuttle supports IPv6 and UDP, that Mallet does not support, however Mallet is more performant than sshuttle.

The following benchmark is measured by this method: https://github.com/ryotarai/mallet#benchmark

### iperf benchmark

| | Throughput |
| --- | --- |
| (D) Direct | 4.98 Gbits/sec |
| (A) Mallet | 1.84 Gbits/sec |
| (B) Mallet over SSH | 1.04 Gbits/sec |
| (C) sshuttle | 0.279 Gbits/sec |

### HTTP benchmark (wrk and nginx)

req/sec

| Concurrency (== Threads) | 1 | 2 | 4 | 8 |
| --- | --- | --- | --- | --- |
| (D) Direct | 10174.78 | 18137.10 | 30328.02 | 39130.81 |
| (A) Mallet | 3560.81 | 6772.88 | 11054.35 | 15576.85 |
| (B) Mallet over SSH | 2465.27 | 4434.10 | 6881.70 | 9767.50 |
| (C) sshuttle | 2416.52 | 4254.54 | 5491.61 | 469.49 (socket write error: 14) | 

avg latency

| Concurrency (== Threads) | 1 | 2 | 4 | 8 |
| --- | --- | --- | --- | --- |
| (D) Direct | 95.85us | 107.50us | 128.92us | 211.63us |
| (A) Mallet | 279.71us | 295.74us | 368.46us | 526.68us |
| (B) Mallet over SSH | 406.29us | 452.08us | 586.36us | 823.74us |
| (C) sshuttle | 411.67us | 468.36us | 725.38us | 1.19ms |