After a recent update to the OpenVPN on one of our Ubuntu-based machines, we noticed that the VPN connection stopped working. In the OpenVPN logs on the server, I found the following message repeated several times for each connection attempt:
TLS Error: TLS key negotiation failed to occur within 60 seconds
On the client, the same connection was finished with the “Connection timeout” message. Apparently, the client was sending data to the server, but the server was not able to respond. The first find I tried, was to check what packets are received and sent on the OpenVPN port:
$sudo tcpdump udp port 1194 -n listening on eth0 12:23:55.046450 IP 220.127.116.11.53540 > 10.0.10.250.1194: UDP, length 14 12:23:55.047532 IP 10.0.10.58.1194 > 18.104.22.168.53540: UDP, length 26 12:33:55.142680 IP 22.214.171.124.53540 > 10.0.10.250.1194: UDP, length 303 12:33:55.154378 IP 10.0.10.58.1194 > 126.96.36.199.53540: UDP, length 22
Have you noticed the strange thing? The packets are sent by the client to the server on the IP of 10.0.10.250 but the server responds from the IP of 10.0.10.58! The OpenVPN server responds on different IP than the request came from. Apparently, this issue is not occurring on the TCP connection, but unfortunately, we are using UDP.
What does it mean? The server is responding from a different IP and the router in the middle of the connection is not aware that this packet should be sent back to the client. The connection is not established!
The OpenVPN server, when operating on UDP, is not taking care of how to send packets back. It relies on the kernel to route them properly. In this case, it failed miserably.
How to fix this issue?
In our case it was simple: we had to add one line to the “server.conf” file:
Why? This is the switch that should be used when a server has more than one IP address – multiple interfaces, secondary IP addresses, and so on. It turns on the extended socket API and allows the kernel to route the packet back properly. In the OpenVPN manual it stands:
This option will add some extra lookups to the packet path to ensure that the UDP reply packets are always sent from the address that the client is talking to. This is not supported on all platforms, and it adds more processing, so it’s not enabled by default.Note: this option is only relevant for UDP servers.https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/