Show HN: Encrypted VPN in 2k lines of Go(github.com) |
Show HN: Encrypted VPN in 2k lines of Go(github.com) |
the model of wireguard has been proven correct by formal methods. Builds on modern crypto, and they kept code short for auditing purposes.
> There is no group of users that should be using the code in this repository here under any circumstances at the moment, not even beta testers or dare devils.
Despite the warning I attempted to use it, but without any real docs I didn't get very far.
WireGuard is based on the Noise Protocol Framework [1], designed by the same fella as the Signal Protocol, and already used in production by millions of devices all around the world inside of WhatsApp. Not only that, but we have a formal verification [2] that the crypto is correct in the symbolic model. The WireGuard paper itself [3] was presented to the academic community at NDSS [4]. It's most certainly not the hastily-made nonsense you imply it is with the phrase "rolled our own crypto".
Meanwhile your project, "subnet", tunnels TCP over TCP, which is well known for having pathologically bad performance characteristics [5]. It also has no binding between certificates and the IP addresses that a certificate is allowed to be inside the tunnel, and, unless I've misread, it allows different peers to hijack each others' IP addresses simply by asking [6].
There's a lot of work that goes into doing tunneling well. I encourage your effort to make a fun toy project; it's a great learning opportunity. But please don't spread FUD about other projects without first understanding them.
[2] https://www.wireguard.com/formal-verification/
[3] https://www.wireguard.com/papers/wireguard.pdf
[4] https://www.ndss-symposium.org/ndss2017/
[5] https://www.google.com/search?q=tcp+over+tcp
[6] https://github.com/twitchyliquid64/subnet/blob/50fc8fe2b6ccf...
EDIT: got off my mobile and to a laptop and submitted https://github.com/twitchyliquid64/subnet/issues/3.
It is the future of official vendoring tools.
You could also look at `govendor`: https://github.com/kardianos/govendor
I've used govendor in some projects and found it agreeable. Best of luck :-)
to get you started with a nice workflow. Uses gvt for vendoring. Tests over multiple packages are globbed correctly
A couple of question:
- What is the throughput once you fixed the issues ?
- If you were to implement a client for mobile (iOS, Android), how would you go about it ? (Just theoretically, I understand it's a personal project)
I'm using openvpn on a cloud server and one of the big advantages is the availability of mobile client apps.
Mobile: You have to use the APIs that are available on the platform to hook into the network layer. After that its pretty straightforward though - you open some TLS connections, do verification, and encapsulate network traffic in some simple structs.
[1] http://sshuttle.readthedocs.io/en/stable/how-it-works.html
The 'double congestion-control' effect can be alleviated by opening 10 or so TLS connections and pumping the packets down those, to spread the effects of TCP congestion control.
That said, I'm using a library called Water for the low-level networking, and that library just added support for Windows. Implementing full windows support only requires you to implement a few network methods (such as helpers_linux.go) - PRs welcome :)
I was also expecting to see a single file at that line count, but then again I'm not really familiar with Go. Is this style of "many tiny files in multiple nested directories" common/expected for Go? I know it's rather common in many other languages, but also not what I expect when I see "Simple" or explicit mention of a low line count.
They do, but generally call it tunneling. L2TP and GRE links that don't use IPSEC are fairly common on private WANs.
I suspect the author was trying to point out that the encryption was included in the 2k lines, versus say, calling out to ssh.
I am a strong advocate of the saying 'trust but verify'. I believe you should closely audit whatever OSS software you are looking at using in light of your threat model.
To get round to your question: Why should I use subnet over OpenVPN/Tinc etc? That decision is entirely your prerogative. Subnet is small (quick(er) to audit), easy to understand, and has the bare minimum functionality needed to implement a VPN with full mutual authentication. OpenVPN and others have far more features and are almost certainty xx% faster. Where you want to draw the line is up to you.
I've used C#, Python, Ruby, Java, C, Obj-C, JS and Go for mid-large scale projects. Go is the only language I've ever truly loved; sometimes I even feel like I'm writing poetry (as ridiculous as that may sound).
The community is really incredible^, I've yet to encounter anything that didn't have great documentation or solved by packages. My favorite SO answer of any language is probably this one by icza: https://stackoverflow.com/questions/22892120/how-to-generate... . I also feel that it's very easy to read and understand other peoples code compared to other languages (imo, the only aspect of Go that I think can be difficult for newcomers to grasp is pointers). All in all, I feel very confident that I'll still be writing Go code after ten years.
^ (Although I hate when certain "elitists" downvote questions because they feel they've been sufficiently answered elsewhere.. if a SO answer says how to display time to YYYY-MM-DD:HH-MM then don't complain if someone ask how to display time as YYYY-MM-DD.. I have a strong dislike towards jquery (or rather JS), but I think the great thing about jquery is that every imaginable edge-case seem to be documented)
[1] http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in...
Most network related small apps were written in C, now you can write them in Go. With the added benefit of simple libraries, memory management and goroutines. You don't have to mess arround with platform specific sockets, threading libraries etc. Plus every piece of code you open is written in understandable Go. With C, there is years of baggage, multiple standards, pre-compiled headers, undefined behaviour etc.
And lastly, new is always more exciting than old :)
[0] https://stackoverflow.blog/2017/09/06/incredible-growth-pyth...
+1 for trying to eliminate complexity from developer error. This was one of the worst cows in the herd for OpenSSL.
That said, I think a bit of good design on the APIs part can go a long way. For Instance, I think Go's crypto/tls aint bad: Its pretty difficult to 'accidentally' configure it in a shocking configuration (suites have to be overridden, turning off verification requires you to set a field called InsecureNoVerify etc).
inb4 strawman arguments and other funzies.
Perhaps you should argue with me on my actual assertion, which is that 'we should use crypto that has stood the test and scrutiny of time'. Do not interpret my criticism as a personal attack.
> already used in production by millions of devices all around the world inside of WhatsApp.
Cool. This is good because that means we have a lot of eyes looking at it.
> formal verification that the crypto is correct in the symbolic model.
This is great and we need more of this kind of work. I don't think its good enough however; most practical attacks rely on side channels, implementation mistakes (formal verification helps in catching these but don't get you all the way), and other obscurities. I stand by my assertion that we should use crypto that has stood the test of time.
> The WireGuard paper itself [3] was presented to the academic community at NDSS
Congrats I guess? relevance?
> not the hastily-made nonsense you imply it is with the phrase "rolled our own crypto"
I made no such implication. 'Roll your own crypto' is a common phrase (at least in my circles) meaning to do it yourself instead of depend on someone else's implementation. Again, I don't see what this has to do with my assertion to use old and battle tested crypto.
> "subnet", tunnels TCP over TCP, which is well known for having pathologically bad performance characteristics
Correct, have a gold star. What does this have to do with crypto?
As you could tell if you scrolled down and read the other discussions around TCP-in-TCP, I am fully aware of the implication of my design decision, and stand by it is the right balance of simplicity, security, and speed (well, thats relative, but for what I was intending it for).
> It also has no binding between certificates and the IP addresses that a certificate is allowed to be inside the tunnel, and, unless I've misread, it allows different peers to hijack each others' IP addresses simply by asking
Correct, I am making the assumption that if posess a private key and cert minted by the server you are trusted. This could be fixed at the cost of additional complexity, loosing the ability for a client to change his address, and less alcohol-time on the developers part. That said, if someone asked me to network together hostile entities, I would have given him some coolaid instead of Go code. But I'm digressing, lets get back on topic.
> But please don't spread FUD about other projects without first understanding them.
I have done no such thing. I stand by my assertion that we should use Crypto that has stood the test of time. Am I not allowed to raise such assertions and discuss them on merit?
> What a bunch of senseless FUD
Is not a very courteous way to begin a rebuttal. Definitely makes it feel like an ad hominem.
- https://www.wireguard.com/quickstart/
- https://www.wireguard.com/install/
- https://git.zx2c4.com/WireGuard/about/src/tools/wg.8
- https://git.zx2c4.com/WireGuard/about/src/tools/wg-quick.8
But I use a Mac so I can’t join the VPN I made :/
[1] Send a blank email to wireguard-join at lists dot zx2c4 dot com.
[2] https://lists.zx2c4.com/pipermail/wireguard/2017-May/001338....
It's not uncommon in other projects either, NodeJS for example has a relatively small number of large files (https://github.com/nodejs/node/blob/master/src/node.cc).
Unlike Java, Go does not have limitation of having each public class in its own file. So public symbols of any type can be put together in same file if it makes sense. Go prefers arranging code what makes sense for application functionality instead of auto-generated scaffolding like 'handlers', 'utils', 'assets', 'entities' etc like I do in my Java code.
Looks like it may be a case of coming across some less well written projects and making assumptions about the entire language, which is nice as Go seems fun :)