| 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. |