I spent a morning on a tunnel that came up cleanly and moved traffic in exactly one direction: the branch could reach the file server at headquarters, and every connection opened from headquarters into the branch died at the first SYN. The SAs were up, the tunnel counters were climbing, and the handshake was never the problem. The reply was being routed somewhere the tunnel does not cover, and that choice belongs to the far side. A site-to-site VPN only carries packets a host hands to the gateway, and each host makes that choice separately, in each direction, from its own routing table.

Both directions are routed separately

IP keeps no memory of a conversation direction. Every host that sends a packet runs its own longest-prefix lookup, picks one next hop, and forgets the decision. The request and the reply are two unrelated packets that happen to belong to the same connection, and the tunnel is one hop that either of them may or may not use. Nothing in the IKE exchange teaches the remote server how to reach your subnet; the negotiation only agrees which prefixes may be encrypted.

That agreement is the second gate. On strongSwan the traffic selectors are leftsubnet and rightsubnet, and a packet whose source or destination falls outside the negotiated pair is not encrypted, whatever the routing table says. A prefix that is routed into the tunnel but missing from the selectors is a quiet one-way failure: the route looks right, the packet still leaves in the clear or is dropped, and only the charon log complains.

The far host knows nothing about your tunnel

Inside the remote LAN the reply is an ordinary packet addressed to your client. The destination host sees no IPsec header and has no reason to prefer the VPN gateway; it looks up your prefix, finds nothing more specific than its default route, and follows that. If the default points at a core firewall, the firewall either has a route back into the tunnel or it does not. When it does not, you get a silent drop, an ICMP unreachable, or a reply that leaves by the internet-facing interface and dies.

A second interface is enough to break this even when a route does exist. A NAS with a management link on another VLAN, a server with a backup uplink, a policy rule that sends one source range into a second table: any of these can capture the reply. On Linux, ip rule show and ip route show table all expose rules and tables that the default listing hides.

Read the decision on the box that sends the reply

Ask the kernel before you change anything, and give it the source address, because source-dependent rules change the answer.

ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"

The output names the outgoing interface and the next hop. If the interface is not the one facing the VPN gateway, you have found the defect, and the remaining work is choosing where the route belongs. A ping from the gateway proves little here: it answers with an address the far host can place, not your laptop address.

On Windows the equivalents are Find-NetRoute -RemoteIPAddress 10.10.5.10 for the decision and Get-NetRoute for the table. A route added with New-NetRoute that carries a higher metric than the default loses silently, so read the metric column, not the entry. Then confirm with packets: tcpdump -ni any "host 10.10.5.10 and tcp port 445" on the remote LAN interface shows the request, and the same filter on the tunnel side shows whether a reply came back. Request visible with no reply means the answer was routed elsewhere or dropped; a reply on the wrong interface gives you the culprit before you touch a route.

When the server gateway is not the VPN endpoint

Plenty of sites put a firewall between the servers and the concentrator. That firewall forwards the reply, so it needs a route for your client prefix pointing at the VPN gateway, and forwarding policy in both directions. Stateful devices make it worse: the request crossed the firewall from a LAN host it permitted, the reply now arrives from a different direction, and the connection-tracking entry no longer matches, so the packet is discarded as invalid rather than denied. That is why the policy log looks empty while traffic disappears.

The gateway has a second filter of its own. Linux reverse-path filtering drops packets whose source is not reachable through the interface they arrived on, which is exactly the shape of a legitimate asymmetric return path. The strongSwan forwarding guidance asks for net.ipv4.ip_forward and a relaxed net.ipv4.conf.all.rp_filter for that reason. A strict value of 1 on either gateway breaks a correct route quietly, and nstat -az shows the drops if you know to look.

SymptomWhere the reply is most likely lost
Gateway ping works, LAN host silentSource address the far host cannot place in its table
SYN arrives, no SYN-ACK, tunnel counters flatNo route to the client prefix on the far host or its gateway
Reply counted on the internet-facing interfaceDefault route or policy rule on the far host
Firewall reports invalid stateAsymmetric path through a stateful device
Worked until a link failed overNew path is asymmetric, or rp_filter now rejects it

Route or translate, then verify in both directions

The two repairs are not equivalent. Adding a route keeps the client address intact, so source-based rules, audit logs and applications that record the caller keep working; the price is that every hop making the decision needs the route, which is more places to be wrong. Masquerading on the remote gateway collapses the return path to one hop, because the reply is now addressed to the gateway itself, and hides which client did what.

iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE

Choose it deliberately: once clients appear as the gateway address, source-based ACLs stop telling them apart, and conntrack has to hold the mapping so the reply is rewritten back into the tunnel. If the selectors still exclude the client prefix, NAT changes nothing, because the request never entered the tunnel.

Before you call it fixed, confirm four things in order: the route on the host that sends the reply, the route on every hop that forwards it, the selectors covering both prefixes, and a capture showing the reply entering the tunnel with the source you expect. Then repeat the test from the other site. One direction passing is a half-open design, and the second direction usually fails for a different reason than the one you just repaired.

Artitgels cun il medem tema