Forwarding a remote port over SSH exposes a listening port on a server that actually terminates connections on a client-side or internal service. This pattern provides a controlled path into environments behind firewalls, enables reverse tunnels from systems without public addresses, and centralizes external access through a single OpenSSH endpoint.
Remote port forwarding in OpenSSH uses the -R flag to instruct the remote sshd process to listen on a port and forward traffic over an encrypted channel to a target host and port reachable from the client. Binding addresses control whether the listening socket is only on the remote loopback interface or is reachable from other systems, and server-side options such as GatewayPorts and AllowTcpForwarding govern what clients are allowed to request.
Allowing remote port forwarding can expose sensitive local or internal services if configuration is too permissive or tunnels remain open longer than necessary. Server policies should restrict which users can forward ports and which destinations are reachable, and production environments should monitor tunnels and clean up stale sessions. The commands assume basic shell access to both ends of the connection and a remote sshd configuration that permits remote forwarding.
$ whoami user
$ ss -tlnp | grep 8081
LISTEN 0 5 127.0.0.1:8081 0.0.0.0:* users:(("python3",pid=14599,fd=3))
Local loopback listeners such as 127.0.0.1:8081 are common for development web servers.
$ ssh -f -N -R 9000:localhost:8081 user@host.example.net
The -R option uses the form remote_port:target_host:target_port to tell sshd which port to listen on and where to send the traffic.
$ ss -tlnp | grep 9000
LISTEN 0 128 127.0.0.1:9000 0.0.0.0:* users:(("sshd",pid=15136,fd=8))
LISTEN 0 128 [::1]:9000 [::]:* users:(("sshd",pid=15136,fd=7))
A loopback-only bind ensures that only processes on the remote server can connect to the forwarded port.
$ curl -s http://127.0.0.1:9000/ | head -n 5 <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <title>Directory listing for /</title> ##### snipped #####
$ ssh -f -N -R 0.0.0.0:9000:localhost:8081 user@host.example.net
Binding to 0.0.0.0 combined with a permissive firewall exposes the tunneled service to any host that can reach the remote server.
$ sudo grep -E '^(AllowTcpForwarding|GatewayPorts|PermitOpen)' /etc/ssh/sshd_config AllowTcpForwarding remote GatewayPorts clientspecified PermitOpen localhost:8081
AllowTcpForwarding controls whether clients may request any port forwarding, and GatewayPorts determines whether non-loopback bind addresses from the client are honored.
///etc/ssh/sshd_config AllowTcpForwarding remote GatewayPorts clientspecified PermitOpen localhost:8081
Limiting PermitOpen to specific destinations prevents untrusted users from turning the server into a generic TCP relay.
$ sudo sshd -t
Syntax errors in /etc/ssh/sshd_config can stop sshd from starting and block remote logins until fixed via console or recovery access.
Related: How to test SSH server configuration
$ sudo systemctl reload sshd
$ curl -s http://host.example.net:9000/ | head -n 5 <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <title>Directory listing for /</title> ##### snipped #####
$ pkill -f "ssh -f -N -R 9000:localhost:8081"
Long-lived remote port forwards increase exposure for the tunneled service and should be shut down when tasks complete or no longer require remote access.