summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McLellan <btm@loftninjas.org>2019-05-13 13:36:18 -0400
committerBryan McLellan <btm@loftninjas.org>2019-05-13 13:39:57 -0400
commitf015d668e7661d9776fffcc6da012125f94704ea (patch)
treee750857433b7bd046a1af192ba7bc585ddd51f28
parent4e485c6944764bedb5e2b9b7b4ab9c5347df43d1 (diff)
downloadchef-f015d668e7661d9776fffcc6da012125f94704ea.tar.gz
Use new Net:SSH host key verify values
Fixes #8482 by prompting to continue if the host key is not recognized. This attempts to tell Net:SSH to accept and write the key but it is only temporarily accepting. This changes the parameters of --ssh-verify-host-key (which is new) to take the Net::SSH values, which get passed through by train. This allows the user more options than only verifying or not. Signed-off-by: Bryan McLellan <btm@loftninjas.org>
-rw-r--r--lib/chef/knife/bootstrap.rb40
-rw-r--r--spec/unit/knife/bootstrap_spec.rb4
2 files changed, 32 insertions, 12 deletions
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 59d7e7007c..c1ba864cea 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -88,7 +88,7 @@ class Chef
option :winrm_auth_method,
short: "-w AUTH-METHOD",
long: "--winrm-auth-method AUTH-METHOD",
- description: "The WinRM authentication method to use. Valid choices are #{friendly_opt_list(WINRM_AUTH_PROTOCOL_LIST)}.",
+ description: "The WinRM authentication method to use.",
proc: Proc.new { |protocol| Chef::Config[:knife][:winrm_auth_method] = protocol },
in: WINRM_AUTH_PROTOCOL_LIST
@@ -146,9 +146,9 @@ class Chef
description: "The SSH identity file used for authentication."
option :ssh_verify_host_key,
- long: "--[no-]ssh-verify-host-key",
- description: "Verify host key, enabled by default.",
- boolean: true
+ long: "--ssh-verify-host-key VALUE",
+ description: "Verify host key. Default is 'always'.",
+ in: %w{always accept_new accept_new_or_local_tunnel never}
#
# bootstrap options
@@ -162,7 +162,7 @@ class Chef
option :channel,
long: "--channel CHANNEL",
- description: "Install from the given channel. Valid values are 'stable, 'current', and 'unstable'. Default is 'stable'",
+ description: "Install from the given channel. Default is 'stable'.",
default: "stable",
in: %w{stable current unstable}
@@ -549,7 +549,28 @@ class Chef
$stdout.sync = true
register_client
- connect!
+ begin
+ connect!
+ rescue Train::Transports::SSHFailed => e
+ if e.message =~ /fingerprint (\S+) is unknown for "(.+)"/
+ fingerprint = $1
+ hostname,ip = $2.split(',')
+ puts "The authenticity of host '#{hostname} (#{ip})' can't be established."
+ # TODO: convert the SHA256 base64 value to hex with colons
+ # 'ssh' example output:
+ # RSA key fingerprint is e5:cb:c0:e2:21:3b:12:52:f8:ce:cb:00:24:e2:0c:92.
+ # ECDSA key fingerprint is 5d:67:61:08:a9:d7:01:fd:5e:ae:7e:09:40:ef:c0:3c.
+ puts "fingerprint is #{fingerprint}."
+ ui.confirm("Are you sure you want to continue connecting")
+ # FIXME: this should save the key to known_hosts but doesn't appear to be
+ config[:ssh_verify_host_key] = :accept_new
+ connection_opts(reset: true)
+ retry
+ end
+
+ raise e
+ end
+
unless client_builder.client_path.nil?
bootstrap_context.client_pem = client_builder.client_path
end
@@ -781,8 +802,8 @@ class Chef
# @return a configuration hash suitable for connecting to the remote
# host via train
- def connection_opts
- return @connection_opts unless @connection_opts.nil?
+ def connection_opts(reset: false)
+ return @connection_opts unless @connection_opts.nil? || reset == true
@connection_opts = {}
@connection_opts.merge! base_opts
@connection_opts.merge! host_verify_opts
@@ -824,8 +845,7 @@ class Chef
{ self_signed: config_value(:winrm_no_verify_cert) === true }
elsif ssh?
# Fall back to the old knife config key name for back compat.
- { verify_host_key: config_value(:ssh_verify_host_key,
- :host_key_verify, true) === true }
+ { verify_host_key: config_value(:ssh_verify_host_key, :host_key_verify, "always") }
else
{}
end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 5280e3b64b..e0157b83a5 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -1131,7 +1131,7 @@ describe Chef::Knife::Bootstrap do
logger: Chef::Log,
keys_only: false,
sudo: false,
- verify_host_key: true,
+ verify_host_key: "always",
non_interactive: true,
}
end
@@ -1229,7 +1229,7 @@ describe Chef::Knife::Bootstrap do
expect(knife.host_verify_opts).to eq( { verify_host_key: false } )
end
it "provides a correct default when no option given" do
- expect(knife.host_verify_opts).to eq( { verify_host_key: true } )
+ expect(knife.host_verify_opts).to eq( { verify_host_key: "always"} )
end
end
end