Pliant AllianceSoftware development notes & tools

Using SSH tunnels to secure remote connections

Remote administration often requires access to a service that should never be exposed directly to the public internet. A database, internal web panel, file server or development tool may be reachable only from a private network, yet the person maintaining it could be working from a home office in Melbourne, a co-working space in Sydney or a regional town with limited connectivity. SSH tunnelling creates an encrypted path through an approved host, allowing authorised traffic to cross an untrusted network without opening the private service to everyone.

The technique is built into OpenSSH, which is available on Linux, macOS and modern Windows systems, and has long been familiar to Unix administrators. It is useful because it separates network reachability from application configuration: a browser, database client or remote desktop program can continue connecting to a local address while SSH carries the data to its real destination. Used carefully, a tunnel reduces exposure; used casually, it can conceal an unsafe service or provide an unintended route into a network.

How an SSH tunnel carries traffic

An SSH connection normally provides an encrypted login session to a remote machine. Port forwarding adds another function. The SSH client listens on one side of the connection, accepts traffic from an application, encrypts it, sends it through the SSH session, and asks the server side to deliver it to a specified host and port. The application does not need to understand SSH. It simply connects to the local listening address.

The most common form is local forwarding. A command such as ssh -L 8443:internal.example:443 alice@gateway.example.com opens local port 8443. When a browser connects to https://127.0.0.1:8443, the gateway attempts to reach internal.example on port 443. The path between the computer and the gateway is encrypted, while the gateway-to-service segment depends on the destination protocol. HTTPS remains encrypted there; plain HTTP, an unencrypted database protocol or an old administration service does not become secure merely because SSH carried the first part.

SSH also supports remote forwarding with -R, where the listening port is created on the server side, and dynamic forwarding with -D, which creates a SOCKS proxy. Dynamic forwarding can send several applications through the remote network, but it needs stricter control because it behaves like a general-purpose proxy. It should not be treated as a convenient way to bypass workplace filtering or expose internal resources without approval.

Select the forwarding method carefully

Local forwarding is usually the clearest choice for a developer who needs one internal service. A PostgreSQL client might connect to 127.0.0.1:15432, while SSH forwards that port to a database available only from a bastion host. The database can remain bound to its private interface, and the firewall does not need to accept database traffic from the whole internet. Choosing a high local port avoids collisions with software already using the standard service port.

Remote forwarding has a different purpose. It can allow a server to reach a service running behind a home router or corporate firewall, provided the SSH server permits it. For example, a temporary development service might be forwarded from a workstation to a controlled server. This arrangement deserves particular scrutiny because sshd settings such as AllowTcpForwarding, PermitOpen and GatewayPorts determine whether the forwarded port is private to the server or visible to other machines. A remote forward that listens on all interfaces can become an accidental public service.

Dynamic forwarding is valuable when several internal websites or tools must be reached and the client software supports SOCKS. The command ssh -D 1080 alice@gateway.example.com creates a local SOCKS5 endpoint. Applications must be configured to use it, and DNS handling must be considered. If the application resolves internal names locally before sending traffic through the proxy, the lookup may fail or disclose information. Proxy-aware DNS, split-horizon DNS and application logs should be checked rather than assumed.

A jump host can provide a cleaner administrative boundary than forwarding directly to every system. With ProxyJump, the client uses a gateway to reach a second host while preserving ordinary SSH authentication and host-key checking. A configuration entry might use Host database, HostName db.internal, User admin, and ProxyJump bastion. This keeps the internal hostname and route in the SSH configuration instead of scattering special commands through shell history.

Build the connection with strong defaults

The first security decision is how the user authenticates to the gateway. A modern Ed25519 key protected by a passphrase is generally preferable to a reusable password, especially when the same account is used from multiple locations. The private key should remain on the user’s device, with restrictive filesystem permissions, and an agent should hold it only for as long as necessary. Hardware-backed keys can provide stronger protection for administrators who manage valuable systems.

Host-key verification is equally important. The first connection records the server’s public host key in known_hosts. A changed key may indicate a rebuilt server, a legitimate migration or a man-in-the-middle attack. Automatically accepting every new key with options such as StrictHostKeyChecking=no removes a valuable warning and is a poor trade for convenience. Maintain known host keys through a trusted configuration process, particularly when staff connect from public networks in Sydney, Brisbane or Perth.

A practical SSH configuration can make the intended limits explicit:

Host bastion
    HostName gateway.example.com
    User alice
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host internal-db
    HostName db.internal
    User dbadmin
    ProxyJump bastion
    LocalForward 127.0.0.1:15432 db.internal:5432

Binding a local forward to 127.0.0.1 is significant. It prevents other devices on the local network from using the listening port. Binding to 0.0.0.0 may be necessary in a carefully designed shared environment, but it exposes the endpoint to every reachable interface and should be accompanied by firewall rules and an explicit access requirement. The same caution applies to IPv6 addresses, where a listener on :: may be reachable even when an administrator has considered only IPv4.

