Candid photograph of a Linux server terminal with a soft olive-green glow against a dark slate background, conveying a calm technical atmosphere.

Step-by-step guides for system administrators — covering command-line basics, web server setup, and preparation material for technical interviews.

Browse Tutorials

SSH tunneling for secure port forwarding

An SSH tunnel carries TCP traffic inside an authenticated, encrypted SSH session. It lets an administrator reach a private database, dashboard or maintenance service without publishing that service directly to the internet.

Local forwarding, remote forwarding and dynamic proxying solve different network paths, but all rely on the same principle: only the SSH endpoint needs to be reachable. A bastion host can therefore front services in a closed network while the administrator works from home or an Australian office.

The examples below suit RHEL, CentOS and Fedora systems, with OpenSSH client options available on macOS and Windows too. They also keep listeners on loopback by default, reducing the chance of accidental exposure.

Map the network path

Start by mapping the path. In a common three-tier layout, a laptop connects to a bastion, and the bastion reaches an application server or database that accepts traffic only from its private subnet. Decide which side owns the listener before choosing local, remote or dynamic forwarding.

Australian networks add useful constraints. Many NBN fixed-line and FTTN connections sit behind carrier-grade NAT, so inbound SSH may fail while an outbound tunnel works; 4G and 5G links can also change IP addresses during a session. In the Australian cloud market, Sydney and Melbourne regions are widely used for such bastions, but the target database should remain private. Linuxtpoint’s broader Linux administration tutorials can support the surrounding setup.

Configure local forwarding

For a local forward, the administrator connects to the bastion and asks it to open a local port that leads to the private target. This example exposes a PostgreSQL service on the administrator’s machine at port 8080:

ssh -N -L 127.0.0.1:8080:10.20.4.15:5432 admin@bastion.example.au

After authentication, requests to 127.0.0.1:8080 travel through the encrypted SSH link to 10.20.4.15:5432. The client listener is loopback-only, so other devices cannot connect to it. ExitOnForwardFailure=yes prevents a misleading command prompt when the requested port is already occupied.

Put recurring settings in ~/.ssh/config rather than relying on a long command:

Host bastion-au
    HostName bastion.example.au
    User admin
    IdentityFile ~/.ssh/id_ed25519_au
    IdentitiesOnly yes
    ExitOnForwardFailure yes
    ServerAliveInterval 30
    ServerAliveCountMax 3

Use IdentitiesOnly yes so the server receives only the intended key, and keep the key file readable only by its owner. Confirm the bastion’s host-key fingerprint through a trusted channel before accepting it; avoid StrictHostKeyChecking=no.

Use remote and dynamic forwarding

Remote forwarding runs the listener on the SSH server. It is useful when a service must call another host that only permits connections from the bastion’s network, although it should not become a hidden substitute for a proper application network.

ssh -N -R 127.0.0.1:9000:target.internal:80 admin@bastion.example.au

With GatewayPorts no, the usual SSH server setting, the remote listener remains on the server’s loopback interface. Only local processes on that server can use it; changing this behaviour requires a deliberate security decision.

Dynamic forwarding creates a SOCKS5 proxy for clients that accept proxy settings:

ssh -N -D 127.0.0.1:1080 admin@bastion.example.au

Applications such as a browser can then select the proxy, while unrelated traffic stays outside the tunnel. Dynamic forwarding is flexible but less transparent, so restrict it to administrative use and avoid sending bulk or unrelated traffic through the bastion.

For multi-hop access, a ProxyJump alias can route through the bastion and a second management host without agent forwarding. Agent forwarding lets a compromised remote host use the administrator’s authentication agent, so dedicated keys and explicit jump hosts provide cleaner separation.

Harden keys and server policy

Generate a dedicated Ed25519 key with a passphrase, rather than accepting the server’s default key on every workstation:

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_au

The -a 100 option increases key-derivation work, making passphrase guessing more expensive. Keep the private key under ~/.ssh; copy only the .pub file to authorized_keys on the bastion. Set directory permissions to 0700 and private-key permissions to 0600. Separate keys make revocation and audit trails clearer.

On the SSH server, use PermitOpen to limit local-forward destinations and PermitListen, where supported, to constrain remote listeners. Accounts that need no forwarding can receive DisableForwarding yes through a Match block. Keep a second administrative session open while changing daemon settings, then validate sshd -t before reloading.

Security depends on configuration, not chance. The reel-game probability example illustrates the distinction: calculated odds describe an outcome, while SSH relies on verified keys, encryption and access policy. A passphrase still protects the private key if the workstation is stolen.

Maintain a hardened tunnel service

Operational hardening includes patching the bastion and monitoring unusual sessions. For the host patching side, Linuxtpoint’s guide to automatic yum security updates provides a practical companion.

Use a systemd unit or managed automation if the tunnel must survive logout, but preserve ExitOnForwardFailure and keepalives. Rotate credentials, test recovery access and document every local, remote or SOCKS proxy.

Diagnose and remember the path

When a forward fails, run ssh -vvv temporarily, inspect the client with ss -lntp, and test the target route from the bastion. On RHEL-family hosts, check SELinux audit messages and firewalld rules as well as cloud security groups. A remote forward can fail because GatewayPorts or PermitListen prevents the requested bind.

Log timestamps in UTC even when teams in Brisbane, Perth, Adelaide, Sydney and Melbourne operate across Australian Eastern, Central and Western time zones. Daylight-saving changes and mobile connections can otherwise make event sequences look inconsistent. Centralised logs and accurate NTP settings support useful incident timelines.

The lasting rule is simple: bind locally, authenticate with strong keys, restrict destinations, and monitor the encrypted path.