Static Local Port Forwarding
Static local port forwarding maps one local listening port to one fixed destination host and port. It is the usual choice for a database, internal web server, mail server, or any other single TCP service.
Example: the database client connects to 127.0.0.1:3307, while the SSH server connects to db.internal:3306.
Chilkat object or managed thread
Separate process or application code
SSH server or remote network component
Destination service
Local-computer boundary
Where each part runs
| Part | Location | Process or thread |
|---|---|---|
| Database client | Local computer | Separate process, such as a database administration tool, ODBC consumer, or application |
| Application code | Local computer | Your application thread configures and controls SshTunnel |
| Listener and relay | Local computer, same application process | Chilkat listener, tunnel-pool, and client background threads |
| SSH server | Remote gateway or server | Separate SSH server process |
| Destination database | Reachable from the SSH server | Separate database server process; it may be on the SSH server or another host |
Property and port meanings
| Setting | Meaning |
|---|---|
BeginAccepting(3307) | Create the local listening socket on port 3307. The database client connects here. |
ListenBindIpAddress = "127.0.0.1" | Restrict the listener to clients on the same computer. |
DestHostname = "db.internal" | The destination host the SSH server will attempt to reach. |
DestPort = 3306 | The destination service port opened by the SSH server. |
DynamicPortForwarding = false | Use fixed-destination forwarding. This is the default mode. |
Important name-resolution detail:
DestHostname identifies a host from the SSH server's network perspective. A private name such as db.internal may be resolvable from the SSH server even when it is not resolvable from the local computer.Language-neutral API sequence
tunnel.ListenBindIpAddress = "127.0.0.1"
tunnel.DynamicPortForwarding = false
tunnel.DestHostname = "db.internal"
tunnel.DestPort = 3306
success = tunnel.Connect("ssh.example.com", 22)
// Compare tunnel.HostKeyFingerprint with the expected fingerprint.
success = tunnel.AuthenticatePw("ssh-user", "ssh-password")
success = tunnel.BeginAccepting(3307)
// Check tunnel.IsAccepting after the listener thread has started.
Credentials belong to different layers
The SSH username and password authenticate the tunnel application to the SSH server. The database username and password authenticate the database client to the database server. The tunnel transports the database protocol but does not replace database authentication.
Common mistakes
- Configuring the database client to connect directly to
db.internal:3306instead of the local endpoint127.0.0.1:3307. - Using a local port already occupied by another process.
BeginAcceptingstarts asynchronously, so inspectIsAcceptingto confirm the listener remained active. - Binding to all interfaces when only local access is intended.
- Assuming SSH also encrypts the SSH-server-to-database segment.