Opened 10 years ago

Closed 9 years ago

#442 closed Bug / Defect (notabug)

While in UDP mode server responds on different IP than request

Reported by: jabal Owned by:
Priority: major Milestone:
Component: Generic / unclassified Version: OpenVPN 2.2.2 (Community Ed)
Severity: Not set (select this one, unless your'e a OpenVPN developer) Keywords: UDP IP bind
Cc:

Description

Running over UDP the request is to IP 192.168.2.4, but the response comes from 192.168.2.3:

(TCPDUMP)
00:54:55.144074 IP 217.122.41.138.48226 > 192.168.2.4.openvpn: UDP, length 14
00:54:55.145373 IP 192.168.2.3.openvpn > 217.122.41.138.48226: UDP, length 26

This screws up routing. IP 192.168.2.3 is routed over gateway 1, while IP 192.168.2.4 is routed over gateway 2. This means the handshake between client and server does not succeed.

When I change to TCP TCPDUMP shows:
00:58:49.602282 IP 217.122.41.138.37386 > 192.168.2.4.openvpn: Flags [P.], seq 5691:5719, ack 7594, win 463, options [nop,nop,TS val 3457577307 ecr 42786829], length 28
00:58:49.602325 IP 192.168.2.4.openvpn > 217.122.41.138.37386: Flags ., ack 5719, win 411, options [nop,nop,TS val 42786842 ecr 3457577307], length 0

This means the request is to 192.168.2.4 and the response comes from the same address. In this case the VPN launches immediately.

Binding the OpenVPN server to IP 192.168.2.4, using the local directive, works with UDP as well but kills the dual internet line routing policy.

I consider this a bug. Please let me know if you do too.

I am running version:

[jabal@plato network-scripts]$ openvpn --version
OpenVPN 2.2.2 x86_64-unknown-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Apr 5 2012
Originally developed by James Yonan
Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@…>

$ ./configure --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --disable-dependency-tracking --program-prefix= --enable-iproute2 --enable-pkcs11 --enable-password-save --enable-pthread

Compile time defines: ENABLE_CLIENT_SERVER ENABLE_DEBUG ENABLE_EUREPHIA ENABLE_FRAGMENT ENABLE_HTTP_PROXY ENABLE_MANAGEMENT ENABLE_MULTIHOME ENABLE_PASSWORD_SAVE ENABLE_PORT_SHARE ENABLE_SOCKS USE_CRYPTO USE_LIBDL USE_LZO USE_PKCS11 USE_SSL

On CentOS 6.4

Change History (2)

comment:1 Changed 9 years ago by gustavo@…

We are having exactly the same problem. We use dual WAN routers with Linux, SSH and OpenVPN. Each router has 2 public IPs directly on its interfaces and we have all the necessary routing tables and routing rules, plus the necessary iptables ACCEPT rules.

SSH listens on both IPs and replies correctly as the routing rules mandate (ie, the source IP and gateways are respected).

OpenVPN always sends replies through the default gateway regardless of which interface the client is accessing the service through. Therefore, OpenVPN is "escaping" the routing rules and, as a result, connections only work on one interface.

[root@gateway ~]# openvpn --version
OpenVPN 2.1_rc4 i386-redhat-linux-gnu [SSL] [LZO2] [EPOLL] built on Dec 16 2007
Developed by James Yonan
Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
[root@gateway ~]#
Version 0, edited 9 years ago by gustavo@… (next)

comment:2 Changed 9 years ago by Gert Döring

Resolution: notabug
Status: newclosed

Sorry for never replying to this. Yes, this is a one of the common caveats with UDP - with TCP, you get a file descriptor from the kernel, and the kernel handles all the "where did the original packet go to? what do I need to use as a source address for replies?" (because TCP).

For UDP, the application needs to do this, and normal socket API does not even tell the application the destination IP address used in the client connection - so when OpenVPN answers, the kernel will just use one of the addresses in the system (typically the address on the outgoing interface).

Extended socket API to the rescue :-) - call OpenVPN with "--multihome" and it will use a different API to receive UDP packets that will also deliver the destination address, and that will be used to send replies from the proper source.

--multihome is not enabled by default as it has a (small) performance impact, and (worse) the code did not work right no some of the supported platforms. Much work has been invested, and it should now work perfectly fine with 2.3.4 and up, with IPv4 and IPv6, and so on :-)

See also trac #348 and #306 for more discussion about the problems encountered.

So... please use 2.3.4 or up (2.3.6 is current, 2.3.7 will be released in a few weeks), add "--multihome" to your server config, and if the problem *still* shows itself, reopen the ticket.

(PS: for IPv4-only and Linux, --multihome should work in 2.1 and 2.2 as well, but generally speaking, you really want to upgrade to the 2.3 series)

thanks,

Note: See TracTickets for help on using tickets.