I had a lab box that accepted a tunnel from a remote site and also dialed out to a vendor network. The outbound profile had worked for weeks. After the inbound server was added, the outbound one connected and then stopped passing traffic within seconds, or refused to start with an address-in-use error. The config files had not changed; the host had simply acquired a second OpenVPN process with its own opinion about ports and routes.

The failure is not random, and it is not an authentication problem. Two daemons on one machine compete for the same local socket and for the same routing table, and whichever starts or reconnects last tends to win. Knowing which of those two collisions you have decides where to look first.

Read the symptom backwards

Start with when the tunnel dies. A bind error at startup points at the listening side: something already owns that port, and OpenVPN refuses to start rather than share it. A tunnel that comes up and then goes quiet points at routing, because a route installed by the other instance can pull the outer connection's packets off their path.

Both cases produce the same user complaint, which is why retry loops and watchdog scripts do not fix anything. They reconnect the client into the same conflict. The useful first question is whether the process is still running when traffic stops.

One socket and one device per instance

A listening server binds its port; an outbound client also needs a local port for its encapsulated traffic. When both live on the same host, the default client behavior can collide with the server's port. The client's local port can be pinned, and binding can be skipped where the peer does not need a fixed source port:

lport 1195
nobind
dev tun1

Those numbers are examples, not a requirement. What matters is that the client stops competing for the server's port and that each instance gets a separate tunnel device. Two daemons sharing tun0 overwrite each other's device state even when their ports differ, so one device per tunnel is not optional.

nobind belongs to the client side. A server must still bind and listen, so do not copy the line into the server config, and do not disable binding on a client whose peer filters on a fixed source port.

Choose one owner for the default route

Only one connection can install a default route. If both profiles redirect all traffic, the second connect silently replaces the first, and the first appears to break. Either keep the outbound tunnel split and push only the vendor prefixes, or give it a separate routing table.

ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2

The addresses and table number above are placeholders. Immediately after adding the rule, confirm that the VPN server's own address still resolves through the normal table; a table that captures the outer transport breaks the tunnel it was meant to protect, and the reconnect loop that follows looks like an unreliable provider.

For a setup that must survive reconnects and reboots, a network namespace is the sturdier boundary. The second client runs inside its own namespace with its own interfaces and routes, and only the services that must cross are exposed. The host keeps one default route, and a namespace reconnect cannot rewrite it.

Verify with the table, not the status line

A client reporting connected only proves its control channel. Capture the routing state before and after each connect, then ask the kernel which device a real destination would use:

ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194

If the selected device for the vendor address changes when the second tunnel starts, you have the route collision. If both processes show up against the same local port, you have the socket collision. Fixing the first without the second just moves the failure to the next reconnect.

Write the ports, devices, tables, and route owner into the host's runbook. The next person to add a third tunnel will otherwise rediscover the same collision, and the only visible evidence will be a connection that works until someone else's daemon restarts.

ບົດຄວາມທີ່ກ່ຽວຂ້ອງ