Sample code for 30+ languages & platforms
PowerBuilder

Multi-Hop SSH (SSH Through SSH)

See more SSH Examples

Demonstrates connecting to one SSH server through another: Application => ServerSSH1 => ServerSSH2. The ConnectThroughSsh method tunnels the second connection through the first. The technique chains further, so ServerSSH3 and beyond can be reached the same way.

Background: This is the "jump host" or bastion pattern: a gateway server is reachable from outside, and the machines you actually want are only reachable from inside. Each hop authenticates separately with its own credentials, and the result is an ordinary Ssh object for the far server that happens to be routed through the near one. Any number of connections may be tunneled through a single existing connection, and closing an inner connection leaves the outer one alive for reuse.

Chilkat PowerBuilder Downloads

PowerBuilder
integer li_rc
integer li_Success
oleobject loo_Ssh1
string ls_Hostname
integer li_Port
string ls_Password
oleobject loo_Ssh2
string ls_Password2
integer li_ChannelNum

li_Success = 0

//  This example requires the Chilkat API to have been previously unlocked.
//  See Global Unlock Sample for sample code.

//  Demonstrates connecting to one SSH server through another (SSH through SSH):
//  
//      Application => ServerSSH1 => ServerSSH2
//  
//  Any number of SSH connections may be tunneled through a single existing SSH connection, and
//  the technique can be chained further to reach ServerSSH3, ServerSSH4, and so on.

loo_Ssh1 = create oleobject
li_rc = loo_Ssh1.ConnectToNewObject("Chilkat.Ssh")
if li_rc < 0 then
    destroy loo_Ssh1
    MessageBox("Error","Connecting to COM object failed")
    return
end if

//  Connect directly to the 1st SSH server.
ls_Hostname = "jump.example.com"
li_Port = 22
li_Success = loo_Ssh1.Connect(ls_Hostname,li_Port)
if li_Success = 0 then
    Write-Debug loo_Ssh1.LastErrorText
    destroy loo_Ssh1
    return
end if

//  Normally you would not hard-code the password in source.  You should instead obtain it
//  from an interactive prompt, environment variable, or a secrets vault.
ls_Password = "mySshPassword"

li_Success = loo_Ssh1.AuthenticatePw("mySshLogin",ls_Password)
if li_Success = 0 then
    Write-Debug loo_Ssh1.LastErrorText
    destroy loo_Ssh1
    return
end if

//  Connect through the 1st SSH connection to reach the 2nd SSH server.
loo_Ssh2 = create oleobject
li_rc = loo_Ssh2.ConnectToNewObject("Chilkat.Ssh")

li_Success = loo_Ssh2.ConnectThroughSsh(loo_Ssh1,"target.example.com",li_Port)
if li_Success = 0 then
    Write-Debug loo_Ssh2.LastErrorText
    destroy loo_Ssh1
    destroy loo_Ssh2
    return
end if

//  The 2nd server has its own credentials.
ls_Password2 = "mySshPassword2"
li_Success = loo_Ssh2.AuthenticatePw("mySshLogin2",ls_Password2)
if li_Success = 0 then
    Write-Debug loo_Ssh2.LastErrorText
    destroy loo_Ssh1
    destroy loo_Ssh2
    return
end if

//  ssh2 is now connected and authenticated, and can be used exactly as if it were connected
//  directly.  For example, open a session channel to run commands.
li_ChannelNum = loo_Ssh2.OpenSessionChannel()
if li_ChannelNum < 0 then
    Write-Debug loo_Ssh2.LastErrorText
    destroy loo_Ssh1
    destroy loo_Ssh2
    return
end if

//  ... run commands on ssh2 ...

//  Closing ssh2 closes the tunnel through ssh1.  The ssh1 connection remains alive and may be
//  reused for more connections.
loo_Ssh2.Disconnect()

loo_Ssh1.Disconnect()


destroy loo_Ssh1
destroy loo_Ssh2