MULTI: bad source address from client - any one-off solutions?

Setup: I have the an openvpn client/server setup (config files at bottom), and I get the infamous MULTI: bad source address from client [192.168.x.x], packet dropped message at server. The server has a public IP address, while the client is behind NAT.

Shortcomings of previously proposed solutions: The client-config-dir defined in the server config is currently empty. Previous posts (here and in openvpn support forums) suggest adding either a file named DEFAULT with the proper rules in client-config-dir, or adding a per-user file with those rules to solve the problem.

However, this doesn't seem to be a long-term solution, because these rules are client-location specific. So, I can add a rule to allow clients from 192.168.x.0 to connect. But if they connect from another network which instead uses 192.168.y.0 for NAT, a new rule will be required.

Questions:

  • Can the required rules be written in a generic/one-off way?
  • Can someone explain why this problem occurs in the first place?

Server config:

port 1234
proto tcp
dev tun

ca ca.crt
cert openvpn.crt
key openvpn.key
dh dh2048.pem

server 10.78.96.0 255.255.255.0
keepalive 10 120
comp-lzo
cipher CAMELLIA-128-CBC

user nobody
group nogroup  
persist-key
persist-tun
client-cert-not-required
plugin /usr/lib/openvpn/openvpn-auth-pam.so login

status openvpn-status.log

push "redirect-gateway def1"
push "remote-gateway 1.2.3.4"
push "dhcp-option DNS 8.8.8.8"

client-config-dir ccd
verb 4

Client config:

ca ca.crt
client
dev tun
proto tcp
remote 1.2.3.4 1234

auth-user-pass
script-security 2
keepalive 5 60
topology subnet
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
cipher CAMELLIA-128-CBC
comp-lzo
verb 4

Solution 1:

You asked: "Can someone explain why this problem occurs in the first place?"

Based on what is reported in the official OpenVPN FAQ I bet it's caused by a routing problem within the OpenVPN engine.

To better clarify the scenario, let me refer to following diagram:

Here you can see:

  • an OpenVPN "server" connected to the HEADQUARTER internal network (10.0.1.0/24)
  • an OpenVPN "client" running at a Remote Site, and connected to the remote 192.168.1.0/24 network

Also

  • we're assuming that the OpenVPN tunnel is established and:
    • OpenVPN "server" is reachable via its own tun interface, with address 10.10.0.1. Also the P2P address, used by the tun interface is 10.10.0.2 (this is important for later discussion, so let's emphasize it)
    • OpenVPN "client" has a tun interface with IP 10.10.0.2

Now, let's assume that:

  • the OpenVPN "Client" has redefined it's default gateway, so to redirect within the tunnel all the outgoing IP traffic;
  • the OpenVPN "Client" has IP_FORWARDING enabled and, as such, can route packets coming from its internal LAN (192.168.1.0/24) (I'm emphasizing this point, as it's critical for our discussion).

With such a scenario in place, let's check in detail what happens when R_PC1 (192.168.1.2) send a packet, like an echo-request, to L_PC1 (10.0.1.2):

  1. after leaving R_PC1 NIC, the packet reach OpenVPN client;
  2. OpenVPN client (that is configured to act as a common router), route it according to it's routing table. As it's default-gateway is the tunnel, it sends the packet to the tunnel;
  3. Packet reach the tun interface of the OpenVPN server. OpenVPN will "see" it and, as it (OpenVPN server) knows that 10.0.1.2 is an address belonging to its LAN subnet, it "forward" the packet, from TUN to LAN;
  4. Packet reach L_PC1.

So everything is fine...

Now let's check what happens with the echo-reply that L_PC1 reply to R_PC1.

  1. echo-reply leaves L_PC1 NIC and reach OpenVPN server LAN interface (10.0.1.1);

Now, if we want OpenVPN Server being able to reach the remote site, we need to define the routing with a "static route". Something like:

route add -net 192.168.1.0 netmask 255.255.255.0 gw 10.10.0.2

Please note the P2P address used as gateway.

Such static routes will operate at OS-level. In other words, it's needed for the operating system to properly route the packet. It means something like: "Please, all the traffic addressed to 192.168.1.0/24 subnet needs to be forwarded to the OpenVPN engine, with whom the OS is able to talk via the P2P address". Thanks to such static route, now...

  1. the packet leaves the OS-routing context and reaches OpenVPN. The OpenVPN instance running on the OpenVPN Server. So, at this point, the OS has nothing more to do and all the routing (within the VPN) is left to the OpenVPN server software.

So, now, the problem is: how, the openvpn server software, will be able to decide the route of a packet, with SRC_IP 10.0.1.2 and DST_IP 192.168.1.2?

Please note that, based on the configuration of OpenVPN server, it knows nothing about the 192.168.1.0/24 network, nor the 192.168.1.2 host. It's not a connected client. It's not a local client. And so? OpenVPN, also, knows that it is not the "OS-Router", so it doesn't really want (and can....) send the packet back to the local gateway. So the only option, here, is to raise an error. Exactly the error you're experiencing

To say it with the language of the FAQ: "...it doesn't know how to route the packet to this machine, so it drops the packet...".

How can we solve the problem?

As you can see from the official documentation, the option iroute serves exactly to our scope:

--iroute network [netmask]
Generate an internal route to a specific client. The netmask 
parameter, if omitted, defaults to 255.255.255.255.
This directive can be used to route a fixed subnet from the server 
to a particular client, regardless of where the client is 
connecting from. Remember that you must also add the route to the 
system routing table as well (such as by using the --route 
directive). The reason why two routes are needed is that the 
--route directive routes the packet from the kernel to OpenVPN. 
Once in OpenVPN, the --iroute directive routes to the specific 
client.

So you need a:

--iroute 192.168.1.0 255.255.255.0

to be applied (to the server) when your OpenVPN client connect, for example via an ad-hoc configuration file defined on the server (client-config-dir, etc.).

Should you wonder why this problem does not happen at step 2) above, my understanding is that OpenVPN Client knows how to route it, 'cause it knows that the VPN-tunnel is a default-gateway.

The same cannot be done at OpenVPN Server, 'cause there the default gateway is tipically not overridden. Also, consider that you could have a single OpenVPN server with plenty of OpenVPN client: each client knows how to reach the server but... how can, the server, decide which is the client acting as a gateway for an unknown subnet?


As for your first question(Can the required rules be written in a generic/one-off way?), I'm sorry but I'm not getting your very problem. Can you rephrase providing more details?


Solution 2:

I had a problem that seems similar, but I'm not sure if it's the same as your problem. I was trying to ping from an openvpn client to a computer in the openvpn server's local network (routed in the server's config), getting no reply and I could see the "bad source address" message in the server's openvpn log.

To solve it, I had to do 2 things:

  1. Enable ip forwarding on the server.
  2. Add a route for the vpn subnet on the server's gateway, because the gateway for the server's local network in my case is not the server itself, but a router. The pinged computer was trying to reply through the gateway, which had no idea what to do for the vpn subnet. So I added a static route in the router using the vpn subnet for the destination, and openvpn server's ip as the gateway for it.

That fixed it for me.