Last active
October 3, 2015 06:57
-
-
Save halo/2412677 to your computer and use it in GitHub Desktop.
A small Ruby tool making it easy to establish an SSH tunnel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
require 'ostruct' | |
# Extension for colored Strings | |
class String | |
def red() colored(:red); end | |
def green() colored(:green); end | |
def yellow() colored(:yellow); end | |
def blue() colored(:blue); end | |
def magenta() colored(:magenta); end | |
def cyan() colored(:cyan); end | |
def colored(color=nil) | |
code = case color | |
when :red then 31 | |
when :green then 32 | |
when :yellow then 33 | |
when :blue then 34 | |
when :magenta then 35 | |
when :cyan then 36 | |
end | |
self.gsub!('<b>', "\033[1m") | |
self.gsub!('</b>', "\033[22m") | |
self.gsub!('<blink>', "\033[5m") | |
self.gsub!('</blink>', "\033[25m") | |
"\033[#{code}m#{self}\033[0m" | |
end | |
end | |
# Setting default options | |
options = OpenStruct.new({ | |
:local => OpenStruct.new({ | |
:host => `hostname -f`.chomp, | |
:port => 2000, | |
}), | |
:proxy => OpenStruct.new({ | |
:host => 'proxy.example.com', | |
:ssh => OpenStruct.new({ | |
:user => nil, | |
:port => nil, | |
}), | |
}), | |
:target => OpenStruct.new({ | |
:host => 'target.example.com', | |
:port => 3306, | |
}), | |
}) | |
# Draws a graph of the tunnel according to options | |
def graph(options) | |
result = "Port <b>#{options.local.port}</b> of #{options.local.host}</b>".green | |
result << " ➜ " | |
if options.proxy.host | |
result << "<b>#{options.proxy.ssh.user}@</b>".yellow if options.proxy.ssh.user | |
result << "<b>#{options.proxy.host}</b>".yellow | |
result << " (using port <b>#{options.proxy.ssh.port}</b> for SSH access)".yellow if options.proxy.ssh.port | |
result << ' ➜ ' | |
end | |
result << "Port <b>#{options.target.port}</b> of <b>#{options.target.host}</b>".red | |
result | |
end | |
help = '' | |
OptionParser.new do |parser| | |
parser.banner = "" | |
parser.separator " TUNNEL ENTRANCE".green | |
parser.on("--local-port=PORT", "The tunnel begins on this port on <b>#{options.local.host}</b> ".colored) do |value| | |
options.local.port = value | |
end | |
parser.separator "" | |
parser.separator " TUNNEL PROXY".yellow + " (optional)" | |
parser.on("--proxy-host=HOST", "If this is set, the Tunnel will go via this server. ") do |value| | |
options.proxy.host = value | |
end | |
parser.on("--proxy-user=USER", "The SSH user for connecting to the proxy server <b>#{options.proxy.host ? options.proxy.host + ' ' : ''}</b>".colored) do |value| | |
options.proxy.ssh.user = value | |
end | |
parser.on("--proxy-port=PORT", "The SSH port for connecting to the proxy server <b>#{options.proxy.host ? options.proxy.host + ' ' : ''}</b>".colored) do |value| | |
options.proxy.ssh.port = value | |
end | |
parser.separator "" | |
parser.separator " TUNNEL EXIT".red | |
parser.on("--target-host=HOST", 'The server you\'re trying to establish a tunnel to. Use "localhost" if it\'s the proxy.'.colored) do |value| | |
options.target.host = value | |
end | |
parser.on("--target-port=PORT", "The port on the target-host at the very end of the tunnel.".colored) do |value| | |
options.target.port = value | |
end | |
parser.on('--go', 'Establishes the tunnel') do |value| | |
options.go = true | |
end | |
parser.separator "" | |
help = parser.help | |
end.order! | |
proxy_user_addon = options.proxy.ssh.user ? "#{options.proxy.ssh.user}@" : '' | |
proxy_port_addon = options.proxy.ssh.port ? "-p #{options.proxy.ssh.port} " : '' | |
command = %{ssh #{proxy_user_addon}#{options.proxy.host} #{proxy_port_addon}-N -L #{options.local.port}:#{options.target.host}:#{options.target.port}} | |
if options.go | |
puts | |
puts " Establishing tunnel..." | |
puts ' ' + graph(options) | |
puts | |
puts ' ' + command | |
puts | |
exec command | |
else | |
puts | |
puts " USAGE".cyan | |
puts " Add the parameter " + '--go'.cyan + ' to establish the tunnel according to the "current configuration" below.'.colored | |
puts | |
puts " CURRENT CONFIGURATION".cyan | |
puts " #{graph(options)}" | |
puts help | |
puts " COMMAND USED".cyan | |
puts " #{command}" | |
puts | |
exit | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Running this in bash, you'll get this help message.
Note that it presents to you the ssh command it would use (the last line shown above)