`SIOCADDRT: Network is unreachable` when routing to a computer in LAN over VPN

But it seems the route command on sys3 not actually sending any packet to sys1 via sys2 to check if reacheble.

It’s not a “liveness” check – the reachability check is based entirely on the local routing table at sys3. The “via” address of a route is really a stand-in for the gateway’s layer-2 (MAC) address, therefore the specified gateway must be local (not already behind another gateway), so if sys3 has no direct route to the requested gateway’s IP address then the gateway is automatically “unreachable”.

Right now the only route matching 10.252.85.135 is an indirect via 10.136.139.254, which implies that the gateway you want is already behind at least one other gateway (possibly more), so sys3 cannot reach it through a MAC address alone.

(Routing packets via gateways is done by sending them to that gateway’s layer-2 (MAC) address as the destination – the IP header remains intact – and there’s only one “destination MAC” field in a packet. There’s no natively supported way to describe a route through two hops; although IP used to support a “Source Route” option, gateways already stopped honoring it probably in the 1990s, as it makes address spoofing much too easy.)

I am unable to ssh to sys1 from sys3 but I’m able to ssh sys3 from sys1 by enabling internet sharing on sys2’s VPN adapter for the Ethernet adapter.

This works in one direction because Windows “Internet Connection Sharing” includes NAT – you’re able to SSH from sys1 to sys3 because the latter thinks it’s receiving a connection from sys2 (i.e. from 10.252.85.135) and can still reply.

How can I ssh to sys1 from sys3?

Set up a tunnel between sys2 and sys3 (preferably from sys2 to sys3, as there might be a firewall blocking new sys3→sys2 connections), or a tunnel from sys1 to sys3 (initiated by sys1 to take advantage of ICS NAT), then SSH through that tunnel.

For example, if you can SSH to sys3, then you can also use SSH’s “reverse forwarding” using ssh -R which will piggyback any kind of inbound TCP connections over the existing outbound (from sys1) SSH connection.

sys1> ssh sys3 -R 5022:localhost:22
  sys3> ssh localhost -p 5022
    sys1> _

sys2> ssh sys3 -R 5022:sys1:22
  sys3> ssh localhost -p 5022
    sys1> _

Alternatively you can set up sys3 as an OpenVPN server, or as a WireGuard endpoint, or as any other IP-over-IP tunnel. As long as the tunnel is kept alive, it can carry connections back.

And if connections from sys3 to sys2 aren’t blocked, you can do the opposite and set up a VPN server on sys2 – or an SOCKS proxy, or an HTTP CONNECT proxy, etc. SSH can also be used here with its -L local forwarding:

sys3> ssh sys2 -L 6022:sys1:22 -fN
sys3> ssh localhost -p 6022
  sys1> _