Chilkat.SshTunnel Class Overview
Chilkat.SshTunnel creates SSH tunnels for forwarding local client connections through an SSH server to a destination service, such as a database server or other TCP service. It supports fixed destination forwarding, dynamic SOCKS-style port forwarding, password and public-key authentication, keyboard- interactive authentication, proxy connections to the SSH server, multi-hop SSH connections, background accept threads, tunnel/client logging, secure secret lookup, and connection diagnostics.
What the Class Is Used For
Use Chilkat.SshTunnel when an application needs to expose a local listening port and forward accepted client connections through an SSH server. The SSH server then forwards traffic to a destination host and port, or in dynamic port-forwarding mode, acts like a SOCKS proxy where each inbound client supplies the destination dynamically.
Typical Workflow: Fixed Destination Tunnel
- Create an SshTunnel object.
- Set DestHostname and DestPort to the service reached from the SSH server.
- Optionally configure outbound proxy settings, bind settings, timeouts, logging, algorithms, or socket performance properties.
- Call Connect to connect to the SSH server.
- Authenticate using AuthenticatePw, AuthenticatePk, AuthenticatePwPk, or the secure-string variants.
- Call BeginAccepting with a local listen port.
- Local clients connect to the local listen port. Chilkat forwards each connection through the SSH tunnel to the configured destination.
- When finished, call CloseTunnel.
Typical Workflow: Dynamic SOCKS Port Forwarding
- Set DynamicPortForwarding = true.
- Set InboundSocksVersion to 4 or 5.
- Optionally set InboundSocksUsername and InboundSocksPassword to require inbound SOCKS authentication.
- Connect and authenticate to the SSH server.
- Call BeginAccepting to start the local SOCKS listener.
Core Concepts
| Concept | Meaning | Important Members |
|---|---|---|
| SSH Server Connection | The encrypted SSH connection used to carry tunneled traffic. | Connect, ConnectThroughSsh, IsSshConnected |
| Destination Service | The host and port that the SSH server forwards traffic to in fixed forwarding mode. | DestHostname, DestPort |
| Local Listener | A local socket accepting inbound client connections for forwarding. | BeginAccepting, StopAccepting, ListenPort, IsAccepting |
| Tunnel Pool | Background management of accepted client connections and their associated SSH tunnel activity. | BeginAccepting, DisconnectAllClients, CloseTunnel |
| Dynamic SOCKS Forwarding | The tunnel behaves as a SOCKS proxy and lets inbound clients choose destinations dynamically. | DynamicPortForwarding, InboundSocksVersion, InboundSocksUsername, InboundSocksPassword |
| Outbound Proxy | An HTTP or SOCKS proxy used by Chilkat when connecting outward to the SSH server. | HttpProxy*, Socks* |
Connection Setup Properties
| Property | Purpose | Guidance |
|---|---|---|
| DestHostname | Destination hostname or IP address for forwarded traffic. | Used in fixed destination forwarding. Ignored when DynamicPortForwarding is true. |
| DestPort | Destination service port. | For example, a database server port reachable from the SSH server. |
| ConnectTimeoutMs | Maximum milliseconds to wait when connecting to the SSH server. | Default is 10000. A value of 0 means wait forever. |
| IdleTimeoutMs | Timeout when tunnel send/receive progress halts. | Default is 10000. A value of 0 means no timeout. |
| ClientIdentifier | SSH client identifier string sent when connecting. | Should begin with SSH-2.0-. Servers may disconnect if it does not. |
| PreferIpv6 | Prefer IPv6 over IPv4 when both are supported for a domain. | Default is false, preferring IPv4. |
Starting and Managing the Local Listener
| Member | Purpose | Important Details |
|---|---|---|
| BeginAccepting | Starts a background thread that listens for inbound client connections. | The listen port must not already be used by another process. Each accepted connection creates and manages a new SSH tunnel. |
| IsAccepting | Indicates whether the background listen thread is running. | After BeginAccepting, wait briefly and check this property to confirm that binding and listening succeeded. |
| ListenPort | Reports the actual local listen port. | If 0 was passed to BeginAccepting, this property contains the allocated port number. |
| ListenBindIpAddress | Binds the local listener to a specific IP address. | Usually leave unset. Useful mainly on computers with multiple network interfaces or IP addresses. |
| StopAccepting | Stops the listen background thread. | Existing clients may remain connected. Listening can be resumed by calling BeginAccepting again. |
Authentication Methods
| Method | Authentication Type | Use When |
|---|---|---|
| AuthenticatePw | Password authentication. | The SSH server requires a username and password. |
| AuthenticatePk | Public-key authentication. | The matching public key is installed on the SSH server and the application supplies the corresponding SshKey private key. |
| AuthenticatePwPk | Password plus private key. | The SSH server requires both a password and a private key. |
| AuthenticateSecPw | Password authentication using secure strings. | Same as AuthenticatePw, but login and password are passed as SecureString. |
| AuthenticateSecPwPk | Password plus private key using secure strings. | Same as AuthenticatePwPk, but username and password are passed as SecureString. |
Keyboard-Interactive Authentication
| Method | Purpose | Result |
|---|---|---|
| StartKeyboardAuth | Begins keyboard-interactive authentication for the given login. | Returns XML containing prompts, or a <success> or <error> response. |
| ContinueKeyboardAuth | Sends the response to a keyboard-interactive prompt. | Returns success, error, or another XML prompt request if additional steps are required. |
Dynamic Port Forwarding and Inbound SOCKS
| Property | Purpose | Guidance |
|---|---|---|
| DynamicPortForwarding | Makes the local listener behave as a SOCKS proxy for inbound connections. | Default is false. When true, DestHostname and DestPort are unused. |
| InboundSocksVersion | Selects inbound SOCKS4 or SOCKS5 for dynamic forwarding. | Must be set to 4 or 5 when dynamic forwarding is used. |
| InboundSocksUsername | Username required for inbound SOCKS client authentication. | If no username is set, inbound connections require no authentication. |
| InboundSocksPassword | Password required for inbound SOCKS client authentication. | Used with dynamic port forwarding when inbound authentication is desired. |
Outbound HTTP Proxy to the SSH Server
| Property | Purpose | Important Details |
|---|---|---|
| HttpProxyHostname | HTTP proxy hostname or IPv4 address. | Used only for the outbound connection to the SSH server. |
| HttpProxyPort | HTTP proxy port. | Common proxy ports include 8080 and 3128. |
| HttpProxyAuthMethod | HTTP proxy authentication method. | Valid choices are Basic and NTLM. |
| HttpProxyUsername | HTTP proxy login name. | Set when the HTTP proxy requires authentication. |
| HttpProxyPassword | HTTP proxy password. | Can be resolved from secure storage when EnableSecrets is enabled. |
| HttpProxyDomain | Optional NTLM domain. | Used only when NTLM authentication is used with the HTTP proxy. |
Outbound SOCKS Proxy to the SSH Server
| Property | Purpose | Default / Guidance |
|---|---|---|
| SocksVersion | Selects whether an outbound SOCKS proxy is used. | 0 = none, 4 = SOCKS4, 5 = SOCKS5. Default is 0. |
| SocksHostname | SOCKS proxy hostname or IPv4 address. | Used only when SocksVersion is 4 or 5. |
| SocksPort | SOCKS proxy port. | Default is 1080. |
| SocksUsername | SOCKS proxy username. | Used only when an outbound SOCKS proxy is configured. |
| SocksPassword | SOCKS5 password. | SOCKS4 does not use a password. Can be resolved from secure storage when EnableSecrets is enabled. |
Lifecycle and Connection Management
| Method | What It Does | When to Use |
|---|---|---|
| Connect | Connects to the SSH server used for tunneling. | Call before authentication. |
| ConnectThroughSsh | Connects to a second SSH server through an existing connected and authenticated Ssh connection. | Use for multi-hop SSH: application → ServerSSH1 → ServerSSH2. |
| BeginAccepting | Starts listening for inbound client connections. | Call after connecting and authenticating to the SSH server. |
| StopAccepting | Stops the listen thread. | Use when no new clients should be accepted, while the tunnel can remain active. |
| DisconnectAllClients | Disconnects all clients while keeping the SSH tunnel open. | Use to drop current tunneled clients without closing the SSH connection. |
| CloseTunnel | Closes the SSH tunnel and disconnects all existing clients. | Call when finished with the tunnel, especially before exiting the program. |
Status and Diagnostics Properties
| Member | Purpose | Guidance |
|---|---|---|
| IsSshConnected | Returns whether the SSH connection is still connected. | Use when detecting whether the underlying SSH connection was lost. |
| GetCurrentState | Returns current state of existing tunnels as XML. | Useful for diagnostics, monitoring, and support logging. |
| HostKeyFingerprint | SSH server host key fingerprint after connection. | Format includes algorithm, key size, and colon-separated fingerprint. |
| LastErrorText | Diagnostic text for the last method or property access. | Check after failures or unexpected behavior. When reporting problems, include the full contents. |
| AbortCurrent | Requests that the currently running method abort. | Applies to long-running network operations and works for synchronous or asynchronous calls. |
| LoadTaskCaller | Loads the caller of an async method’s task. | Used with asynchronous task workflows. |
Logging Properties
| Property | Logs | Storage |
|---|---|---|
| KeepAcceptLog | Enables an in-memory log of the listen thread. | When true, read AcceptLog. |
| AcceptLog | In-memory listen-thread log. | Contains content only when KeepAcceptLog is true. |
| AcceptLogPath | Listen-thread activity. | Writes the accept/listen activity to a file. |
| KeepTunnelLog | Enables an in-memory log of SSH tunnel thread activity. | When true, read TunnelLog. |
| TunnelLog | In-memory tunnel-thread log. | Contains content only when KeepTunnelLog is true. |
| TunnelLogPath | SSH tunnel thread activity. | Writes tunnel activity to a file. |
| ClientLogDir | Per-client tunnel logs. | If set, creates log files named tunnel_client_log_{random_id}.txt. |
Socket Binding and Performance Properties
| Property | Purpose | Guidance |
|---|---|---|
| OutboundBindIpAddress | Binds the outbound socket connecting to the SSH server to a specific IP. | Usually leave unset. Useful mainly for multi-homed systems. |
| OutboundBindPort | Binds the outbound connection to a specific local port. | Leave at default 0 unless a specific local port is required. |
| SoRcvBuf | Receive buffer size socket option. | Default is 4194304. Can be increased if download performance seems slow; use a multiple of 4096. |
| SoSndBuf | Send buffer size socket option. | Default is 262144. Can be increased if upload performance seems slow; use a multiple of 4096. |
| TcpNoDelay | Controls the TCP_NODELAY socket option. | Default is false. Set true to disable Nagle’s algorithm for better performance when small amounts of data are sent. |
Secure Secret Resolution
| Property | Purpose | Applies To |
|---|---|---|
| EnableSecrets | Enables automatic resolution of credentials from operating-system secure storage. | HttpProxyPassword, SocksPassword, AuthenticatePw, and AuthenticatePwPk. |
Algorithm and Compatibility Controls
| Member | Purpose | Guidance |
|---|---|---|
| SetAllowedAlgorithms | Specifies the exact set of algorithms allowed for the SSH connection. | Use when an application must tightly control SSH algorithm negotiation. |
| UncommonOptions | Comma-separated keywords for uncommon SSH, security, compatibility, or platform needs. | Normally leave empty. Set only when a documented option is needed. |
| Uncommon Option | Behavior |
|---|---|
| ForceUserAuthRsaSha1 | Forces rsa-sha1 for public-key user authentication when required by older or unusual servers. |
| NoKeepAliveIgnoreMsg | Prevents Chilkat from sending an SSH ignore message every 20 seconds to keep an unused connection alive. |
| no-weak-mac-algs | Removes weaker MAC algorithms such as hmac-sha1-96, hmac-sha1, hmac-md5, and hmac-ripemd160 from the offered list. |
| ProtectFromVpn | On Android systems, bypasses any VPN that may be installed or active. |
| +ssh-hmac-etm | Re-adds *-etm MAC algorithms that were disabled by default to mitigate the Terrapin attack. |
| +chacha20-poly1305@openssh.com | Re-adds chacha20-poly1305@openssh.com, which is no longer included by default to mitigate the Terrapin attack. |
Method Summary by Category
| Category | Methods / Properties | Purpose |
|---|---|---|
| Connect | Connect, ConnectThroughSsh, IsSshConnected | Establish and monitor the SSH connection used for tunneling. |
| Authenticate | AuthenticatePw, AuthenticatePk, AuthenticatePwPk, AuthenticateSecPw, AuthenticateSecPwPk | Authenticate to the SSH server using password, private key, both, or secure strings. |
| Keyboard-interactive auth | StartKeyboardAuth, ContinueKeyboardAuth | Complete prompt/response style SSH authentication. |
| Accept clients | BeginAccepting, StopAccepting, IsAccepting, ListenPort | Start, stop, and inspect the local listening thread. |
| Close and disconnect | DisconnectAllClients, CloseTunnel | Disconnect current clients or close the entire tunnel. |
| Diagnostics | GetCurrentState, LastErrorText, HostKeyFingerprint | Inspect tunnel state, errors, and the connected server’s host key fingerprint. |
| Security and algorithms | SetAllowedAlgorithms, UncommonOptions | Control allowed SSH algorithms and uncommon compatibility/security options. |
| Async and abort | LoadTaskCaller, AbortCurrent | Support asynchronous task workflows and cancellation of long-running calls. |
Diagnostics and Troubleshooting
| Problem Area | Member | What to Check |
|---|---|---|
| Cannot connect to the SSH server | Connect, ConnectTimeoutMs, HttpProxy*, Socks* | Confirm hostname, port, timeout, outbound proxy settings, and network routing. |
| Authentication fails | AuthenticatePw, AuthenticatePk, AuthenticatePwPk, LastErrorText | Confirm credentials, private key, server-side public key installation, and include the full LastErrorText when reporting problems. |
| Listener does not start | BeginAccepting, IsAccepting, ListenBindIpAddress | Verify the listen port is unused and that any bind IP address is valid for the local machine. |
| Clients connect but traffic does not reach the destination | DestHostname, DestPort, DynamicPortForwarding, GetCurrentState | Confirm fixed destination settings or dynamic SOCKS settings, and inspect current tunnel state. |
| Dynamic SOCKS clients cannot authenticate | InboundSocksVersion, InboundSocksUsername, InboundSocksPassword | Confirm inbound SOCKS version and credentials expected by the client. |
| Tunnel stalls or times out | IdleTimeoutMs, SoRcvBuf, SoSndBuf, TcpNoDelay | Check idle timeout and consider socket buffer or TCP_NODELAY settings for performance-sensitive traffic. |
| Need detailed thread activity | KeepAcceptLog, KeepTunnelLog, AcceptLogPath, TunnelLogPath, ClientLogDir | Enable in-memory or file-based logs for listener, tunnel, or per-client activity. |
| Need operation details after failure | LastErrorText | Check diagnostic text after failed or unexpected connect, authenticate, listen, tunnel, proxy, dynamic forwarding, or close operations. |
Common Pitfalls
| Pitfall | Better Approach |
|---|---|
| Calling BeginAccepting before connecting and authenticating. | Call Connect, then authenticate, then call BeginAccepting. |
| Using a listen port already occupied by another process. | Choose an unused local port, or pass 0 and read the assigned port from ListenPort. |
| Assuming BeginAccepting failure is always returned immediately. | Wait briefly and check IsAccepting because the listener runs in a background thread. |
| Setting DestHostname and DestPort for dynamic forwarding and expecting them to be used. | In dynamic forwarding mode, the SOCKS client supplies the destination. |
| Confusing outbound SOCKS proxy settings with inbound dynamic SOCKS settings. | Use Socks* for the connection to the SSH server. Use InboundSocks* for clients connecting to the local dynamic SOCKS listener. |
| Changing ClientIdentifier to a string not beginning with SSH-2.0-. | Keep the required SSH identifier prefix to avoid server disconnects. |
| Forgetting to close the tunnel before application exit. | Call CloseTunnel when finished. |
Best Practices
| Recommendation | Reason |
|---|---|
| Set only the destination and proxy properties that apply to the selected forwarding mode. | Fixed forwarding uses DestHostname and DestPort; dynamic forwarding uses inbound SOCKS settings. |
| Check HostKeyFingerprint after connecting. | It helps identify the SSH server that was reached. |
| Use EnableSecrets for passwords in supported properties and methods. | It avoids embedding sensitive credentials directly in source code. |
| Leave bind IP and outbound bind port properties unset unless required. | Most systems should use the default routing and local port allocation. |
| Use logging only when needed. | Listener, tunnel, and per-client logs are valuable for troubleshooting but should be enabled deliberately. |
| Use SetAllowedAlgorithms only when strict algorithm control is required. | The default negotiation is usually preferred unless policy or compatibility requires explicit control. |
| Call DisconnectAllClients before closing only when client shutdown should be handled separately. | Otherwise, CloseTunnel closes the tunnel and disconnects existing clients. |
| Check LastErrorText after failures. | It provides useful diagnostic detail for SSH connection, authentication, listening, forwarding, proxy, dynamic SOCKS, algorithm, and shutdown issues. |
Summary
Chilkat.SshTunnel is the Chilkat class for creating SSH tunnels that forward local client connections through an SSH server. It supports fixed destination forwarding, dynamic SOCKS forwarding, several SSH authentication methods, outbound HTTP/SOCKS proxies, multi-hop SSH connections, secure secret lookup, listener and tunnel logging, socket tuning, algorithm controls, and detailed state and error diagnostics.
The most important practical guidance is to connect and authenticate before starting the listener, ensure the listen port is available, distinguish fixed destination forwarding from dynamic SOCKS forwarding, keep outbound proxy settings separate from inbound SOCKS settings, check IsAccepting after starting the listener, and call CloseTunnel when finished.