GSoC 2018 – Kernel-space SOCKS proxy for Linux – Final

Short description

The original plan was a full kernel-space SOCKS proxifier, but that would be a little bit complex for the goal: a faster TCP proxy. Then I found a very elegant solution for the problem: eBPF sockmap support. There is a API for redirect packets between sockets in kernel space using sockmap eBPF program. I decided to extend my shadowsocks-libev fork with the eBPF support. The disabled encryption already give some additional performance, so if anyone already using this one, there is a new option to get more performance.

The results

I did some performance and functional tests in my test environment (described here). The eBPF performance is fairly good compared to the regular version. I included two screenshots, one with and one without eBPF enabled. For sockmap support, at least 4.14 kernel required! (The iperf3 tests performed on 4.14.41 MPTCP supported kernel with 1 network path). host1 machine is connected to ubu1 machine and use it as a router to ubu2 (see the diagram here). For more information about use a machine as a router and transparent proxy please take a look into this.

iperf3 -c ubu2                                            iperf -s
+-----------+              +------------+               +----------+
|           |              |            |               |          |
|   host1   +------------> |    ubu1    +-------------> |   ubu2   |
|           |              |            |               |          |
+-----------+              +------------+               +----------+
                          ss-redir --ebpf                 ss-server
eBPF dataplane disabled

 

eBPF dataplane enabled

The branch with eBPF sockmap support: https://github.com/SPYFF/shadowsocks-libev-nocrypto/tree/ebpf

Future work

Sadly in practice, there is an issue with the current version. For example in a long FTP file transmission, at the end it will skip some bytes or push additional (duplicated) bytes to the receiver.  That’s because in the current kernel implementation sometimes if an error happens during the transmission, the packet size returned instead of the error code. I consulted with John Fastabend (he is the creator of the eBPF sockmap) about the issue and he told me he will send a patch for that which will be get merged into the kernel soon. After that if everything works fine, I will put the whole work into a OpenWRT package.

Links

Leave a Reply

Your email address will not be published. Required fields are marked *