[Devember 2020] SSTP-like VPN implementation

This year my Devember challenge is implementing something similar to an SSTP VPN in the Zig language. ZZTP is the name, coding is the game :sunglasses: .

Building a VPN was on my mind for a while for learning purposes, as I’ve been working with/using multiple different implementations this past year, but why exactly this protocol? (Wireguard will take everything over yada-yada, I know!) The reason is twofold and simple:

  1. I was annoyed at what was available for Linux in the past for this protocol and
  2. that this protocol externally looks like an HTTPS website and it quacks like an HTTPS website.

So it sets up like a website and is not practically block-able by routers anywhere (yeah yeah, other implementations like OpenVPN can do the non-blockable thing yada-yada, I know!).

My goals for this project are:

  • Get my feet wet with Zig
  • Learn a lot of Linux networking and tunneling things
  • Maybe get something useful if I’m lucky
  • Play with my soon-to-be-completed custom router box

What I will not be doing to stay sane:

  • Trying to adhere to the Microsoft’s SSTP and make them kiss. This is a learning project, not a honest-to-god attempt at an implementation.
  • Will definitely not bother supporting anything else except Linux. I might do OpenBSD, but that’s only because it’s a candidate for my router OS.

The (rough) plan:

  • Creation of a virtual tunnel device - Already complete
  • Do unencrypted tunneling
  • Put TLS on the thing
  • Maybe do some nice quality of life things to make it easy to use
  • Maybe do quick setup with Let’s Encrypt

Links and updates soon-ish.

2 Likes

Link - ZZTP. I’ll be working with Zig version 0.7.0.

So, it’s about time to begin development of this thing. So far I’ve created a TUN device on the system and can successfully route the packets that it receives to stdin. I’ve been reading about networking in the Linux kernel in the past few weeks, and have gotten some nice ideas on how to structure my code. I’m looking to go pretty lean on my implementation, but I don’t want to code myself into a corner and end up with OpenVPN (it’s all single thread, lots of global state). So next couple of days are going to be for setting up the application flow and some structuring.

First thing I’ll be working on setting up everything to be able to run in server mode and client mode off of the same code base, proper structure here is important. I’ll be attempting to separate my packet handling into a top half and a bottom half as well (much like the Linux kernel does it).

With this I expect to come out with:

  • A client and server mode with unauthenticated raw TCP transport
  • Somehow go by without issuing IP addresses to connections (since that’s a separate, likely more complex part)
  • Some sort of connection handling so I could handle multiple of them (but this might be impossible to do without issuing addresses)

Update

So far I’ve been working hard on learning/reading on how to do packet routing myself and how to do it effectively. Learning the Zig’s way of doing async/await and how it works, in addition attempting to design the routing mechanism has been time consuming, and so not much progress has been made so far. Although, I did manage to implement network interface self-configuration. It now can assign an address, netmask, and also up itself into immediate operational mode.