aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2014-03-13 00:57:44 -0700
committerelijah <elijah@riseup.net>2014-03-13 00:57:44 -0700
commit82a1295f3a41ace4be6398945dd53e9c300a6d11 (patch)
tree8d8f969ad1468c32f9fe4eb1ac5acbf950a7e7cb
parent4e7e6b8dfe6363469f700260cf191a6fca6c202e (diff)
downloadleap_cli-82a1295f3a41ace4be6398945dd53e9c300a6d11.tar.gz
leap_cli-82a1295f3a41ace4be6398945dd53e9c300a6d11.tar.bz2
various ssh key fixes (REQUIRES rebuilding vagrant nodes).
-rw-r--r--lib/leap_cli/commands/node.rb6
-rw-r--r--lib/leap_cli/commands/shell.rb30
-rw-r--r--lib/leap_cli/remote/tasks.rb24
-rw-r--r--lib/leap_cli/util/remote_command.rb6
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