Closed patschi closed 10 months ago
This is a known issue stemming from an implementation of OpenVPN dating back decades. Tun behaviour hasn't changed and /dev/tunX devices are still not providing alias support. The whole thing is designed to fail and other VPNs using tun devices will inherently break this. I know that @AdSchellevis is rewriting OpenvPN in MVC at the moment and we might discuss options, but I'm a bit pessimistic about the outcome given the constraints that tun driver gives us.
Cheers, Franco
Ah, good to know! I was able to find a few threads and similar GitHub issue, but not this specific behavior is a known issue.
Doing some brainstorming, I think the easiest way might be using $vpnid
across WireGuard, OpenVPN and IPsec (for tun modes). So the first WG VPN is vpnid=1, the 2nd VPN being OpenVPN VPN then gets vpnid=2, and so on. The while loop could stay, identifying the next available, unused vpnid.
But granted, not checked how complicated/feasible the implementation will be.
Yep, you'd need a shared implementation. I think also zerotier openconnect and others are using tun driver...Not sure how feasible this is depending on the individual service's constraints. And the last bit is having all on MVC which OpenVPN is currently not, but at least it will be in the near future as mentioned earlier.
There might be another option using the "original" interface name which is actually shown by ifinfo
(but oddly enough not ifconfig
):
# ifinfo ovpnc1
Interface ovpnc1 (tun1):
[...]
So after rename we could still derive the actual tun/tap index number...
Cheers, Franco
There might be another option using the "original" interface name which is actually shown by ifinfo (but oddly enough not ifconfig):
For the new MVC version we could easily expose the device (tun/tap) number to the user in the advanced settings as well, we are storing and validating it anyway.
The only challenge I see is that the device number is a dynamic value at device creation time (depending on how much else was configured in the meantime by other VPNs).
In particular OpenVPN dev-node
needs to be switched to a runtime value from ifinfo output which would probably fix most of the concerns...
I can take a look at that for the new version, thought we could influence the number in /dev/ as well, but I'm probably wrong.
ah, yes you can:
ifconfig tun99 create
creates /dev/tun99
That is what we do, but we fail to consider that it might already be used by something else so we cannot rely on $vpnid
being the actual device node number.
The workflow is not very complicated since we rename the OpenVPN device anyway before we start using it. We just have to give the right number to openvpn config as mentioned above.
Unfortunately openvpn can't map it back by itself, it still feels a bit silly to tell it which device to use and what it's linked to. But when you're able to choose the number, it would be easier to choose a number that's likely not taken (start at 100 for example). The downside of asking the number on generating the config is that these are less loosely coupled (as you can't generate it statically anymore)
Yep, fixed device range offset might be a good idea. Just offset $vpnid
for tun/tap creation and done :)
Yep, you'd need a shared implementation.
Might be possible using the global $config
variable here.
To add: How's the idea in having a pre-start-hook when starting up OpenVPN? So instead of calling the openvpn binary, we call a script which is doing preparation ahead of the start.
In other words: https://github.com/opnsense/core/blob/bebf3a2a7c2de1eb102ff41aefc401d8e999e52f/src/etc/inc/plugins.inc.d/openvpn.inc#LL933C19-L933C52
Before we call the binary, we can adjust the OpenVPN config to determine a unused /dev/tunX
interface. Then rewrite and start it.
I'm not sure how much VPN sessions the largest OPNsense instances out there have or if there might be scenarios where /dev/tun
might exceed e.g 100 for other VPN sessions for some reasons (some application issues where tun's get stuck or whatsoever).
To add: How's the idea in having a pre-start-hook when starting up OpenVPN?
OPNsense OpenVPN integration is a giant pre-start-hook ;)
But this is what Ad meant with dynamic data influencing configuration file. I think the point is really that OpenVPN will not figure out the device node name itself. And the fixed interface offset is probably the easiest fix too.
This issue has been automatically timed-out (after 180 days of inactivity).
For more information about the policies for this repository, please read https://github.com/opnsense/core/blob/master/CONTRIBUTING.md for further details.
If someone wants to step up and work on this issue, just let us know, so we can reopen the issue and assign an owner to it.
Important notices
Before you add a new report, we ask you kindly to acknowledge the following:
Describe the bug
It looks like there is a naming collision with
/dev/tun
interfaces when using OpenVPN and WireGuard-go on the same OPNsense machine. I was in need in configuring my first OpenVPN server for connecting mobile clients, but after setting this up according to the OPNsense documentation the start failed with:So essentially the culprit is:
How the naming scheme works I wanted to understand more, so I checked the code. That seems to be the most interesting piece: https://github.com/opnsense/core/blob/bebf3a2a7c2de1eb102ff41aefc401d8e999e52f/src/etc/inc/plugins.inc.d/openvpn.inc#L461-L469
Here you can see that always
[mode][vpnid]
is used - so when using the first OpenVPN client with tun mode, this will betun1
.As you can see on the logs above, in my case the
$vpnid
is1
:Here in the code we can see it starts its numbering scheme with 1: https://github.com/opnsense/core/blob/bebf3a2a7c2de1eb102ff41aefc401d8e999e52f/src/etc/inc/plugins.inc.d/openvpn.inc#L220-L224
While this code is checking the next available vpnid, it's checking solely the configuration perspective and not the free naming of the backing
/dev/tun
interfaces.The issue The collision seems to occur with WireGuard - the wireguard-go implementation to be exact. To my knowledge this specific userworld implementation uses those tun interfaces.
I have 2 VPN tunnels in total and both are backed by WG, therefore also two tun interfaces:
So
/dev/tun0
and/dev/tun1
are used by WireGuard. But my first OpenVPN server with VPNID=1 also wants to use/dev/tun1
as per above code, hence the VPN server fails.To Reproduce
Steps to reproduce the behavior:
Expected behavior
The OpenVPN server to be created and able to start.
Describe alternatives you considered
When you create disabled placeholder OVPNs to artificially increase the VPNIDs, you can get the OVPN to work just fine - with the identical configuration:
Screenshots
n/a
Relevant log files
Relevant piece attached above.
Additional context
n/a
Environment
Software version used and hardware type if relevant, e.g.:
OPNsense 22.7.2-amd64