-
Notifications
You must be signed in to change notification settings - Fork 192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add more protections against OS configurations that allow IP spoofing #26
Comments
My understanding of Wireguard is that it provides this, not innernet itself: "At the heart of WireGuard is a concept called Cryptokey Routing, which works by associating public keys with a list of tunnel IP addresses that are allowed inside the tunnel. Each network interface has a private key and a list of peers. Each peer has a public key. Public keys are short and simple, and are used by peers to authenticate each other. They can be passed around for use in configuration files by any out-of-band method, similar to how one might send their SSH public key to a friend for access to a shell server." Innernet is a wrapper around associating IPs and interfaces and would not provide the authentication, Wireguard does. |
Yes, traffic should be dropped that doesn't arrive from the proper interface. |
Oh yes, absolutely agree. Thanks so much for the well-written issue @Spindel, and sorry for taking a bit to reply.
|
You're welcome, and the plan ahead seems like a decent one. Regarding how to add the firewalling rules, that's always tricky, as Linux networking is in a bit of a flux to begin with (low level API's like nftables, eBPF, iptables, high level like firewalld, ufw, etc. ) and then adding Windows and macOS all make it a bit tricky. Even then, address conflicts between local and VPN network ranges can happen, especially on devices that roam (wifi at the office might well be in the same range, etc.) making the service hard to use. ( This was one of the cool features from tailscale, their use of non-routable addresses. ) Sadly, I don't have any good solutions, only problems, and maybe a simple drop-in script might be the better solution? ie, declare an script that will be called with <interface_name> <network_range> when topology changes, and default that script to be something useful? |
Awesome, thank you for the help
|
As far as I understand, the problem is that WireGuard doesn't do the routing (much less authentication) in the case discussed here: The attacker simply sets a different IP address for himself (a "fake IP address" if you will) and starts sending traffic from that IP to the innernet client which will arrive on the client's eth0/wlan0 interface (not wg0) and be forwarded to the super-seekrit service. So until the issue here is solved, any incoming traffic from innernet adresses will still need to be authenticated separately. I would say this is a major issue because it implies that running services like sshd or web servers strictly "inside" the innernet is actually not possible at the current time (or only feasible with additional manual effort). Put differently: There is no included firewall and services listening on "internal" innernet IP addresses are still accessible from the outside. |
As an addendum to my previous comment, I've got a question regarding the attack vector discussed here (I'm not too familiar with the ins and outs of the Linux network stack): If the attacker disguises as 10.42.0.8 and sends a message to our innernet client at 10.42.0.1, will a response by the client then reach the attacker? After all, the network on the client will be set up such that packets to 10.42.0.0/16 should get routed through the wg0 interface. So how does this work if a connection is initiated by a message whose sender is some IP in the range 10.42.0.0/16 but which doesn't reach the client through the wg0 interface? Does this possibly depend on whether it's a UDP or a TCP connection, i.e. whether the client's "super-seekrit service" was listening for incoming UDP or TCP connections? (I imagine for UDP the client's response shouldn't reach the attacker but for TCP it would but I could be mistaken.) |
I clearly wasn't familiar enough either, but it's quite interesting when you dig into it. The security issues with the current model can be broken into two main components, as I currently understand it: 1. Private IP Spoofing via non-strict Reverse Path Filtering (RFC 3704)Most Linux distros, for example, (with the exception of RHEL) default to what's called "loose" Reverse Path Filtering. Say you have two interfaces: One would think that since you send packets to As an example though for the innernet server, this is not an open vector if you're running it on a server whose firewall is blocking all traffic except for FixesOn the application level, you can bind a socket to a specific interface, which is the fix I'm currently implementing first for On the OS level, There may also be less-invasive firewall rules that can also be added to simply block traffic from 2. CSRF-like attacksThere are any number of ways an HTTP request can be made on your behalf without your consent, and peers should be able to prevent random HTTP requests generated from other applications on their machine from being accepted by FixesThe server can generate a token when the interface is brought up, and require that the client sends that token along with every request (similar to how most API keys work out there). The client can store that in Patch releaseFixes are in the works, thanks everyone for being patient and contributing to the discussion. Let this be a reminder that this is experimental software and not to be considered fully secure until much more rigorous review and breaking has occurred. |
This is one many upcoming changes to address IP spoofing issues. See #26 for more details.
This is one many upcoming changes to address IP spoofing issues. See #26 for more details.
This is one many upcoming changes to address IP spoofing issues. See #26 for more details.
This is one many upcoming changes to address IP spoofing issues. See #26 for more details.
Unfortunately, most applications[0] don't provide config options for this, so short of patching most applications one desires to use, I don't think this is a feasible option. [0]: In particular, this is also true for Docker which only allows binding to a certain IP address, not interface, leading to the very same issue we're discussing here.
This and/or it could make sure iptables is set up correctly and to warn the user if necessary. Maybe one could make this a config option? (Or make it the default and add an option to disable it.) |
This is one many upcoming changes to address IP spoofing issues. See #26 for more details.
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
|
It's not sufficient.
... where Considering WireGuard is entirely L3, this should be enough to filter all traffic addressed on 10.42.0.0 from reaching other interfaces, and requires no modification to existing software (my test was A similar rule should be added for other addresses assigned to the WireGuard interface, such as any possible IPv6 addresses, and it'd likely be good to extract the two interfaces into a set in that case. PS: it'd probably be desirable to use EDIT: https://wiki.nftables.org/wiki-nftables/index.php/Atomic_rule_replacement the above is not very atomic, but that should be fine, if this only happens after an interface being added and before any peers or configuration is established. |
FYI there is currently a discussion on HN on how Tailscale prevents IP spoofing which might be of interest here. |
In the innernet blog-post there are some claims about authenticated and trust in IP-addresses.
However, innernet does not actually live up to these claims.
Test methodology:
With three devices:
Assuming that the client LAN is 192.168.0.1/24.
Assuming that the innernet server is set up with the default cidr of 10.42.0.0/16, we hook up the client and enable the server.
Next, we put a super-seekrit service on the client IP of 10.42.0.1 ( telnet, with admin/admin as password!)
On the "rogue" actor, we then do the following (assuming that eth0 is the ip address):
Now the "rogue" client can freely access services that are supposed to only be accessible to internal clients on the innernet ip.
Problem
Linux by default responds to traffic directed to it's own IP addresses on any interface. This can be adjusted with a sysctl, but that sysctl should not be configured by software as a security mechanism, as it may break a fair few things. The proper(Er) solution is to add an interface-level filter for traffic.
This means that innernet client should also make sure to drop traffic directed to it's internal IP that arrives on any interface other than the wg interface.
The text was updated successfully, but these errors were encountered: