Title: OpenVPN on OpenBSD in its own rdomain to prevent data leak | |
Author: Solène | |
Date: 16 December 2021 | |
Tags: openbsd openvpn security | |
Description: This article explains how to prevent programs to access | |
the Internet through a non VPN interface. | |
# Introduction | |
Today I will explain how to establish an OpenVPN tunnel through a | |
dedicated rdomain to only expose the VPN tunnel as an available | |
interface, preventing data leak outside the VPN (and may induce privacy | |
issues). I did the same recently for WireGuard tunnels, but it had an | |
integrated mechanism for this. | |
Let's reuse the network diagram from the WireGuard text to explain: | |
```network diagram in text | |
+-------------+ | |
| server | tun0 remote peer | |
| |---------------+ | |
+-------------+ | | |
| public IP | | |
| 1.2.3.4 | | |
| | | |
| | | |
/\/\/\/\/\/\/\ |OpenVPN | |
| internet | |VPN | |
\/\/\/\/\/\/\/ | | |
| | | |
| | | |
|rdomain 1 | | |
+-------------+ | | |
| computer |---------------+ | |
+-------------+ tun0 | |
rdomain 0 (default) | |
``` | |
We have our computer and have been provided an OpenVPN configuration | |
file, we want to establish the OpenVPN toward the server 1.2.3.4 using | |
rdomain 1. We will set our network interfaces into rdomain 1 so when | |
the VPN is NOT up, we won't be able to connect to the Internet (without | |
the VPN). | |
# Network configuration | |
Add "rdomain 1" to your network interfaces configuration file like | |
"/etc/hostname.trunk0" if you use a trunk interface to aggregate | |
Ethernet/Wi-Fi interfaces into an automatic fail over trunk, or in each | |
interface you are supposed to use regularly. I suppose this setup is | |
mostly interesting for wireless users. | |
Create a "/etc/hostname.tun0" file that will be used to prepare the | |
tun0 interface for OpenVPN, add "rdomain 0" to the file, this will be | |
enough to create the tun0 interface at startup. (Note that the keyword | |
"up" would work too, but if you edit your files I find it easier to | |
understand the rdomains of each interface). | |
Run "sh /etc/netstart" as root to apply changes done to the files, you | |
should have your network interfaces in rdomain 1 now. | |
# OpenVPN configuration | |
From here, I assume your OpenVPN configuration works. The OpenVPN | |
client/server setup is out of the scope of this text. | |
We will use rcctl to ensure openvpn service is enabled (if it's already | |
enabled this is not an issue), then we will configure it to use rtable | |
1 to run, this mean it will connect through the interfaces in the | |
rdomain 1. | |
If your OpenVPN configuration runs a script to set up the route(s) | |
(through "up /etc/something..." directive in the configuration file), | |
you will have to by add parameter -T0 to the command route in the | |
script. This is important because openvpn will run in rdomain 1 so | |
calls to "route" will apply to routing table 1, so you must change the | |
route command to apply the changes in routing table 0. | |
```instructions | |
rcctl enable openvpn | |
rcctl set openvpn rtable 1 | |
rcctl restart openvpn | |
``` | |
Now, you should have your tun0 interface in rdomain 0, being the | |
default route and the other interfaces in rdomain 1. | |
If you run any network program it will go through the VPN, if the VPN | |
is down, the programs won't connect to the Internet (which is the | |
wanted behavior here). | |
# Conclusion | |
The rdomain and routing tables concepts are powerful tools, but they | |
are not always easy to grasp, especially in a context of a VPN mixing | |
both (one for connectivity and one for the tunnel). People using VPN | |
certainly want to prevent their programs to not go through the VPN and | |
this setup is absolutely effective in that task. |