Connecting via Proxies

Net::SSH supports connecting to SSH servers through various types of proxies. This is configured using the :proxy option when calling Net::SSH.start.

ProxyCommand (Custom Command)

You can use any external command to establish a connection, similar to OpenSSH's ProxyCommand directive. This is the most flexible proxy method.

Create an instance of Net::SSH::Proxy::Command with a command template. The template can include placeholders:

  • %h: Replaced with the target hostname.
  • %p: Replaced with the target port.
  • %r: Replaced with the remote username.

Example: Using nc (netcat)

This example tunnels the SSH connection through bastion.example.com using nc.

require 'net/ssh'
require 'net/ssh/proxy/command'

proxy_command = 'ssh user@bastion.example.com -W %h:%p'
proxy = Net::SSH::Proxy::Command.new(proxy_command)

Net::SSH.start('internal-host', 'user', proxy: proxy) do |ssh|
  puts ssh.exec!('hostname')
end

ProxyJump

For multi-hop connections, Net::SSH supports a ProxyJump helper, which simplifies creating a ProxyCommand for SSH jump hosts.

Example: Single Jump Host

require 'net/ssh'
require 'net/ssh/proxy/jump'

proxy = Net::SSH::Proxy::Jump.new('jumpuser@jumphost.example.com')

Net::SSH.start('internal-host', 'user', proxy: proxy) do |ssh|
  puts ssh.exec!('hostname')
end

Example: Multiple Jump Hosts

Provide a comma-separated string for multi-hop jumps.

require 'net/ssh'
require 'net/ssh/proxy/jump'

jump_hosts = 'user1@jump1.example.com,user2@jump2.example.com'
proxy = Net::SSH::Proxy::Jump.new(jump_hosts)

Net::SSH.start('final-destination', 'user', proxy: proxy) do |ssh|
  puts ssh.exec!('hostname')
end

HTTP Proxy

Net::SSH can tunnel connections through an HTTP proxy using the CONNECT method.

Create an instance of Net::SSH::Proxy::HTTP.

Example: Basic HTTP Proxy

require 'net/ssh'
require 'net/ssh/proxy/http'

proxy = Net::SSH::Proxy::HTTP.new('proxy.example.com', 8080)

Net::SSH.start('ssh-server', 'user', proxy: proxy) do |ssh|
  puts ssh.exec!('hostname')
end

Example: HTTP Proxy with Authentication

If your proxy requires Basic authentication, provide the :user and :password options.

proxy = Net::SSH::Proxy::HTTP.new('proxy.example.com', 8080,
                                  user: 'proxy_user',
                                  password: 'proxy_password')

Net::SSH.start('ssh-server', 'user', proxy: proxy, password: 'ssh_password') do |ssh|
  # ...
end

HTTPS Proxy

For proxies that require TLS/SSL encryption for the proxy connection itself, use Net::SSH::Proxy::HTTPS.

require 'net/ssh'
require 'net/ssh/proxy/https'

proxy = Net::SSH::Proxy::HTTPS.new('secure-proxy.example.com', 443)

Net::SSH.start('ssh-server', 'user', proxy: proxy) do |ssh|
  # ...
end

SOCKS5 Proxy

To connect through a SOCKS5 proxy, use Net::SSH::Proxy::SOCKS5.

require 'net/ssh'
require 'net/ssh/proxy/socks5'

proxy = Net::SSH::Proxy::SOCKS5.new('socks-proxy.example.com', 1080,
                                  user: 'socks_user',
                                  password: 'socks_password')

Net::SSH.start('ssh-server', 'user', proxy: proxy) do |ssh|
  # ...
end

SOCKS4 Proxy

For older SOCKS4 proxies, use Net::SSH::Proxy::SOCKS4.

require 'net/ssh'
require 'net/ssh/proxy/socks4'

proxy = Net::SSH::Proxy::SOCKS4.new('socks4-proxy.example.com', 1080)

Net::SSH.start('ssh-server', 'user', proxy: proxy) do |ssh|
  # ...
end