Tokio based VPN crate


#1

Hey :wave: there,

I just had the idea of a Deep Packet Inspection (DPI) safe OpenVPN alternative written in Rust. For sure, it should be blazing fast and secure, and I start reading the Tokio tutorials for my first bunch of code.

Do you think this is feasible and possible to realize with Tokio? I did not found any implementation based on Tokio yet in that direction. Thank you very much for the input! :innocent:


#2

Implementing VPN requires touching crypto and networking code. Errors in that area are not prevented by the Rust compiler! It only protects you against use-after-free, buffer overflow etc. If you want this to be secure, you will have to be extremely careful!

If this is possible with Tokio I don’t know because I haven’t looked into it yet.


#3

Yes, I think building it on Tokio is probably the right thing to do.

If you make (or anybody else makes) an implementation that is open source with a GPLv2- and BSD/ISC/MIT- compatible license, and if you use ring for the crypto, then I am happy to help you out with whatever crypto issues you run into, including adding new features to ring as needed. In fact, I have a standing open offer for this: https://twitter.com/BRIAN_____/status/806616999463817216.

A TLS-based protocol like the one OpenVPN uses makes a lot of sense. I would recommend trying to build something on top of Rustls, which is already built on top of ring.


#4

Sounds great, I did some small experiments with tokio and tokio-tls, which is based on rust-native-tls. What are the benefits of Rustls in relation to native-tls? I guess a first crate could be the tokio enabled version of rustls, right?


#5

If your VPN implementation can work with those APIs, then I don’t think it is a high priority to replace the TLS part with something else.

Rustls is written 100% in the safe subset of Rust, designed from the start with modern security practices in mind. native-tls is over a million lines of legacy C code, with a thin layer of Rust on top. So, in some sense, whether to use Rustls vs native-tls depends on how much benefit you think using Rust has over using C, and how much benefit using modern security engineering practices have over what was done in the 90’s.

When you’re further along in your project, Rustls is also likely to be much easier to change to do things to protect against traffic analysis and other things that are especially important to a DPI-fighting VPN. In particular, let’s say you want the VPN traffic to look like modern web browser traffic. Then soon you’ll need a TLS 1.3 implementation that works on every platform your users use. native-tls won’t be able to do that, but Rustls can. But this is a longer-term thing.

It should be possible to change tokio-tls so that (1) it can use Rustls when requested with a feature flag, and (2) it uses Rustls by default on platforms like Linux that don’t have a native TLS stack. This would be an amazing contribution to the community independently of a VPN stack. (I had thought that that was already done, but I may be confusing it with something else.)


#6

Alright I totally got your point in relation to native-tls vs rustls.

Yes I think this should be done as an initial step. It seems there are already some plans to support it in the future, but I guess the implementation is not done, yet.


#7

It would be an awesome contribution to get it working again. It was working at one point in time and I imagine it wouldn’t be too difficult to add it back.


#8

Related, I just heard about WireGuard which claims to have a lot of nice properties both from the crypto and implementation standpoint: https://www.wireguard.io/presentations/#february-5-2017-fosdem-brussels-belgium


#9

It looks very nice indeed. Because they made a brand-new protocol, they are able to make things very nice. But, IIUC, because they made a brand-new protocol, it is easy for a MitM to recognize that protocol and block it. The idea of a “Deep Packet Inspection (DPI) safe” VPN, as proposed in this thread, is to make the VPN look just like a benign HTTPS connection that a web browser would make, to reduce the chances that the connection will be noticed by a censoring MitM.


#10

It is really neat and I will have a look at there source code. Another option later on to make it really safe from any DPI would be to add an obfuscation support like obfs4.


#11

I had a look at the source code and read the white paper of WireGuard. I really like the approach putting the functionality within a kernel module, this gains speed and makes the implementation more straight forward. I am not sure how a good implementation in Rust would look like. But maybe a hybrid implementation could fit in here.


#12

AFAIK the developers of WireGuard are planning to release userspace client written in Rust. Here’s part of the discussion on HN https://news.ycombinator.com/item?id=11996201


#13

Right, I just writing to their mailing list and will ask what the status of the Rust implementation is.


#14

ring was (and still is) intended to be used in a kernel-space TLS stack like this, not just for Linux but for kernels that are even less flexible. In my research for the kernel-space TLS stack, I didn’t see any serious long-term barriers to the project. Unless the OS kernel is written in Rust, any such implementation would be a “hybrid” and in some areas it is currently more convenient to use some C code than Rust. But in general a Rust kernel-space TLS implementation based on ring is very doable and may have even already been done.


#15

I got in contact with the WireGuard team and we decided to start the initial implementation of wireguard-rs. Target is a userspace implementation which is based on tokio.rs. If you want to contribute feel free to use the github issue tracking or the wiregard mailing list. I would be glad to get support by you guys. :slight_smile:


#16

I see you are implementing it as a library. That’s awesome. I have plans to embed WireGuard in my apps. This will make it even nicer to work with :grin:


#17

How is the project coming along? Do you have any road map to see what’s left to do?