| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| vpn-connection-sharing-SCRIPT-2026-01-05.tar | 2026-01-05 | 686.1 kB | |
| README.md | 2026-01-05 | 5.3 kB | |
| Totals: 2 Items | 691.4 kB | 0 |
Script for VPN Connection Sharing
Easily share a VPN connection with your virtual machines.
By Jelle Geerts.
December 29, 2025
What this script does:
It allows you to easily share the VPN connection of your system with virtual machines (or containers) that are running on the same (VM host) system.
The script has been tested with an IPsec VPN connection (which is usually implemented via the XFRM mechanism in Linux). The VPN client used for this test was strongSwan, which is usable via the NetworkManager GUI if you have the right packages installed.
How to use this script:
Steps:
-
Copy the script to a secure location that only the
rootuser can write to, such as/opt. For example, the full path might be/opt/vpn-connection-sharing/. -
Configure the script by editing
config.sh. -
Then, create a desktop launcher for the
vpn-connection-sharing-daemon-WRAPPER.shscript, and add the created launcher to your desktop environment, such as in a desktop panel (taskbar). -
(optional) Generate a sudoers file and place it in the
/etc/sudoers.d/directory such that the script is usable without having to enter a password every time you launch it. To generate such a sudoers file, a helper script is included, which we can call like so:
# Select everything between the scissor lines and enter
# it into a terminal.
# --8<----------------
./generate-sudoers-template.sh | \
sudo tee -a \
/etc/sudoers.d/nopasswd-vpn-connection-sharing
# -->8----------------
Security warning:
By doing this, we are giving the wrapper script (mentioned in step 3) the ability to run sudo without any user interaction. Since this is a security risk, please install the script into a secure location (see step 1) that only the root user can modify. This prevents malware from modifying (hijacking) the script to run nefarious commands on your system.
Done! Now, whenever you're using VMs (or containers) and wish to share your host system's active VPN connection with the virtual machines, simply launch the script via the launcher you created.
Features:
- The script automatically adds/removes the SNAT firewall rules whenever the VPN connection state changes (when it connects or disconnects).
How this script works:
Basically, for each remote network (behind the VPN) that you want to be able to reach from your virtual machines (which run on the same system that is connected to the remote VPN), the script adds SNAT firewall rules to translate the source address of the traffic, such that the traffic is sent via the host system's active VPN connection. (These rules are temporary and lost when rebooting the host system.)
For example, we might configure the script so it effectively performs the following actions whenever the VPN connection on the host system becomes active.
nft add rule ip nat POSTROUTING ip saddr 192.168.122.0/24 \
ip daddr 172.20.100.0/24 snat to 10.10.10.2/32
nft add rule ip nat POSTROUTING ip saddr 192.168.144.0/24 \
ip daddr 172.20.100.0/24 snat to 10.10.10.2/32
Of course, the actual network addresses depend on the configuration (see config.sh). But basically, this is what the script boils down to.
What the above firewall rules do:
- The first rule adds an SNAT rule for VMs that use the VM network 192.168.122.0/24 (this network is often the default network in QEMU/KVM/libvirt). In this example, a VM is using the IP address 192.168.122.100. The host system (which runs the VMs) has an active VPN connection with IP address 10.10.10.2. The SNAT rule allows the VM to reach the network 172.20.100.0/24. Whenever the VM generates traffic to an IP address in that network, such as 172.20.100.150, the source address of the packet is changed from 192.168.122.100 to 10.10.10.2. That way, the packet leaves the host system via the active VPN connection.
- The second rule is almost the same, but this time we allow VMs that use the 192.168.144.0/24 network to reach the 172.20.100.0/24 network via the VPN interface of the host system.
Design choices:
- This script is designed to be launched manually, instead of running as a permanently active system service. The reason is twofold: First, strictly speaking, sharing a VPN with virtual machines might be considered a security risk, depending on the nature of your work. Second, the script requires some configuration (it doesn't know which VM networks you have, or which VPN networks you want your VMs to be able to access), and therefore it may be more intuitive to have to launch the script manually, so you see an active terminal window that reminds you about the VPN connection sharing. This way, if you're debugging some networking problem, you're less likely to forget about this script being a factor that is affecting your network traffic. Also, if the VPN configuration changes on the remote end, like when you add new networks to the phase 2 IPsec security associations (SAs), then you're probably less likely to forget to reconfigure this script as well, such that it matches the VPN networks again.