Skip to content

Instantly share code, notes, and snippets.

@redperadot
Last active August 29, 2015 14:01
Show Gist options
  • Save redperadot/ddf0ffb272fa16787eae to your computer and use it in GitHub Desktop.
Save redperadot/ddf0ffb272fa16787eae to your computer and use it in GitHub Desktop.
Setup SSH login without a password.
#!/usr/bin/env ruby
#
# auto-ssh.rb - Setup SSH login without a password.
# Made with ❤︎ by [email protected]
## Gem Installer
def require_gems(*gems)
gems.each do |_gem|
begin require _gem
rescue LoadError
dep = _gem.split('/')[0]
puts "[Info] Installing the dependency '#{dep}'."
system("gem install #{dep} > /dev/null 2>&1")
require _gem
end
end
end
## Version, Require Stuff, & Clean Exit
version = 0.3
Signal.trap("INT") { puts; exit 0 }
require_gems( 'optparse', 'io/console', 'net/sftp' )
## Get CLI Options
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [flag]"
opts.on("--help", "Show this message.") do
puts opts
exit
end
opts.on("-h", "--host HOSTNAME", "The remote host to install your public key.") do |hn|
@host = hn
end
opts.on("-u", "--user USERNAME", "The user to log into the remote host.") do |un|
@user = un
end
opts.on("-p", "--pass PASSWORD", "The password to log into the remote host.") do |pw|
@pass = pw
end
opts.on("-k", "--key KEYFILE", "The path to the public key to install.") do |kf|
@key = kf
end
end
## Parse Options
begin opt_parser.parse! ARGV
rescue OptionParser::InvalidOption => e
puts "[Error] #{e}"
exit 1
rescue OptionParser::MissingArgument => e
puts "[Error] #{e}"
exit 1
end
## Ask about remote system.
puts "I need some information about the remote system."
@host ||= (print 'Hostname: '; gets.chomp)
@user ||= (print 'Username: '; gets.chomp)
@pass ||= (print 'Password: '; $stdin.noecho(&:gets).chomp)
puts
## Get this users key.
def get_key
# If the key was set from an argument, lets read it.
unless @key.nil?
puts "Reading your public key."
@key = File.read(@key)
return
end
# Let's generate a key if one does not already exist.
unless File.exists?(File.expand_path('~/.ssh/id_rsa.pub'))
puts "You don't have a rsa key pair yet. So I will generate one for you."
`ssh-keygen -t rsa`
end
# We can now read the public key.
puts "Reading your public key."
@key = File.read(File.expand_path('~/.ssh/id_rsa.pub'))
end
## Give remote host this users key.
def write_key
puts "Accessing the remote host '#{@host}'."
begin
Net::SFTP.start(@host, @user, :password => @pass) do |sftp|
puts "Creating the SSH directory on '#{@host}'."
sftp.mkdir! '.ssh'
puts "Adding your key to #{@user}@#{@host}'s authorized keys."
sftp.file.open('.ssh/authorized_keys', 'a') do |f|
f.puts @key
end
end
rescue SocketError
abort('[Error] The port was not open on the remote host.')
rescue Timeout::Error
abort('[Error] The connection timed out.')
rescue Errno::EHOSTUNREACH
abort('[Error] Could not reach the remote host.')
rescue Errno::ECONNREFUSED
abort('[Error] The connection to the remote host was refused.')
rescue Net::SSH::AuthenticationFailed
abort('[Error] Authentication with the remote host failed.')
rescue NameError
abort('[Error] The gem "net-sftp" is not installed.')
rescue Exception
abort('[Error] An unknown error occurred.')
end
end
## Run Actions
get_key
write_key
puts "You can now login to #{@host} without a password."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment