Linux: Restrict User/Group to Access the Internet only via VPN using Pyroman

On Linux, if you need to have a user or an application running with a dedicated user access the internet only if a VPN connection is active, you can do that relatively simply with a few firewall rules. One way is to use plain iptables statements. On Ubuntu, I’m using a iptables wrapper called Pyroman.

sudo apt-get install pyroman

In the example below, I am assuming that the system does currently not have any iptables rules in place. So, we are allowing any inbound and outbound traffic and are just restricting what matches the rule. So, in file /etc/pyroman/00_iptables-defaults.py we are commenting out the DROP defaults and replace them with ACCEPT lines.

# /etc/pyroman/00_iptables-defaults.py
# add_chain("INPUT",                     default="DROP")
add_chain("INPUT",                     default="ACCEPT")
# add_chain("OUTPUT",                    default="DROP")
add_chain("OUTPUT",                    default="ACCEPT")

Then connect to your VPN and see what network device it uses.

ip link

Also know the user or group name you wish to restrict. Then create a file in the /etc/pyroman/ directory with a name that makes sense to you. In my example, I call it 05_deluge.py.

# /etc/pyroman/05_deluge.py
iptables(Firewall.output, "-p tcp -m owner --gid-owner debian-deluged ! -o tun0 -j %s" % Firewall.reject)
iptables(Firewall.output, "-p udp -m owner --gid-owner debian-deluged ! -o tun0 -j %s" % Firewall.reject)

In the example above, I am applying the rule on the group with the name debian-deluged. Change it to your use case. Also change the device from tun0 to whatever device your VPN creates.

Here is another example using Nordvpn. Its client creates a device called nordlynx.

  • --uid-owner – Match a user ID.
  • --gid-owner – Match a group ID.

Now just make sure, Pyroman is enabled with every system boot:

sudo systemctl enable pyroman

Test it before relying on it! If you are using deluged, the same service as in my example, note that it needs a restart whenever the VPN connection is established:

sudo systemctl restart deluged.service

This could be automated at some point, I guess.