Identity management for WireGuard
lwn.net
lwn.net
I have noticed an interesting change psychology arising from behavior such as this. I am more likely to use Tailscale (at the very least professionally, if not personally) instead of the free/OSS version because of this goodwill. Another example is Aeotec, who produce Z-Wave appliances. Aeotec's cooperation with the community (in terms of firmware) gives me significantly more confidence in the longevity of their devices.
Sadly, I don't think this psychology is ever going to become pervasive. People like what they already like.
Right now the thing that's stopping me is the lack of Split-DNS. I'd even be happy if I could configure this in the official client, I've only got a handful of devices so distributing the configuration by hand is fine. My IKEv2/IPSec set up does this perfectly, and using MDM profiles lets me set up connect-on-demand. WireGuard already does connect-on-demand and my limited testing suggests that it works well enough.
I don't want to use Tailscale since I'd like to keep everything self-hosted. It sounds like Headscale is almost there - it just needs the iOS client to be able to point to an arbitrary endpoint.
Wireguard itself will always consider authentication, dns, routing, etc. out of scope which IMO is really for the best
On the official client I can specify DNS servers for a particular connection, so one "easy" solution would be to specify domains that need to go to that set of DNS servers. e.g., when connected to home use 192.168.x.y to resolve *.blah, otherwise use the system resolvers.
The big hurdle is understanding the concept of search domain vs routing domain and the interaction with resolved and NetworkManager.
It's magical. It's well on the way towards being a critical piece of infrastructure in my mind.
I think the problem is though that the iOS client doesn't support configuring this option in the profile (whether installed via configurator or MDM) either.
I'm also using it to SSH into my home PC. No need to open router ports, configure dynamic IP, or whatever. Just setup tailscale, and I can simply do ssh user@homepc thanks to MagicDNS.
There’s no way to troubleshoot. A bunch of forum posters reported the same issue after an update, but no solution for a few months.
What's the bug? I hadn't heard about this.
Metrics show no drop in iOS control plane connections.
https://forum.tailscale.com/t/difficulty-with-ios-tailscale-...
Other posts had some troubleshooting guidance that wasnt effective. Note that it only failed on iOS. Still using it on my Debian boxes.
If you could point me at anything I would be very grateful. I’m using some other VPN container now that i don’t like!
My preferred ideal dream setup would be if the Tinc open source VPN had integration with OpenLDAP for ID management and could leverage Wireguard for speed. I am not a proper developer so I can only wish for such a thing or maybe pay someone to make this. Tinc has awesome user-space dynamic mesh routing but lacks user management and is slow compared to Strongswan/OpenVPN. Wireguard is fast. OpenLDAP can back-end ID management for just about anything, especially when combining it with oauth/saml and can be integrated into just about anything and that works for me because I am a fan of decentralized and/or distributed systems.
[Edit] Answering my own question. Custom SAML providers are only supported with the Enterprise edition. [1]
FWIW, tailscale is technically not free once more than 1 user, its a commercial service at the end of the day not some self-hosted open source application. They have extremely generous fair use policy in my experience and won't bill for a small number of users though. This means custom SSO is likely only a real issue for paying customers to begin with, although I can understand the frustration for the few users who do want it on the free tier.
I like these more traditional VPN style use tools for Wireguard, but you can always use the lower level version itself, if you’re comfortable with the configuration limitations.
That is how I use Tinc today. I briefly tried Wireguard but it works very much like OpenVPN and Strongswan in that it does not have dynamic mesh routing. Privacy advantages aside, the dynamic mesh routing I get from Tinc works around internet outages, albeit slower than I would like but a 2 minute routing outage is still better than {n} time it takes for ISP's to manually work around fiber breaks and datacenter network changes gone-wrong. But that is just my preference, it certainly isn't for everyone. I could probably accomplish this in Wireguard using weighted routing table rules but that gets complicated and messy very fast and I just lazy enough to avoid this. Perhaps someone has created an Ansible playbook that calculates all the routing rules and weights for this setup but I have not actually looked for it.
That said I can layer things on top of Wireguard, OpenVPN and Strongswan that accomplish similar goals such as using HAproxy but then protocol support is limited whereas a dynamic mesh in Tinc allows all TCP/UDP for my needs.
I have a full mesh of Wireguard tunnels configured between home/office/datacenters/laptop, and run bird[0] on the VPN endpoints to direct traffic between them.
Wireguard has none of that, not even the notion of a user. There are just keys in a special (unsupported by anything else) format that are assigned an IP address statically in a file. Oh, and the frigging software writes into that config file if you change anything.
Wireguard is a nightmare for any attempt at sane system administration.
It’s quite simple really: WireGuard is a building block. TFA mentions several systems built on top of WireGuard, that enables sophisticated handling of users/roles, authentication, ACLs, etc.
However, the system on top of WireGuard cannot just spit out a key to the user and call it a day.
The key (sorry…) is to make the system a) verify the identity of the users via an IdP (e.g. Okta or something similar) and then b) distribute short-lived keys, that can be revoked.
If one reads how Tailscale handles user authentication and key rotation, one will notice that they have a solid system in place for handling the keys and the product is much more sophisticated than OpenVPN.
I haven’t studied the approach of their competitors (e.g. Firezone) so I can’t comment on that.
References/suggested reading: https://tailscale.com/kb/1028/key-expiry/ ⦁ https://tailscale.com/blog/tailscale-key-management/ ⦁ https://tailscale.com/customers/gini/ ⦁ https://tailscale.com/kb/1009/protect-ssh-servers/
https://web.archive.org/web/20210919013400/https://community...
OpenVPN is simply bad at networking irrespective of any security considerations. (Wireguard, AFAICT, does the right thing with regard to MTU and is much simpler as a result. OpenVPN seems to go out of its way to be wrong.)
There's too many headers that are too big. If you do a simple L2 tunnel, you have three options: jumbo frames, packet fragmentation, or custom hacks. None are great.
> Linux has built in L2 tunneling, sans encryption
IIRC, because the extra header for the encryption layer pushes the MTU over 1500.
I'm using that in production with Babel (managing dynamic routes) with great success. Tinc had been solid for us for years, but once I actually payed attention to the performance hit, it was worth a bit of hassle to make it work over wireguard.
But more importantly, you can't just count lines of code as if they're all equivalent. There's a trusted core of code that is more important than the rest of the code, and WireGuard's trusted code is microscopic compared to OpenVPN. That's the right word in this case: "microscopic". It's some of the easiest code in the whole kernel to read, even given the cryptography.
Do you have some evidence for that or is it just speculation?
"But more importantly, you can't just count lines of code as if they're all equivalent."
You're right but the Wireguard white paper conclusion claims an advantage for Wireguard based solely upon the lines of code needed to implement.
OpenVPN, Wireguard and IPsec all have their advantages and disadvantages. I have and will use all 3 where appropriate based upon them.
Further, that is not what the WireGuard paper concludes. For instance: the paper makes a note of the fact that WireGuard is designed to be implemented without dynamic memory allocation, which is not a function of lines of code (in fact, it probably adds lines of code).
You do you, but as a practitioner in this space, I'd say using OpenVPN or IPSEC in 2022 without some powerful compatibility, regulatory, or network complexity concern to support it is malpractice. You might disagree, but I think you'd be in the minority of security engineers on the point. Feel free to ask around! The codebases for OpenVPN and the IPSECs are reviled.
The Wireguard paper makes notes of many things including the lines of code needed to implement.
"I'd say using OpenVPN or IPSEC in 2022 without some powerful compatibility, regulatory, or network complexity concern to support it is malpractice."
Life is complicated and those type of concerns are almost always in play which means OpenVPN and IPsec are also always in play. Wireguard is great where it is a fit but there are characteristics of Wireguard which also make it the more complicated and fragile solution in some circumstances.
- Logging of peer IPs when they initially connect or change (yes, you can do this with module flags, but it should come out of the box).
- Tieing WireGuard private keys to a source IP. As far as I know the endpoint flag does not enforce an IP, a peer can use a different one and still connect.
- More control over DNS resolution for endpoints. I want WireGuard to periodically refresh the endpoint IP when I change networks, for instance.
Out of curiosity, why do you want this?
It'd definitely be nice if wg-quick and the official apps supported it, though.
Alternatively if your client is Linux, there is:
https://github.com/WireGuard/wireguard-tools/tree/master/con...
I may have a critical server that only comes from 1-2 known, static, IPs.
Repeat this for dozens of servers. Now treat each of these servers as third parties not under your control. I don’t want one of these third parties using a key that doesn’t belong to them. As a silly example, let’s say I send one third party the key for my super important server by mistake. I would prefer it simply wasn’t able to connect.
You need a firewall rule anyway to let the wg traffic through.
WG was built to handle roaming, and the FW can do a great job of filtering by address already, so it makes sense to not bloat wg with extra code to me.
Remember your WG service could be terminating many tunnels from many different sources. Some yes roaming may be valid. Others not. There is no way in WG to selectively disable roaming for some keys but not others. This may be an intentional design decision in WG but I would argue it’s a poor one due to the above.
I consider the behavior a feature, allows for seamless roaming. You should not trust the IPs anyway, that's what the keys are for.
Yes WireGuard roams, which is the right behavior usually. What's your use case where an otherwise valid encrypted packet should be rejected based on source ip? Could you use ufw?
1) Client-server, where the client is behind NAT and the server is publicly available at some DNS. The client specifies the server by hostname as the endpoint, and the server doesn't bother specifying an endpoint. Client roams when they switch networks, server roams when they roll over the server, everybody is happy.
2) Peer-to-peer, where the nodes are directly addressable by IP address, whether by public IP or private virtual private IP. In this case, the node dialing in sets an endpoint of the node being dialed, and the node being dialed doesn't bother specifying an endpoint. Thereafter node identity is verified by private key and nodes can fully roam within the firewall-limited subnet.
In every case I've seen, roaming by default is the right choice.
These are oversights, and it's OK for software to have them, but they need to get added in the future. Requiring users to layer this stuff on top of WireGuard creates security footguns. WireGuard's implementation isn't set in stone, it should be improved.
Needless to say, Wireguard is preferred over other VPNs. Far less code.
(Spoofing other users if you already have access to our tf state isn't a vector we care about.. even if we logged user info for audit, that kind of access would let you fake that and worse anyway.)
Maybe it's not as flashy to set up from a non-technical-end-user perspective, but it's easy; it's just wireguard & terraform, both of which we're using anyway.
“The WireGuard private key is stored in the memory of the Pritunl client background service and also in the WireGuard configuration file. WireGuard uses a connection-less design and this private key could be used by an attacker to hijack the connection even if multi-factor authentication is used. In high security environments it is important to consider that OpenVPN connections with multi-factor authentication will not have these weaknesses. For this reason the server will quickly revoke WireGuard keys of inactive clients to limit the possibility of this occurring”
Does anyone know how others like Tailscale address this issue?
[1] https://github.com/WireGuard/wgctrl-go [2] https://github.com/pritunl/pritunl/blob/f82528ff2b7250965faf...
Because these keys aren’t the short life, in-memory session keys[1], but auth keys. Knowing this single key effectively bypasses any MFA you may have.
Seems like Tailscale has 180 days by default[2], which feels a bit too long for a person who expects MFA to be more proactive than this. Sure you can change the default to 1 day, but how many users know it’s possible or would even think to change that?
Compare that with OpenVPN where you can force every single auth attempt to use a password plus TOTP code for instance.