OpenVPN and iroute
Jump to navigation Jump to search

Having problems pinging from one subnet to another using an OpenVPN TUN interface (usually in one direction) between two devices configured as routers to connect two remote subnets? Yup!

Have you checked the Routing Table (using the ROUTE or IP Command) on both the OpenVPN Server and Client? Yes, and looks good!

All the Firewall Settings and Zones are configured correctly? I hope so...

...but the connectivity problems (like PING responses, or lack thereof) still exist? Yes. : (

There's Hope!

Well, here's the thing: All of the above, especially the Routing Table, can look just fine. But if the iroute Directive in the Client's "CCD" File isn't configured correctly (or is absent), then that's the cause.


But what about the Routing Table? It looks fine.


Here's what's going on. But read this first;

...from the OpenVPN "MAN" Page;

--iroute network [netmask]
Generate an internal route to a specific client. The netmask parameter, if omitted, defaults to
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.

This option must be specified either in a client instance config file using --client-config-dir or dynamically generated using a --client-connect script.

The --iroute directive also has an important interaction with --push "route ...". --iroute essentially defines a subnet which is owned by a particular client (we will call this client A). If you would like other clients to be able to reach A's subnet, you can use --push "route ..." together with --client-to-client to effect this. In order for all clients to see A's subnet, OpenVPN must push this route to all clients EXCEPT for A, since the subnet is already owned by A. OpenVPN accomplishes this by not not pushing a route to a client if it matches one of the client's iroutes.

Did you catch that part about the kernel? Well, as it turns out, the route Directive (configured on the OpenVPN Server side configuration file) sets the information seen when the ROUTE or IP command is used. According to the above information, the iroute Directive "...routes to the specific client, Once in OpenVPN" (reworded here slightly to fit into the grammatical context of the sentence). Hmmm, first question might be: "What does 'Once in OpenVPN' mean?" Answer: Not sure. I didn't write it. But as best as one might be able to determine, it might be the "OpenVPN Routing" between the OpenVPN IP Address and the Local Area Network IP Address on the Client (for example the TUN1 and eth0 adapter / interfaces), then onto the Public WAN NIC (if used in a 'router to router' OpenVPN TUN network).

So what command will show this "Internal" / "Once in OpenVPN" Routing Table?

Nothing. There is no command. You'll have to dive deep into the log files for that information.

And in a complete reversal of court room style proof, you'll need to look for the absence of information. In the below example, the IP Address of was used

  • In Client "CCD File": iroute
  • The following information was logged in the Server's Log Files (verbosity set to 3);
    WhatEverClientCertificateName/WhatEverIPAddress:SomePort MULTI: internal route -> WhatEverClientCertificateName/WhatEverIPAddress:SomePort
    WhatEverClientCertificateName/WhatEverIPAddress:SomePort# MULTI: Learn: -> WhatEverClientCertificateName/WhatEverIPAddress:SomePort

So, if you don't see that in your Server Logs, make sure the CCD File contains an iroute Directive.