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.

Steps to create a remote SSH port forward:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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:9001

    PermitListen restricts the remote listening address and port requested by ssh -R. Do not substitute PermitOpen for this job; PermitOpen limits forwarding destinations.

  7. Test the remote sshd configuration.
    $ sudo sshd -t

    No output means the configuration parsed successfully.

  8. Reload the remote SSH service.
    $ sudo systemctl reload ssh

    Use sudo systemctl reload sshd on distributions where the service is named sshd.

  9. 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.

  10. 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:*
  11. 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

  12. 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.