tonarino / innernet

A private network system that uses WireGuard under the hood.
https://blog.tonari.no/introducing-innernet
MIT License
5k stars 186 forks source link

config option to flag a cidrs peers not to be able to connect peers of the same cidr #62

Open ghost opened 3 years ago

ghost commented 3 years ago

I am not sure how to address this, i believe, the behavior is sort of intentional, but it might be also b.a.d...

Problem: Peers of the same cidr can connect each other without further actions. It makes a lot of sense to allow this configuration on site2site vpns and also on cidrs for servers, as any service will have its own authentication, but not on human users local endpoint systems (classic name: roadwarriors).

I think, this is problematic as most devs see their local machine also as server for testing services locally and these may run without any authentication as they are local to the dev.

These services are exposed to the vpn, if they are not bound to a dedicated interface. Most services are really bound to 0.0.0.0 as default, if they are not databases which usually bind to 127.0.0.1 as default.

Even if the developer does not portforward her innernet port to her cablemodem/router: It is sufficient, if she initiates a connection to another vpn and keep it running to expose this port as it is udp.

Example: Alice and Bob are humans and in the cidr humans. Machine-A is a service in the cidr svc. Humans cidr is allowed to connect to cidr svc.

Alice connects to machine-a (vpn peer, not in her cidr, but allowed) Bob does inn list --tree and nmaps Alices ip address:

$ nmap 10.42.4.1
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-23 08:56 UTC
Nmap scan report for alice.fcloud.wg (10.42.4.1)
Host is up (0.024s latency).
Not shown: 996 closed ports
PORT     STATE SERVICE
80/tcp   open  http
3000/tcp open  ppp
8086/tcp open  d-s-n
8888/tcp open  sun-answerbook

From Alices point of view (the nmap only catches tcp):

[0] % sudo netstat -tpaun |awk '{print $1,$4}' | grep -E '0.0.0.0|:::'
tcp 0.0.0.0:80
tcp6 :::8086
tcp6 :::8888
tcp6 :::3000
tcp6 :::80
udp 0.0.0.0:49029
udp 0.0.0.0:68
udp 0.0.0.0:5353
udp6 :::49029

In a classic (centralized) wireguard vpn network it is easy to prevent this by managing routing on the central server and sending human peer vpn config stencils maintaining the AllowedIPs netmask as /32.

To achive the same with innernet i would need to create a lot of /30 nets with one human user in each. And i would need to enable any single human peer instead of groups of users in the same cidr.

Please keep in mind that it will not help to setup local firewall rules against this on Alices machine as the traffic has already passed the external interface (is authenticated and decrypted) and than checked, if the source ip is allowed. (https://www.wireguard.com/#cryptokey-routing)

As an admin i feel the need trying to protect my users as most as possible against unforeseen co-drivers on their personal hardware. Kudos to the attendees in the discord discussion which made it possible to sharpen the request.

I propose to introduce a configuration flag (prevent inter-cidr communication or similar) to prevent that peers of a cidr can connect each other without further configuration.

At least we should add a remark to the security-recommendations chapter, but i feel that most classical users will not read it.

mcginty commented 3 years ago

Thanks for the great issue!

The current behavior is very much intentional and is mentioned whenever a CIDR is created, but it was definitely designed with a certain scenario in mind where each CIDR was considered more like a traditional LAN and associations were between CIDRs and more like "site-to-site" connections.

Please keep in mind that it will not help to setup local firewall rules against this on Alices machine as the traffic has already passed the external interface (is authenticated and decrypted) and than checked, if the source ip is allowed.

I'm not sure I understand this part, local firewall rules should work for this use case. You can spin up a machine with an HTTP server listening on http://0.0.0.0:80, then we can setup a quick-and-easy UFW firewall configuration like so:

# Assuming you have an innernet called "evilcorp", configured to listen on 51820.
sudo ufw allow 51820/udp

Then try to reach that HTTP server from a connected peer, netfilter will deny.

Now add another rule:

sudo ufw allow in on evilcorp to any port 80 proto tcp

And the HTTP server should become reachable.

As an admin i feel the need trying to protect my users as most as possible against unforeseen co-drivers on their personal hardware.

Right - for innernet to run networks that have peers with varying levels of trust, we should reconsider this default. Perhaps it's best to, instead of a specific flag, have all CIDRs default to not exposing its own peers to each other, and then one can simply add an association between the CIDR and itself to have peers within that CIDR be visible to each other...

ghost commented 3 years ago

Sorry for the long time for that answer. You are totally right with running firewall services on the users machine, my mistake (i made a typo in the input chain drop policy in my testing).

My point: A lot of enduser machines do not run (proper) local firewall services, they think to be hidden behind a NAT gateway with proper firewall configuration and they have not portforwarded their innernet port to that gateway. Other peers are able to connect these machines.

For my perspective i am fine with not exposing peers of the same cidr to each other, it will fit to my ideas of grouping human and non human peers and connect them with little effort.

bmullan commented 3 years ago

@mcginty

In your previous comment I noticed you switched from UDP to TCP in the 2 examples...

I'm not sure I understand this part, local firewall rules should work for this use case. You can spin up a machine with an HTTP server listening on http://0.0.0.0:80, then we can setup a quick-and-easy UFW firewall configuration like so:

# Assuming you have an innernet called "evilcorp", configured to listen on 51820.

sudo ufw allow 51820/udp

Then try to reach that HTTP server from a connected peer, netfilter will deny.

Now add another rule:

sudo ufw allow in on evilcorp to any port 80 proto tcp

In the first example of "sudo ufw allow" you specify only UDP

In the second example of "sudo ufw allow" you specify only TCP is that correct?

brian

mcginty commented 3 years ago

@bmullan yeah, the 51820/udp is for WireGuard, exposed to the internet, 80/tcp for the server that you are allowing to be visible only over the WireGuard network.

Kerwood commented 3 years ago

Having an option to either enable or disable Private VLAN/port isolation on a CIDR would be nice. Personally i wouldn't "secure" my services on the server CIDR with port isolation, but I see the benefit of enabling it on a client CIDR.

mcginty commented 3 years ago

@Kerwood I've been thinking about having innernet be able to automatically add netfilter/pf rules, and I think this would accomplish the "private VLAN isolation" on OS's that the article's talking about, unless I'm misunderstanding.

Kerwood commented 3 years ago

I'm not sure on how to accomplish it, but I guess you could use netfilter to protect one self from other peers.

tianon commented 3 years ago

Wouldn't this be more directly accomplished by not having the members of the VLAN have each other as "peers" inside WireGuard? (Then there's a natural "firewall" between them because they're not connected to begin with and just happen to share a CIDR in the larger IP space.)