cisagov / ansible-role-openvpn

Ansible role to install an OpenVPN server and configure it to authenticate users certificates against FreeIPA.
Creative Commons Zero v1.0 Universal
8 stars 2 forks source link

Block routing of packets between VPN clients #53

Closed felddy closed 1 year ago

felddy commented 2 years ago

💡 Summary

Configure the VPN server to prevent the routing of packets from one VPN client to another.

Motivation and context

Routing of client packets to other clients should not be the default configuration. In fact, OpenVPN isolates clients by default unless the client-to-client options is specified. Since we are setting up packet-forwarding with this role we are allowing clients to see each other.

From https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/ : --client-to-client:

Because the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router. The --client-to-client flag tells OpenVPN to internally route client-to-client traffic rather than pushing all client-originating traffic to the TUN/TAP interface.When this option is used, each client will "see" the other clients which are currently connected. Otherwise, each client will only see the server. Don't use this option if you want to firewall tunnel traffic using custom, per-client rules.

Implementation notes

This should relatively easy to implement. I think it would require the addition of a firewall rule preventing the hairpin routing:

iptables --append FORWARD --in-interface tun0 --out-interface tun0 --jump DROP

See:

Acceptance criteria

How do we know when this work is done?

felddy commented 1 year ago

The correct call would be to insert at the head for the FORWARD chain and not append to the end:

iptables --insert FORWARD 1 --in-interface tun0 --out-interface tun0 --jump DROP

This was tested successfully on staging.

Since we are using ufw on this instance, we should modify the ufw configuration to handle this change. It could also be handled in the same place we enable the NATing.

See:

After thinking about this more, it should live in the cloudinit script. This is where we are turning on NATing, which is enabling peer-to-peer routing.

felddy commented 1 year ago

New hotness to get tunnel device:

# python3 -c "from ipaddress import IPv4Network; print(IPv4Network('10.128.248.0/255.255.248.0').network_address)"
10.128.248.0

# ip route get 10.128.248.0 | head -n1 | sed 's/^.*dev \([^ ]*\).*$/\1/'
tun0