SSH on a Second Private Path While the VPN Stays Up
An SSH daemon bound to a tunnel address will not answer on a new private interface. Add the binding and verify a new session before closing the old one.
One machine reaches another over a VPN, and someone now wants the same shell over a provider private network. The route exists, the ping succeeds, and SSH still refuses. The usual cause is that the daemon never listened on the new address, so there is nothing to connect to. This is an address-binding problem before it is a firewall problem.
Why a new route does not create a new listener
A listening socket is created by a process that names the addresses it will accept. A route only tells packets where to travel; it does not create a listener at the destination. When sshd is configured with a single ListenAddress, connections to any other local address are refused even though the interface is up. The same holds for a socket unit that owns the port, which is why the first check is always what is actually listening.
Compare the two paths by destination address rather than interface name. A client connects to an address, and that address must be bound before any firewall rule matters.
List the addresses and the listeners
Before editing anything, record the addresses on the host and the sockets that exist now.
ip -br addr
ss -ltnp | grep ':22'The address list shows which private address is real and on which interface, while the socket list shows whether anything is bound to it. A listener on 0.0.0.0:22 already accepts every address, so a new binding adds nothing. A listener on one specific address explains the refusal immediately. If the port belongs to a socket unit rather than the daemon, the daemon configuration is not the whole story.
Add the binding and keep the old one
OpenSSH accepts several ListenAddress entries, so the VPN path can stay while the private one is added. Test the file before reloading it.
sshd -t
systemctl reload sshdA failed configuration test leaves the running daemon untouched, which is precisely what you want while connected over the path you are editing. Keep the existing entry, add the new local address, and confirm the service reloads without dropping the current session. On socket-activated installations, add the address to the socket unit instead and reload that unit. Then read the listener list again, because a binding that never appeared means the wrong component was edited.
Verify the new session before closing the old one
Connect to the new address while the original session is still open, using verbose output to see which address and key were used. Keep the original session open until the probe succeeds twice.
ssh -v [email protected]Read the debug lines for the destination address and the host key that was presented. Confirm the host key fingerprint against a value you already trust, rather than accepting an unknown key because the network is described as private. The new destination needs its own known_hosts entry, and that is expected. Only once the private path works should the old management session be closed.
SSH protects the transport, but it does not make two networks equivalent in isolation. Decide whether the private transit's trust matches the data before relying on it.