I've searched around and the only thing I've found is that "yes, OpenVPN supports connections over TCP", but I haven't found any way to coerce the openvpn server to listen the same port for both protocols at the same time. I've found some very old guides about creating tap interfaces, or recommending to have another instance of the server with the same configuration running at the same time. The former looks too complicated for something simple, and the later seems obsolete.
2 Answers
The same openvpn process can't listen on UDP and TCP sockets at the same time.
You have two good options:
use two tap interfaces for openvpn. Have two openvpn server processes, one for each tap interface; one should listen on UDP, the other on TCP. Bridge these two tap interfaces on the server.
use two tun interfaces. These can't be bridged, so if you want to share the IP space between TCP and UDP clients, you'll need to use a
learn-address
script like the one at http://thomas.gouverneur.name/2014/02/openvpn-listen-on-tcp-and-udp-with-tun/ (however, this specific script is vulnerable to a /tmp symlink attack, so remove the logging to /tmp if you use it).
The third option is to just run two openvpn instances and assign separate client IP space to both (for example, one /25 from the same /24 subnet each). This avoids bridging and the need for a learn-address script.
EDIT: since I needed such a learn-address script myself, I wrote one. I place it in the public domain.
#!/bin/sh
#
# This script allows an openvpn server with several openvpn instances that
# use tun interfaces to share client IP space by adjusting the routing table
# to create entries towards specific clients as needed
action="$1"
addr="$2"
cn="$3" # not used, but it's there; you could e.g. log it
case "$action" in
add)
echo "sudo ip ro add $addr/32 dev $dev" >&2
sudo ip ro change $addr/32 dev $dev || sudo ip ro add $addr/32 dev $dev # if a route already existed, add will fail but change should work, and vice versa
;;
delete)
# even if a client connects to one OpenVPN instance first, then reconnects to the other before the first connection times out, the "add" case above sets up the correct route; it may thus not be necessary to delete routes, ever
# echo "sudo ip ro del $addr/32 dev $dev" >&2
# sudo ip ro del $addr/32 dev $dev
# exit 0 # ignore errors
;;
update)
echo "sudo ip ro change $addr/32 dev $dev" >&2
sudo ip ro change $addr/32 dev $dev \
|| exec sudo ip ro add $addr/32 dev $dev # 'change' can fail with ENOENT, in which case we must 'add'
;;
esac
This script logs to stderr, which should end up in the openvpn log.
If you want your OpenVPN server to listen on a TCP port instead of a UDP port, use
proto tcp
instead ofproto udp
(If you want OpenVPN to listen on both a UDP and TCP port, you must run two separate OpenVPN instances).
Do you mean this page is obsolete?
I think you can run two OpenVPN servers (one for TCP, one for UDP,) bridge each of them with a TUN, and then connect the TUNs.
-
2
tun
interfaces don't have a MAC layer and thus can't be members of a bridge. If you want bridging, you need to usetap
interfaces. Jun 4, 2019 at 6:25