7. Using Proxies
7.1. Introduction
Many times, you may find yourself behind a firewall, unable to SSH out. In such instances, you can often take advantage of your existing proxies to tunnel an SSH connection through your firewall.
7.2. HTTP
If you have an HTTP proxy running, you may be able to use it to your advantage. The following snippet demonstrates how to tunnel an SSH connection through an HTTP proxy:
1 2 3 4 5 6 7 8 9 10 | require 'net/ssh' require 'net/ssh/proxy/http' proxy_host = 'my.proxy.com' proxy_port = 8080 proxy = Net::SSH::Proxy::HTTP.new( proxy_host, proxy_port ) Net::SSH.start( 'host', :proxy => proxy ) do |session| ... end |
As you can see, you first create an instance of the proxy you want to use. (This flexibility allows for other proxy types to be supported, although at present only HTTP and SOCKS are available.)
Once you’ve created your proxy, you just start your SSH session, as usual, except you also pass a :proxy
option. The proxy will then be used to obtain a connection to the remote host.
Note: If your proxy does not allow connects to be made to other hosts on port 22, then you’ll have to do some magic to allow SSH connections on your remote host on ports other than 22. Port forwarding on that remote host (from itself, to itself), can help you there.
For instance, if your proxy disallows connections to any port except (say) 443, you could run the following command on the remote host:
ssh -gL 443:localhost:22 localhost
Then, as long as that command is running, port 443 will always be forwarded to port 22. Naturally, this means that you must run this command while you have access to the box; if you can’t access that machine in the first place (ie, because you’re behind a firewall), then it does you no good.
Proxy Authentication
Some proxies require authentication. Net::SSH supports these proxies as well. If you specify the user name either as a :user
option to the HTTP proxy constructor, or in the HTTP_PROXY_USER
or CONNECT_USER
environment variables, that name will be used to authenticate with the proxy. Likewise, the password may be given either via the :password
constructor option, or via the HTTP_PROXY_PASSWORD
or CONNECT_PASSWORD
environment variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | require 'net/ssh' require 'net/ssh/proxy/http' proxy_host = 'my.proxy.com' proxy_port = 8080 proxy_user = 'my-name' proxy_password = 'my-password' proxy = Net::SSH::Proxy::HTTP.new( proxy_host, proxy_port, :user => proxy_user, :password => proxy_password ) Net::SSH.start( 'host', :proxy => proxy ) do |session| ... end |
Note that currently, only basic authentication is supported; in the future, digest authentication may be added for proxies that support it.
7.3. SOCKS
In addition to the HTTP proxy, Net::SSH also supports SOCKS proxies (both versions 4 and 5). Their usage is almost identical to the HTTP version (except SOCKS4 does not use passwords, just user names):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | require 'net/ssh' require 'net/ssh/proxy/socks4' require 'net/ssh/proxy/socks5' proxy_host = 'my.proxy.com' proxy_port = 1080 proxy_user = 'my-name' proxy_password = 'my-password' socks4 = Net::SSH::Proxy::SOCKS4.new( proxy_host, proxy_port, :user => proxy_user ) socks5 = Net::SSH::Proxy::SOCKS5.new( proxy_host, proxy_port, :user => proxy_user, :password => proxy_password) Net::SSH.start( 'host', :proxy => socks4 ) do |session| ... end |