When a service runs on a laptop, build host, or private network that outsiders cannot reach directly, an SSH remote port forward can publish one remote-server port that sends traffic back through the SSH session. The remote server receives connections on the chosen port, while the actual application stays on the client side or an internal address reachable from that client.
OpenSSH creates this reverse tunnel with the -R option. The remote sshd listener accepts connections and sends each one over the encrypted channel to the target host and port named after the last colon pair. A loopback bind keeps the remote listener private to the server; a non-loopback bind publishes it on a remote interface if server policy allows it.
Remote forwards cross the firewall direction that usually blocks direct inbound access. Keep the tunnel user and listen port narrow, use ExitOnForwardFailure so setup failures are visible, and only enable non-loopback binds after checking AllowTcpForwarding, GatewayPorts, and PermitListen on the remote server.
Related: How to forward a local port with SSH
Related: How to allow remote hosts to use an SSH tunnel
Related: How to disable SSH TCP forwarding
Steps to create a remote SSH port forward:
- Confirm that the client-side service responds before creating the tunnel.
$ curl -sS http://127.0.0.1:8081/health internal app ok
Replace 127.0.0.1:8081 with the host and port reachable from the machine that starts the SSH connection.
- Start a loopback-only remote port forward from the client machine.
$ ssh -N -o ExitOnForwardFailure=yes -R 127.0.0.1:9000:127.0.0.1:8081 user@host.example.net
The command keeps the SSH session open. Use another terminal for the remote checks, and return to this terminal to close the tunnel with Ctrl-C.
- Check the remote listener from a separate shell on the remote server.
$ ss --tcp --listen --numeric 'sport = :9000' State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:9000 0.0.0.0:*
A Local Address of 127.0.0.1:9000 means only processes on the remote server can connect to the forwarded port.
- Request the forwarded port from the remote server.
$ curl -sS http://127.0.0.1:9000/health internal app ok
The response should match the client-side service, proving the remote server is reaching it through the SSH tunnel.
- Open a remote sshd policy file only when other hosts must reach the forwarded port.
$ sudoedit /etc/ssh/sshd_config.d/70-remote-forward.conf
Edit /etc/ssh/sshd_config instead when the server does not load drop-ins from /etc/ssh/sshd_config.d/*.conf.
- Add a restricted remote-forwarding policy for the tunnel account.
/etc/ssh/sshd_config.d/70-remote-forward.conf Match User tunneluser AllowTcpForwarding remote GatewayPorts clientspecified PermitListen 127.0.0.1:9000 0.0.0.0:9001PermitListen restricts the remote listening address and port requested by ssh -R. Do not substitute PermitOpen for this job; PermitOpen limits forwarding destinations.
- Test the remote sshd configuration.
$ sudo sshd -t
No output means the configuration parsed successfully.
Related: How to test SSH server configuration
- Reload the remote SSH service.
$ sudo systemctl reload ssh
Use sudo systemctl reload sshd on distributions where the service is named sshd.
- Start the remote forward with a non-loopback bind when network clients should reach it.
$ ssh -N -o ExitOnForwardFailure=yes -R 0.0.0.0:9001:127.0.0.1:8081 user@host.example.net
Binding the remote listener to 0.0.0.0 exposes the tunneled service to every source allowed by the remote host firewall, security group, or network ACL.
- Check that the remote listener is bound to the expected address.
$ ss --tcp --listen --numeric 'sport = :9001' State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:9001 0.0.0.0:*
- Test the exposed remote port from another host.
$ curl -sS http://host.example.net:9001/health internal app ok
If the listener is correct but the request fails, check the remote host firewall or cloud security group for port 9001.
Tool: Port Exposure Summary Checker - Press Ctrl-C in the terminal running the SSH command.
Leaving a remote forward running keeps the remote listener open for as long as the SSH session remains connected.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.