1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
require_relative 'common'
require 'fileutils'
require 'tmpdir'
require 'net/ssh'
require 'timeout'
# see Vagrantfile,playbook for env.
# we're running as net_ssh_1 user password foo
# and usually connecting to net_ssh_2 user password foo2pwd
class TestCertHostAuth < NetSSHTest
include IntegrationTestHelpers
def setup_ssh_env(&block)
tmpdir do |dir|
cert_type = "rsa"
# cert_type = "ssh-ed25519"
host_key_type = "ecdsa"
# host_key_type = "ed25519"
# create a cert, and sign the host key
@cert = "#{dir}/ca"
sh "rm -rf #{@cert} #{@cert}.pub"
sh "ssh-keygen -t #{cert_type} -N '' -C 'ca@hosts.netssh' -f #{@cert} #{debug ? '' : '-q'}"
FileUtils.cp "/etc/ssh/ssh_host_#{host_key_type}_key.pub", "#{dir}/one.hosts.netssh.pub"
Dir.chdir(dir) do
sh "ssh-keygen -s #{@cert} -h -I one.hosts.netssh -n one.hosts.netssh #{debug ? '' : '-q'} #{dir}/one.hosts.netssh.pub"
sh "ssh-keygen -L -f one.hosts.netssh-cert.pub" if debug
end
signed_host_key = "/etc/ssh/ssh_host_#{host_key_type}_key-cert.pub"
sh "sudo cp -f #{dir}/one.hosts.netssh-cert.pub #{signed_host_key}"
# we don't use this for signing the cert
@badcert = "#{dir}/badca"
sh "rm -rf #{@badcert} #{@badcert}.pub"
sh "ssh-keygen -t #{cert_type} -N '' -C 'ca@hosts.netssh' -f #{@badcert} #{debug ? '' : '-q'}"
yield(cert_pub: "#{@cert}.pub", badcert_pub: "#{@badcert}.pub", signed_host_key: signed_host_key)
end
end
def debug
false
end
def test_host_should_match_when_host_key_was_signed_by_key
Tempfile.open('cert_kh') do |f|
setup_ssh_env do |params|
data = File.read(params[:cert_pub])
f.write("@cert-authority [*.hosts.netssh]:2200 #{data}")
f.close
config_lines = ["HostCertificate #{params[:signed_host_key]}"]
start_sshd_7_or_later(config: config_lines) do |_pid, port|
Timeout.timeout(500) do
# sleep 0.2
# sh "ssh -v -i ~/.ssh/id_ed25519 one.hosts.netssh -o UserKnownHostsFile=#{f.path} -p 2200"
ret = Net::SSH.start("one.hosts.netssh", "net_ssh_1", password: 'foopwd', port: port, verify_host_key: :always, user_known_hosts_file: [f.path]) do |ssh|
ssh.exec! "echo 'foo'"
end
assert_equal "foo\n", ret
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
sleep 0.25
retry
end
end
end
end
end
def test_with_other_pub_key_host_key_should_not_match
Tempfile.open('cert_kh') do |f|
setup_ssh_env do |params|
data = File.read(params[:badcert_pub])
f.write("@cert-authority [*.hosts.netssh]:2200 #{data}")
f.close
config_lines = ["HostCertificate #{params[:signed_host_key]}"]
start_sshd_7_or_later(config: config_lines) do |_pid, port|
Timeout.timeout(100) do
sleep 0.2
assert_raises(Net::SSH::HostKeyMismatch) do
Net::SSH.start("one.hosts.netssh", "net_ssh_1", password: 'foopwd', port: port, verify_host_key: :always, user_known_hosts_file: [f.path]) do |ssh|
ssh.exec! "echo 'foo'"
end
end
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
sleep 0.25
retry
end
end
end
end
end
end
|