Class: Awsborn::KnownHostsUpdater

Inherits:
Object
  • Object
show all
Defined in:
lib/awsborn/known_hosts_updater.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ec2, host_name) ⇒ KnownHostsUpdater

Returns a new instance of KnownHostsUpdater.



18
19
20
21
# File 'lib/awsborn/known_hosts_updater.rb', line 18

def initialize (ec2, host_name)
  @host_name = host_name
  @ec2 = ec2
end

Class Attribute Details

.loggerObject

Returns the value of attribute logger.



5
6
7
# File 'lib/awsborn/known_hosts_updater.rb', line 5

def logger
  @logger
end

Instance Attribute Details

#console_fingerprintObject

Returns the value of attribute console_fingerprint.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def console_fingerprint
  @console_fingerprint
end

#ec2Object

Returns the value of attribute ec2.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def ec2
  @ec2
end

#fingerprint_fileObject

Returns the value of attribute fingerprint_file.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def fingerprint_file
  @fingerprint_file
end

#host_ipObject

Returns the value of attribute host_ip.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def host_ip
  @host_ip
end

#host_nameObject

Returns the value of attribute host_name.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def host_name
  @host_name
end

#loggerObject

Returns the value of attribute logger.



16
17
18
# File 'lib/awsborn/known_hosts_updater.rb', line 16

def logger
  @logger
end

Class Method Details

.update_for_server(server) ⇒ Object



6
7
8
9
# File 'lib/awsborn/known_hosts_updater.rb', line 6

def update_for_server (server)
  known_hosts = new(server.ec2, server.host_name)
  known_hosts.update
end

Instance Method Details

#clean_out_known_hostsObject



67
68
69
70
# File 'lib/awsborn/known_hosts_updater.rb', line 67

def clean_out_known_hosts
  remove_from_known_hosts host_name
  remove_from_known_hosts host_ip
end

#compare_fingerprints!Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/awsborn/known_hosts_updater.rb', line 81

def compare_fingerprints!
  name_fingerprint, ip_fingerprint = fingerprints_from_file

  if name_fingerprint.nil? || ip_fingerprint.nil?
    raise SecurityError, "name_fingerprint = #{name_fingerprint.inspect}, ip_fingerprint = #{ip_fingerprint.inspect}"
  elsif name_fingerprint.split[1] != ip_fingerprint.split[1]
    raise SecurityError, "Fingerprints do not match:\n#{name_fingerprint} (#{host_name})\n#{ip_fingerprint} (#{host_ip})!"
  elsif name_fingerprint.split[1] != console_fingerprint
    raise SecurityError, "Fingerprints do not match:\n#{name_fingerprint} (#{host_name})\n#{console_fingerprint} (EC2 Console)!"
  end
end

#create_tempfileObject



101
102
103
104
105
106
107
108
# File 'lib/awsborn/known_hosts_updater.rb', line 101

def create_tempfile
  tmp = Tempfile.new "awsborn"
  tmp.close
  def tmp.to_s
    path
  end
  tmp
end

#fingerprints_from_fileObject



93
94
95
# File 'lib/awsborn/known_hosts_updater.rb', line 93

def fingerprints_from_file
  `ssh-keygen -l -f #{fingerprint_file}`.split("\n")
end

#get_console_fingerprintObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/awsborn/known_hosts_updater.rb', line 49

def get_console_fingerprint
  # ec2: -----BEGIN SSH HOST KEY FINGERPRINTS-----
  # ec2: 2048 7a:e9:eb:41:b7:45:b1:07:30:ad:13:c5:a9:2a:a1:e5 /etc/ssh/ssh_host_rsa_key.pub (RSA)
  regexp = %r{BEGIN SSH HOST KEY FINGERPRINTS.*((?:[0-9a-f]{2}:){15}[0-9a-f]{2})[ \t]+\S+[ \t]+\(RSA\)}m
  @console_fingerprint = Awsborn.wait_for "console output", 15, 420 do
    console = ec2.get_console_output
    unless console.empty?
      fingerprint = console[regexp, 1]
      if ! fingerprint
        logger.error "*** SSH RSA fingerprint not found ***"
        logger.error console
        logger.error "*** SSH RSA fingerprint not found ***"
      end
    end
    fingerprint
  end
end

#remove_from_known_hosts(host) ⇒ Object



72
73
74
# File 'lib/awsborn/known_hosts_updater.rb', line 72

def remove_from_known_hosts (host)
  system "ssh-keygen -R #{host} > /dev/null 2>&1"
end

#save_fingerprintsObject



97
98
99
# File 'lib/awsborn/known_hosts_updater.rb', line 97

def save_fingerprints
  system "cat #{fingerprint_file} >> #{ENV['HOME']}/.ssh/known_hosts"
end

#scan_hostsObject



76
77
78
79
# File 'lib/awsborn/known_hosts_updater.rb', line 76

def scan_hosts
  self.fingerprint_file = create_tempfile
  system "ssh-keyscan -t rsa #{host_name} #{host_ip} > #{fingerprint_file} 2>/dev/null"
end

#try_updateObject



41
42
43
44
45
46
47
# File 'lib/awsborn/known_hosts_updater.rb', line 41

def try_update
  get_console_fingerprint
  clean_out_known_hosts
  scan_hosts
  compare_fingerprints!
  save_fingerprints
end

#updateObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/awsborn/known_hosts_updater.rb', line 23

def update
  tries = 0
  begin
    tries += 1
    try_update
  rescue SecurityError => e
    if tries < 8
      logger.debug e.message
      sleep_time = [2**tries, 30].min
      logger.debug "Fingerprint try #{tries} failed, sleeping #{sleep_time} seconds"
      sleep(sleep_time)
      retry
    else
      raise e
    end
  end
end