From 82a1295f3a41ace4be6398945dd53e9c300a6d11 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 13 Mar 2014 00:57:44 -0700 Subject: various ssh key fixes (REQUIRES rebuilding vagrant nodes). --- lib/leap_cli/commands/node.rb | 6 +++++- lib/leap_cli/commands/shell.rb | 30 +++++++++++++++++++++++++----- lib/leap_cli/remote/tasks.rb | 24 ++++++++++++++++++++++++ lib/leap_cli/util/remote_command.rb | 6 ++++++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index 056ec28..fdd1fa8 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -63,7 +63,11 @@ module LeapCli; module Commands update_compiled_ssh_configs ssh_connect_options = connect_options(options).merge({:bootstrap => true, :echo => options[:echo]}) ssh_connect(node, ssh_connect_options) do |ssh| - ssh.install_authorized_keys + if node.vagrant? + ssh.install_authorized_keys2 + else + ssh.install_authorized_keys + end ssh.install_prerequisites ssh.leap.capture(facter_cmd) do |response| if response[:exitcode] == 0 diff --git a/lib/leap_cli/commands/shell.rb b/lib/leap_cli/commands/shell.rb index c7d14f8..13c5003 100644 --- a/lib/leap_cli/commands/shell.rb +++ b/lib/leap_cli/commands/shell.rb @@ -32,19 +32,28 @@ module LeapCli; module Commands return connect_options end + def ssh_config_help_message + puts "" + puts "Are 'too many authentication failures' getting you down?" + puts "Then we have the solution for you! Add something like this to your ~/.ssh/config file:" + puts " Host *.#{manager.provider.domain}" + puts " IdentityFile ~/.ssh/id_rsa" + puts " IdentitiesOnly=yes" + puts "(replace `id_rsa` with the actual private key filename that you use for this provider)" + end + private def exec_ssh(cmd, args) node = get_node_from_args(args, :include_disabled => true) options = [ - "-o 'HostName=#{node.ip_address}'", + "-o 'HostName=#{node.domain.full}'", # "-o 'HostKeyAlias=#{node.name}'", << oddly incompatible with ports in known_hosts file, so we must not use this or non-standard ports break. "-o 'GlobalKnownHostsFile=#{path(:known_hosts)}'", "-o 'UserKnownHostsFile=/dev/null'" ] if node.vagrant? options << "-i #{vagrant_ssh_key_file}" # use the universal vagrant insecure key - options << '-o IdentitiesOnly=yes' # only use explicitly configured keys options << "-o 'StrictHostKeyChecking=no'" # blindly accept host key and don't save it (since userknownhostsfile is /dev/null) else options << "-o 'StrictHostKeyChecking=yes'" @@ -57,12 +66,23 @@ module LeapCli; module Commands end ssh = "ssh -l #{username} -p #{node.ssh.port} #{options.join(' ')}" if cmd == :ssh - command = "#{ssh} #{node.name}" + command = "#{ssh} #{node.domain.full}" elsif cmd == :mosh - command = "MOSH_TITLE_NOPREFIX=1 mosh --ssh \"#{ssh}\" #{node.name}" + command = "MOSH_TITLE_NOPREFIX=1 mosh --ssh \"#{ssh}\" #{node.domain.full}" end log 2, command - exec "#{command}" + + # exec the shell command in a subprocess + pid = fork { exec "#{command}" } + + # wait for shell to exit so we can grab the exit status + _, status = Process.waitpid2(pid) + + if status.exitstatus == 255 + ssh_config_help_message + elsif status.exitstatus != 0 + exit_now! status.exitstatus, status.exitstatus + end end end; end \ No newline at end of file diff --git a/lib/leap_cli/remote/tasks.rb b/lib/leap_cli/remote/tasks.rb index 5b0418a..9f24599 100644 --- a/lib/leap_cli/remote/tasks.rb +++ b/lib/leap_cli/remote/tasks.rb @@ -12,6 +12,30 @@ task :install_authorized_keys, :max_hosts => MAX_HOSTS do end end +# +# for vagrant nodes, we don't overwrite authorized_keys, because we want to keep the insecure vagrant key. +# instead we install to authorized_keys2, which is also used by sshd. +# +# why? +# without it, it might be impossible to re-initialize a node. +# +# ok, why is that? +# when we init a vagrant node, we force it to use the insecure vagrant key, and not the user's keys +# (so re-initialization would be impossible if authorized_keys doesn't include insecure key). +# +# ok, why force the insecure vagrant key in the first place? +# if we don't do this, then first time initialization might fail if the user has many keys +# (ssh will bomb out before it gets to the vagrant key). +# and it really doesn't make sense to ask users to pin the insecure vagrant key in their +# .ssh/config files. +# +task :install_authorized_keys2, :max_hosts => MAX_HOSTS do + leap.log :updating, "authorized_keys2" do + leap.mkdirs '/root/.ssh' + upload LeapCli::Path.named_path(:authorized_keys), '/root/.ssh/authorized_keys2', :mode => '600' + end +end + task :install_prerequisites, :max_hosts => MAX_HOSTS do leap.mkdirs LeapCli::PUPPET_DESTINATION leap.log :updating, "package list" do diff --git a/lib/leap_cli/util/remote_command.rb b/lib/leap_cli/util/remote_command.rb index 93d1bd1..847b056 100644 --- a/lib/leap_cli/util/remote_command.rb +++ b/lib/leap_cli/util/remote_command.rb @@ -35,6 +35,12 @@ module LeapCli; module Util; module RemoteCommand end yield cap + rescue Capistrano::ConnectionError => exc + # not sure if this will work if english is not the locale?? + if exc.message =~ /Too many authentication failures/ + at_exit {ssh_config_help_message} + end + raise exc end private -- cgit v1.2.3