Iptables – OpenVPN per user rules while not routing Internet traffic

access-control-listiptablesopenvpnrouting

EDIT: I know that learn-address is what I would need to use to call a script (as specified in the openvpn-netfilter project) to set the firewall rules. I guess my question is more related to the config.ovpn script. How do you configure the client.ovpn files to simultaneously learn which routes to the user needs, while also keeping Internet traffic to the user's ISP?

I have a question about how to do per user firewall rules, while also not routing Internet traffic through an OpenVPN server. I'm trying to setup a VPN server for a group of friends and I as we work on a project. I will implement something like this Github project: https://github.com/gdestuynder/openvpn-netfilter. This will enable the VPN server to lookup ACLs for a user, and implement them using iptables on the server side. All other traffic would be dropped.

For my own personal home VPN, I know I can use the following in my client.ovpn config to not route Internet traffic through the VPN:

route-nopull
route 192.168.1.0 255.255.255.0

Where 192.168.1.0/24 is my home subnet, and 10.8.0.0/24 (not shown) is the DHCP IP range of the tun adapter. I know placing that in the client's configuration overrides the server setting push "redirect-gateway def1 bypass-dhcp".

This is where I get confused: I already know my home subnet is 192.168.1.0/24, so I can easily place that in the client.ovpn file. But if I have no knowledge of the subnets/IPs I have access to (as most users don't), how does OpenVPN dynamically push per user VPN rules to the client?

In other words, if user1 has acess to 10.0.0.2 and 10.0.2.10 and user2 has access to 10.0.2.10 and 10.0.3.4, how does OpenVPN know to push the right routes to each user, while using the same generic client.ovpn configuration?

Best Answer

You can push individual openvpn directives to your clients using client specific configuration files in the client-config-dir.

In the server config file include the directive:

client-config-dir ccd

and create this directory in case it does not already exist in your openvpn path, for example:

/etc/openvpn/ccd

Now create a config file per client in the ccd directory having the same name as the client's X509 common name. The following options are legal in a client-specific context: push, push-reset, iroute, ifconfig-push, and config.

For example to push routes to a client with CN user1 in his certificate:

echo 'push "route 10.0.0.2 255.255.255.255 10.8.0.1"' >> /etc/openvpn/ccd/user1
echo 'push "route 10.0.2.10 255.255.255.255 10.8.0.1"' >> /etc/openvpn/ccd/user1

For this to work you need to pull configuration directives on your clients from the server using the pull directive.

You may have the directive client in your client-config, which is a helper directive and expands as follows:

pull
tls-client

Do not use route-nopull in combination as it would stop the client pulling routes. If you need redirect-gateway on certain clients to route all traffic through the VPN subnet, you can place this directive just in those client configuration files and not in your server config file for all clients. The redirect-gateway directive automatically executes routing commands to cause all outgoing IP traffic to be redirected over the VPN. See man page.