The Great OpenVPN Migration Mystery

The Great OpenVPN Migration Mystery

Let me tell you a tale of network migration, troubleshooting, and the surprising revelation that sometimes the simplest solutions hide behind misleading names.

The Setup

Picture this: I was migrating from a battle-tested NetBSD router running PF and OpenVPN to a shiny new OPNsense installation. The network layout was fairly straightforward:

OPNsense Router: 10.1.78.1
OpenVPN Server: 10.66.77.1
Site A Network: 10.1.78.0/24 (Main site with OPNsense)
Site B Network: 10.2.78.0/24 (Remote location)
Site C Network: 10.3.78.0/24 (Another remote location)
VPN Network: 10.66.77.0/24 (For remote clients)

The Mystery

Everything seemed perfect at first. The certificate migration went smoothly, OpenVPN configuration was recreated, and the client-specific configurations (ccd) were in place. Servers could talk to each other, routes were being pushed, and life was good... or so I thought.

Then came the mobile clients. Connecting from my phone, I'd get assigned an IP like 10.66.77.5, and I could happily access anything in Site A's network. Want to reach 10.1.78.5? No problem! But trying to access anything in Sites B or C? Complete silence. Not even a rejection - just packets disappearing into the void.

The Investigation

I went full detective mode:

# Nothing in the firewall logs
tcpdump -i ovpns1 net 10.2.78.0/24
# *cricket sounds*

# Routes on remote sites looked perfect
$ route show
Destination        Gateway            Flags
10.1.78.0/24      10.66.77.1         UGS    # Works
10.2.78.0/24      10.66.77.1         UGS    # Should work, but doesn't
10.3.78.0/24      10.66.77.1         UGS    # Also doesn't work

I tried everything:

  • Added NAT rules for LAN and OpenVPN networks
  • Double-checked firewall rules (OpenVPN was set to allow any:any)
  • Verified routing tables on all sites
  • Probably made five cups of coffee

The Revelation

During my second migration attempt (because who gets it right the first time?), I decided to dive into the XML backup file. There, hidden in plain sight, was the answer: the push_route directive only contained Site A's network!

But here's the kicker - in OPNsense's GUI, this setting was hiding under "Local Networks" in the OpenVPN configuration. Yes, the same option I had ignored because I thought "local networks" meant "networks directly connected to this router."

The fix? Simply adding these networks to OpenVPN instance configuration:

<push_route>10.1.78.0/24,10.2.78.0/24,10.3.78.0/24</push_route>

Or through the GUI:

  1. Navigate to VPN → OpenVPN → Instances
  2. Edit your server instance
  3. Find the "Local Networks" field
  4. Add all the networks you want clients to reach
  5. Watch as OPNsense generates the proper push_route directives

The Happy Ending

Suddenly, everything worked! VPN clients could reach all networks, packets were flowing freely, and I could sleep peacefully again.

The moral of this story?

  1. Don't trust naming conventions
  2. Sometimes the simplest solution is hidden behind a misleading name
  3. When migrating, always check your push_route directives
  4. Reading XML backups can actually be useful (who knew?)

And remember, in the world of networking, "Local" doesn't always mean what you think it means. Sometimes it just means "networks you want to push to clients" - but I guess "Networks to Push to Clients" was too long for a GUI label!

Now, if you'll excuse me, I need to update my documentation to prevent future me from spending two days troubleshooting what turned out to be a simple checkbox in the GUI.

P.S. My coffee consumption during this troubleshooting session was directly proportional to the time spent looking at firewall rules instead of OpenVPN configuration.

Read more