The belief is common enough to be treated as fact: Android allows only one VPN, so an SSH server running on the phone cannot work over that tunnel. The first half is true and the conclusion does not follow. The platform limit is about how many apps may hold the VPN service slot, not about how many sockets may exist or who is allowed to connect to the phone. An SSH daemon with a listening socket is an ordinary app with an ordinary port, and the tunnel is one of the paths its traffic can take.

What the one-VPN rule actually constrains

VpnService is a single-slot resource. When an app establishes a tunnel it becomes the device's VPN, and a second app that tries to establish one is refused until the first goes away. That is a rule about tunnel ownership, and it explains why two VPN clients cannot run at once.

It says nothing about listening sockets. The SSH server does not call VpnService, does not intercept packets, and does not compete for that slot. It binds a port and accepts connections, which is the same thing it would do with no VPN installed at all. So the myth confuses a limit on tunnel providers with a limit on network connections, and the two have no relationship.

The listener is a destination, not part of the tunnel

Once the tunnel exists, the phone has an address on it, and the peer device has a route to that address. Whether anything answers is decided by the listener. A daemon bound to loopback is reachable only from the phone itself; a daemon bound to the old tunnel address may keep its binding after a reconnect while the address it bound to has changed.

Binding rules are ordinary SSH configuration: the listen address and port, and who may authenticate. On Android those settings live in the app's own configuration, and the app's process owner may not be allowed to use privileged ports, so a desktop habit of binding port 22 as root does not transfer unchanged.

ListenAddress 10.90.0.4
Port 2222
AllowUsers alice

Then there is permission on the path itself. A consumer VPN that happily carries outbound web traffic need not allow inbound connections to its clients at all; many do not, because it would expose one customer to another. If the peer cannot reach the phone's tunnel address from anywhere, the problem sits in the service's policy rather than in the phone.

The reply path is where it usually breaks

Assume the peer reaches the phone's tunnel address and the SYN arrives. The reply now has to leave by the same path, and that is a routing decision inside the phone. If the reply goes out over Wi-Fi because that is the default network, the peer sees a connection that never completes, which looks exactly like a firewall.

Android makes this more complicated than a desktop because the default network is chosen per process and can be changed by the VPN app's policy. A VPN client can route only a list of allowed applications, so a server app that is outside that list keeps using the physical network for its replies while the peer expects them through the tunnel.

An app can also bind its own sockets to a specific network, which overrides the default. When you read a report that a service is reachable from one address and not another, this is usually the mechanism behind it.

Bypassing the VPN does not repair an inbound service

The popular workaround, excluding the SSH app from the VPN so its traffic stops being redirected, is a fix for the opposite problem. It helps when an outbound SSH client's transport keeps breaking because of the tunnel. For a hosted server it can move the replies off the tunnel that the peer is using, which turns a partial failure into a total one.

The same applies to opening a public port on the router. If the requirement is that one authorized device reaches the phone over the VPN, exposing SSH to the internet is a different threat model and not a repair.

Decide the service address first: the phone's LAN address, its tunnel address, or a deliberately forwarded endpoint. Each one has its own reachability and exposure contract, and blending them is how a small access problem becomes a permanent hole.

Diagnose one direction at a time

Write down four facts before changing configuration: the address the peer is connecting to, the listener state on the phone, the app and user context that owns it, and the path observed in each direction. A report that says the VPN disconnects SSH contains none of them and cannot distinguish a client transport problem from an unreachable server.

adb shell ip -br addr
adb shell ip route get 10.90.0.9
nc -vz 10.90.0.4 2222

Run the port check from the peer, not from the phone, and read the SSH client's verbose output to see whether it fails before or after the TCP handshake. A socket that never connects and a login that is rejected are different stages with different owners.

Keep host-key verification and account restrictions intact while you debug. Restricting the listener and the permitted users is what makes a reachable server acceptable; loosening them to get a connection working trades one problem for a worse one. The OpenSSH server reference covers the listen and access controls if your Android implementation follows the same configuration names.

Erthyglow kevrennek