openvpn icon indicating copy to clipboard operation
openvpn copied to clipboard

OpenVPN does not properly initialize existing tun interface

Open crashkopf opened this issue 5 months ago • 4 comments

Describe the bug On FreeBSD, if OpenVPN is configured to use a specific tun interface, and the interface exists but does not have the TUNSIFMODE ioctl set, then OpenVPN fails to properly set up the interface and dies.

root@host# cat /var/log/daemon.log
... output trimmed ...
openvpn[2580]: Failed to create interface tun0 (SIOCSIFNAME): File exists (errno=17)
openvpn[2580]: dco_set_ifmode: failed to set ifmode=00008002: Invalid argument (errno=22)
openvpn[2580]: DCO device tun0 already exists, won't be destroyed at shutdown
openvpn[2580]: do_ifconfig, ipv4=1, ipv6=0
openvpn[2580]: /sbin/ifconfig tun0 10.8.0.1/24 mtu 1500 up
openvpn[2580]: FreeBSD ifconfig failed: external program exited with error status: 1
openvpn[2580]: Exiting due to fatal error
... output trimmed ...

To Reproduce

root@host# cat /usr/local/etc/openvpn/openvpn.conf
... output trimmed ...
dev tun0
topology subnet
server 10.8.0.0 255.255.255.0
;persist-tun
verb 9
... output trimmed ...

root@host# ifconfig tun0 destroy
root@host# ifconfig tun0 create
root@host# ifconfig tun0
tun0: flags=8010<POINTOPOINT,MULTICAST> metric 0 mtu 1500
	options=80000<LINKSTATE>
	groups: tun
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

root@host# service openvpn onestart

Expected behavior

root@host# cat /var/log/daemon.log
... output trimmed ...
Jul 11 18:07:11 pris openvpn[2769]: DCO device tun0 opened
Jul 11 18:07:11 pris openvpn[2769]: do_ifconfig, ipv4=1, ipv6=0
Jul 11 18:07:11 pris openvpn[2769]: /sbin/ifconfig tun0 10.8.0.1/24 mtu 1500 up
... output trimmed ...

root@host# ifconfig tun0
tun0: flags=1008003<UP,BROADCAST,MULTICAST,LOWER_UP> metric 0 mtu 1500
	options=80000<LINKSTATE>
	inet 10.8.0.1 netmask 0xffffff00 broadcast 10.8.0.255
	groups: openvpn
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Version information (please complete the following information):

root@host# openvpn --version
OpenVPN 2.6.14 amd64-portbld-freebsd14.2 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [MH/RECVDA] [AEAD] [DCO]
library versions: OpenSSL 3.0.16 11 Feb 2025, LZO 2.10
DCO version: FreeBSD 14.2-RELEASE-p1 GENERIC
... output trimmed ...

crashkopf avatar Jul 11 '25 18:07 crashkopf

Mmmmh, this is surprising. OpenVPN does not really care if TUNSIFMODE fails here - but it aborts because the ifconfig call returns an error.

Due to it being exec() ed, we do not see the output from Ifconfig in the log - which is a bit annoying. Can you run OpenVPN from the cli (without --log etc) and copy-paste the lines around the ifconfig call?

(I'm fairly sure I have this case somewhere in my test set on FreeBSD - "preconfigure an interface and use that" - so it's really expected to work)

cron2 avatar Jul 14 '25 07:07 cron2

Ah... I have this as a client-side test, but not server-side (which needs the ioctl() to succeed, to be allowed to configure a non-point-to-point interface)...

cron2 avatar Jul 14 '25 07:07 cron2

Here you go:

root@host # ifconfig tun0 create
root@host # env /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --config /usr/local/etc/openvpn/openvpn.conf --writepid /var/run/openvpn.pid
2025-07-14 17:15:29 Note: --cipher is not set. OpenVPN versions before 2.5 defaulted to BF-CBC as fallback when cipher negotiation failed in this case. If you need this fallback please add '--data-ciphers-fallback BF-CBC' to your configuration and/or add BF-CBC to --data-ciphers.
2025-07-14 17:15:29 OpenVPN 2.6.14 amd64-portbld-freebsd14.2 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [MH/RECVDA] [AEAD] [DCO]
2025-07-14 17:15:29 library versions: OpenSSL 3.0.16 11 Feb 2025, LZO 2.10
2025-07-14 17:15:29 DCO version: FreeBSD 14.2-RELEASE-p1 GENERIC
2025-07-14 17:15:29 Diffie-Hellman initialized with 2048 bit key
2025-07-14 17:15:29 Failed to create interface tun0 (SIOCSIFNAME): File exists (errno=17)
2025-07-14 17:15:29 dco_set_ifmode: failed to set ifmode=00008002: Invalid argument (errno=22)
2025-07-14 17:15:29 DCO device tun0 already exists, won't be destroyed at shutdown
2025-07-14 17:15:29 /sbin/ifconfig tun0 10.8.0.1/24 mtu 1500 up
ifconfig: in_exec_nl(): Empty IFA_LOCAL/IFA_ADDRESS
ifconfig: ioctl (SIOCAIFADDR): Invalid argument
2025-07-14 17:15:29 FreeBSD ifconfig failed: external program exited with error status: 1
2025-07-14 17:15:29 Exiting due to fatal error

crashkopf avatar Jul 14 '25 17:07 crashkopf

2025-07-14 17:15:29 /sbin/ifconfig tun0 10.8.0.1/24 mtu 1500 up
ifconfig: in_exec_nl(): Empty IFA_LOCAL/IFA_ADDRESS

Is because when the tun device is in point to point mode, it expects you to provide the ptp address like /sbin/ifconfig tun5 10.149.242.42 10.149.242.41 mtu 1500 netmask 255.255.255.255 up which is why this fails since the tun device is still in ptp mode.

Since I assume the openvpn server is in topology subnet and the call to TUNSIFMODE failed to remove ptp mode on the tun, this is why the call fails.

Firstyear avatar Dec 06 '25 02:12 Firstyear