Keep tunnels visible and dependable

An SSH tunnel is a process, not a permanent security architecture. If the network drops, the process may remain while the forwarding path is unusable, or it may reconnect in a way that hides a changed route. ServerAliveInterval and ServerAliveCountMax help detect a dead session. For long-running connections, a service manager or a controlled tool such as autossh can restart the tunnel, but automatic reconnection should use a dedicated key, a restricted account and narrowly permitted destinations.

A reliable setup begins with a clear inventory. Record the local listening port, the gateway account, the ultimate destination, the allowed protocol and the person responsible for the tunnel. Check active listeners with ss -lntp on Linux or an equivalent network utility on Windows and macOS. Review gateway logs for authentication events and forwarding activity. Unused forwards should be closed rather than left running indefinitely in a terminal multiplexer.

Latency and intermittent links matter in Australia. A developer in Adelaide reaching a service hosted in Sydney may notice a modest delay; a worker in regional Queensland or Western Australia may encounter higher round-trip times, mobile-network changes or evening congestion. An encrypted tunnel does not improve the underlying connection. Keep-alive settings can prevent idle sessions from being discarded by a carrier or firewall, but they cannot fix packet loss, overloaded Wi-Fi or a failing broadband service.

Public wireless networks at airports, hotels and cafés deserve the same suspicion as any other untrusted network. SSH encrypts the session after the client has verified the gateway’s identity, but it does not protect a compromised endpoint. Malware, browser extensions, stolen private keys and an incorrectly configured SOCKS proxy remain risks. A tunnel should complement endpoint patching, multi-factor authentication where available, disk encryption and sensible separation between personal and administrative accounts.

Understand what the tunnel does not protect

Port forwarding protects the traffic that travels through the SSH session. It does not automatically secure the service beyond the SSH endpoint, and it does not repair weak application authentication. If a database accepts a simple password, an internal web console has a known vulnerability or a file share grants excessive permissions, the tunnel merely gives that service a less visible route. Apply normal access controls, patching, TLS configuration and least-privilege rules at the destination.

Name resolution and certificate validation can also produce surprises. A browser connecting to 127.0.0.1:8443 may display a certificate issued for internal.example, producing a warning unless the application supports the intended hostname separately. Some clients send the hostname through the tunnel, while others resolve it locally. Verify whether the destination certificate, DNS search domain and proxy behaviour match the design. Avoid disabling certificate validation to make a forwarded service appear convenient.

Forwarding should be governed like firewall access. Restrict gateway accounts with AllowUsers, disable unused authentication methods, and consider PermitOpen host:port for accounts that require only one destination. On the server, disable agent forwarding unless it is genuinely needed; a compromised host can otherwise misuse credentials available through an agent. Avoid sharing a general administrative account among a team, because individual keys and logs make investigations and revocation far more manageable.

A tunnel can also bypass network segmentation. This matters in Australian organisations handling customer information, health records or financial data. The Privacy Act 1988 and the Australian Privacy Principles may impose obligations around the protection and disclosure of personal information, while the Notifiable Data Breaches scheme affects how serious incidents are handled. SSH encryption can support those controls, but it is not proof of compliance. Logging, retention, access reviews, vendor arrangements and incident response still need to be designed around the data and the organisation’s responsibilities.

Operate tunnels as controlled infrastructure

The safest pattern is usually a deliberately placed bastion host with a hardened operating system, limited inbound access and monitored administrative accounts. The gateway should expose SSH only where required, preferably with network-level restrictions and multi-factor controls around privileged access. It should not double as an unmaintained general-purpose server. In larger environments, a private access service or managed VPN may provide clearer identity and policy controls than a collection of personal port forwards.

Australian teams should also consider where the gateway and logs are hosted. A small business using a cloud server in Singapore, Sydney or another region may face different contractual, privacy and operational considerations. Data sovereignty is not solved by selecting an Australian datacentre, but location can affect latency, support arrangements and the handling of regulated information. The Australian Cyber Security Centre’s Essential Eight provides useful operational context for patching, administrator privileges, multi-factor authentication and backups, even though SSH tunnelling itself is only one part of a broader defensive design.

For a temporary task, create a short-lived key, restrict its destination and remove it when the work ends. For a recurring service, document the tunnel in configuration management, monitor whether it is connected and alert when it stops or changes behaviour. An administrator should be able to answer which account opened the tunnel, which source device was used, where the traffic went and when the permission expires. These details matter during an audit and are invaluable after a suspected compromise.

Used with those controls, SSH forwarding offers a precise way to reach private services without placing them directly on the public internet. Local forwarding is often enough for a single database or web console; a jump host handles multi-stage administration; dynamic and remote forwarding demand extra scrutiny. The security benefit comes from the whole arrangement—verified host keys, strong identities, limited destinations, monitored gateways and sound application security—not from the encrypted tunnel alone.