Puppet Function: ssh::autokey

Defined in:
lib/puppet/functions/ssh/autokey.rb
Function type:
Ruby 4.x API

Summary

Generates a random RSA SSH private and public key pair for a passed

Overview

user.

Keys are stored in

"Puppet[:vardir]/simp/environments/<environment>/simp_autofiles/ssh_autokeys"

Note: This function if marked as an InternalFunction because it changes the state of the system by writing key files.

Signatures:

  • ssh::autokey(String $username, Optional[Hash] $options)String

    The following options are supported:

    • ‘key_strength’: key length, Integer, defaults to 2048

    • ‘return_private’: whether to return the private key, Boolean, defaults to false

    NOTE: A minimum key strength of 1024 is enforced!

    Parameters:

    • username (String)

      username for which SSH key pairs will be generated

    • options (Optional[Hash])

      Options hash

    Returns:

    • (String)

      The public key of the user

  • ssh::autokey(String $username, Optional[Integer] $key_strength, Optional[Boolean] $return_private)String

    NOTE: A minimum key strength of 1024 is enforced!

    Parameters:

    • username (String)

      username for which SSH key pairs will be generated

    • key_strength (Optional[Integer])

      key length, defaults to 2048

    • return_private (Optional[Boolean])

      whether to return the private key, defaults to false

    Returns:

    • (String)

      The public key of the user or the private key if return_private is specified.



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
95
96
97
98
# File 'lib/puppet/functions/ssh/autokey.rb', line 10

Puppet::Functions.create_function(:'ssh::autokey', Puppet::Functions::InternalFunction) do
  # @param username username for which SSH key pairs will be generated
  # @param options Options hash
  # The following options are supported:
  # - 'key_strength': key length, Integer, defaults to 2048
  # - 'return_private': whether to return the private key, Boolean, defaults to false
  # NOTE: A minimum key strength of 1024 is enforced!
  #
  # @return [String] The public key of the user
  dispatch :autokey_with_options_hash do
    required_param 'String', :username
    optional_param 'Hash', :options
  end

  # @param username username for which SSH key pairs will be generated
  # @param key_strength key length, defaults to 2048
  # @param return_private whether to return the private key, defaults to false
  # NOTE: A minimum key strength of 1024 is enforced!
  #
  # @return [String] The public key of the user or the private key if
  #   return_private is specified.
  dispatch :autokey do
    required_param 'String', :username
    optional_param 'Integer', :key_strength
    optional_param 'Boolean', :return_private
  end

  def autokey_with_options_hash(username, options=nil)
    key_strength = 2048
    return_private = false

    if options
      key_strength = options['key_strength'].to_i if options['key_strength']
      return_private = options['return_private'] if options['return_private']
    end

    autokey(username, key_strength, return_private)
  end

  def autokey(username, key_strength=nil, return_private=nil)
    require "timeout"

    key_strength = 2048 if key_strength.nil?
    key_strength = 1024 unless (key_strength > 1024)
    return_private = false if return_private.nil?

    retval = "error"

    if !username
      fail('ssh::autokey: Error, username not specified')
    end

    env = closure_scope.lookupvar('::environment')
    keydir = "#{Puppet[:vardir]}/simp/environments/#{env}/simp_autofiles/ssh_autokeys"

    if ( !File.directory?(keydir) )
      begin
        FileUtils.mkdir_p(keydir, mode: 0750)
      rescue
        Puppet.warning "ssh::autokey: Could not make directory #{keydir}. Ensure that #{keydir} is writable by 'puppet'"
        return retval
      end
    end

    if ( !File.exist?("#{keydir}/#{username}") )
      begin
        Timeout::timeout(30) do
          Puppet::Util::Execution.execute("/usr/bin/ssh-keygen -N '' -q -t rsa -C '' -b #{key_strength} -f #{keydir}/#{username}")
          FileUtils.chmod 0640, "#{keydir}/#{username}"
          FileUtils.chmod 0640, "#{keydir}/#{username}.pub"
        end
      rescue Timeout::Error
        Puppet.warning "ssh::autokey: ssh-keygen timed out for #{username}"
      end
    end

    if ( File.exist?("#{keydir}/#{username}.pub") )
      if return_private
        retval = File.read("#{keydir}/#{username}")
      else
        # Grab the first line from the generated file and spit out only the
        # hash portion.
        retval = File.readlines("#{keydir}/#{username}.pub")[0].split(/\s/)[1]
      end
    end

    return retval
  end
end