mozilla-vpn-client icon indicating copy to clipboard operation
mozilla-vpn-client copied to clipboard

VPN-5865 - Move a few rules from ip rules to the firewall

Open brizental opened this issue 11 months ago • 4 comments

The approach for these firewall rules is "deny by default". I have added two new chains to our Linux firewall configuration:

chain mozvpn-input {
		type filter hook input priority filter; policy drop;
# Allow traffic to the loopback interface
		meta iiftype loopback accept
# Allow traffic to the VPN interface
		iifname "moz0" accept
# Allow udp traffic to the VPN servers
		meta protocol ip meta l4proto udp @nh,96,32 @mozvpn-addrset accept
# Allow LAN traffic and any other exclusision the user might have set up
		ip6 saddr fc00::/7 accept
		ip6 saddr ff00::/8 accept
		ip saddr 10.0.0.0/8 accept
		ip saddr 172.16.0.0/12 accept
		ip saddr 192.168.0.0/16 accept
		ip saddr 224.0.0.0/4 accept
# Allow DHCP
		udp sport 68 ip daddr 255.255.255.255 udp dport 67 accept
		udp sport 68 udp dport 67 accept
	}

	chain mozvpn-output {
		type filter hook output priority filter; policy drop;
# Allow traffic from the loopback interface
		meta oiftype loopback accept
# Allow traffic from the VPN interface
		oifname "moz0" accept
# Allow udp traffic from the VPN servers
		meta protocol ip meta l4proto udp @nh,128,32 @mozvpn-addrset accept
# Allow LAN traffic and any other exclusision the user might have set up
		ip6 daddr fc00::/7 accept
		ip6 daddr ff00::/8 accept
		ip daddr 10.0.0.0/8 accept
		ip daddr 172.16.0.0/12 accept
		ip daddr 192.168.0.0/16 accept
		ip daddr 224.0.0.0/4 accept
# Allow DHCPv4 (no v6... can add it, but on Windows we don't have it for the longest time and all is fine)
		udp sport 68 ip daddr 255.255.255.255 udp dport 67 accept
		udp sport 67 udp dport 68 accept
# Stop any DNS queries going outside of the tunnel
		udp dport 53 reject
		tcp dport 53 reject with tcp reset
	}

~On the Windows firewall we also add rules to allow DHCP packets to bypass the VPN tunnel, which I want to add here as well before we merge.~ Done.

Notice the default policy for all input and output packets is to drop, unless the packet matches any of the rules in this table.

By moving these rules to the firewall I was able to clean up the routing table in the ip rules to:

$ ip route show table 51820
default dev moz0 proto static scope link 

No routing is required, when packets get here they have already been "routed".


I have also done a bit of refactoring and moved the firewall out of the WireguardUtils class.

Note: I am sorry for the reformatting of netfilter.go I only noticed that when I opened this PR. I can undo it if you all hate it too much... But that would not be to ostright forward. I reccomend reviewing commit by commit, because fortunately the reformatting is all concentrated in the first commit -- where there are no real changed to that file :woman_facepalming:

brizental avatar Mar 21 '24 17:03 brizental

Some additional things that need testing to make sure that this doesn't break things:

  • Please install the ufw package on Ubuntu and make sure that things continue to work as expected. This installs a stricter user firewall software on the machine that will attempt to enforce stateful packet filtering. In the past we have encountered a bunch of pain in this regard, and that's why there were a bunch of connection tracking rules in the old firewall code.

  • Please enable reverse-path-filtering in the kernel (eg: for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 2 > $i; done) and ensure that things continue to work as expected. This adds an additional inbound packet filtering technique that some (but not all) kernels will use as the default. The gist of the check here is that packets must be received from the same interface on which they would be sent. It helps prevent IP spoofing and DDoS attacks, but if we don't get the fwmark settings just right then it can also cause the inbound wireguard traffic to fail too.

  • We also need to test this on an IPv6 network to make sure that we aren't causing a breakage of IPv6 connectivity. This test should include accessing IPv6 local network resources as well as reaching IPv6 destinations on the internet.

oskirby avatar Apr 08 '24 18:04 oskirby

I would also like to review the firewall rules around IPv6 neighbor discovery that Mullvad includes to make sure that we aren't forgetting anything important.

oskirby avatar Apr 08 '24 18:04 oskirby

Has this been tested with app exclusions? I think that we are missing a rule to permit excluded apps to be sent outside the tunnel. This would be a rule something to the effect of: meta mark $fwmark accept

oskirby avatar Apr 08 '24 18:04 oskirby

I would also like to review the firewall rules around IPv6 neighbor discovery that Mullvad includes to make sure that we aren't forgetting anything important.

I have added this to the ticket.

Has this been tested with app exclusions? I think that we are missing a rule to permit excluded apps to be sent outside the tunnel. This would be a rule something to the effect of: meta mark $fwmark accept

Good call, I have added this rule. Turns out I am currently getting error around marking cgroupv2 traffic which is preventing me from testing this. I will try to downgrade cgroupsv1 and test this again.

brizental avatar Apr 11 '24 09:04 brizental