[HN Gopher] Show HN: SafeHaven - A Minimal VPN Implementation in Go
       ___________________________________________________________________
        
       Show HN: SafeHaven - A Minimal VPN Implementation in Go
        
       Hi HN,  For the past few months, I've been exploring tools that
       integrate with the Linux networking stack. This led me to build
       SafeHaven, a lightweight and configurable VPN implementation
       written in Go. The goal was to better understand how virtual
       private networks work at a fundamental level.  Would love feedback
       from the community! Repo link:
       https://github.com/kwakubiney/safehaven
        
       Author : kwakubiney
       Score  : 66 points
       Date   : 2025-03-02 12:00 UTC (11 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | jimmyl02 wrote:
       | pretty cool and thanks for the details about TUN devices!
       | 
       | I believe wireguard runs over UDP and while you still need a TUN
       | device, it has kernel implementations to handle encrypting the
       | traffic.
        
         | kwakubiney wrote:
         | Thanks for the comment and nice words! The encryption bit is
         | still something I am yet to get into since I have not decided
         | on how to go about that yet! It seems Tailscale uses the
         | WireGuard protocol, I could probably look into how they are
         | doing that and get some ideas from there :)
        
           | smw wrote:
           | Tailscale actually implements wireguard in go in user space,
           | last time I checked.
        
           | homebrewer wrote:
           | netbird is more interesting as it's able to rely on kernel-
           | mode wireguard when peers can see each other directly, and
           | fall back to the userspace implementation.
        
       | sepositus wrote:
       | Awesome, thanks for sharing. Did you use anything particular to
       | help direct the implementation? I've been on a streak of building
       | things in Go for the same reason (learning), and a VPN is one of
       | the items on my list.
        
         | kwakubiney wrote:
         | Hey! Thanks for the comment. There was not any particular one
         | resource I used to direct this implementation, I used a couple.
         | Most prominent was reading open source code on GitHub[1] by
         | people who have done similar things. Understanding how TUN/TAP
         | devices work was crucial and this book[2] helped a lot.
         | 
         | [1]https://github.com/dsnet/udptunnel
         | [2]https://www.amazon.com/Internet-Security-Hands-Approach-
         | Comp...
        
       | max-privatevoid wrote:
       | Nice. This does some things very similarly to Hyprspace[1]. The
       | core idea is the same: Receive some bytes from a TUN device,
       | shove them into a network socket, and vice versa. Hyprspace uses
       | libp2p to manage the outer connections between VPN nodes instead
       | of plain UDP, which takes care of addressing, hole punching and
       | encryption.
       | 
       | BTW: You can also use the netlink library to configure the
       | routing table without external processes[2]. The /1 trick isn't
       | necessary either, you can just create a route for 0.0.0.0/0 and
       | set its metric lower than the existing default route. That won't
       | replace the old route in the table, the new one will just take
       | precedence as long as it exists.
       | 
       | [1] https://github.com/hyprspace/hyprspace
       | 
       | [2]
       | https://github.com/hyprspace/hyprspace/blob/a5957e485ff0c2e9...
        
         | kwakubiney wrote:
         | Thanks for the comment. Cool stuff you lot are doing on
         | Hyprspace! I agree the usage of `exec.Command` is a bit gnarly,
         | using the netlink library would make it a bit more cleaner. The
         | suggestion to define a metric lower than that of the existing
         | default route makes sense. But then that would mean I then find
         | out what the default route's metric is by making an extra call
         | where my current implementation does not use that extra call
         | but the outcome is the same? To reduce cognitive complexity, I
         | can understand how your suggestion helps though :), unless
         | there's another thing I am missing?
        
         | kwakubiney wrote:
         | Ah nvm, I see how it reduces the complexity now. I would not
         | have to create routes for the halved address spaces anymore
        
       | entropyneur wrote:
       | Since people are apparently interested in minimal VPNs, here's
       | one I built in Rust recently:
       | https://github.com/atereshkin/nanovpn
       | 
       | My goal there was to have as little code as possible so that one
       | could look at it and immediately grasp what goes into
       | establishing a VPN.
        
       | gsliepen wrote:
       | From the article:
       | 
       | > Currently, packets are not being encrypted within the UDP
       | tunnel so packet sniffing over the internet is possible. It is
       | encouraged to use this over a protocol like SSH
       | 
       | No encryption takes the P out of VPN. Also, if you are going to
       | need SSH to make it secure, then you can just use OpenSSH's
       | built-in support for the tun device using the -w option.
        
       ___________________________________________________________________
       (page generated 2025-03-02 23:01 UTC)