diff options
author | Olivier Blin <blino@mageia.org> | 2010-11-22 00:22:53 +0000 |
---|---|---|
committer | Olivier Blin <blino@mageia.org> | 2010-11-22 00:22:53 +0000 |
commit | bad3d2f5abd672dd67da510a73a03f28605bd386 (patch) | |
tree | eb894c54071ca008acd534f1eb579881a62f760a /modules | |
parent | dc4f9763c08806d7fcf7865af4c8aa14f78ca7b1 (diff) | |
download | puppet-bad3d2f5abd672dd67da510a73a03f28605bd386.tar puppet-bad3d2f5abd672dd67da510a73a03f28605bd386.tar.gz puppet-bad3d2f5abd672dd67da510a73a03f28605bd386.tar.bz2 puppet-bad3d2f5abd672dd67da510a73a03f28605bd386.tar.xz puppet-bad3d2f5abd672dd67da510a73a03f28605bd386.zip |
really add ssh::auth
Diffstat (limited to 'modules')
-rw-r--r-- | modules/ssh_auth/manifests/init.pp | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/modules/ssh_auth/manifests/init.pp b/modules/ssh_auth/manifests/init.pp new file mode 100644 index 00000000..08570add --- /dev/null +++ b/modules/ssh_auth/manifests/init.pp @@ -0,0 +1,336 @@ +# =========
+# ssh::auth
+# =========
+#
+# The latest official release and documentation for ssh::auth can always
+# be found at http://reductivelabs.com/trac/puppet/wiki/Recipes/ModuleSSHAuth .
+#
+# Version: 0.3.2
+# Release date: 2009-12-29
+
+class ssh::auth {
+
+$keymaster_storage = "/var/lib/keys"
+
+Exec { path => "/usr/bin:/usr/sbin:/bin:/sbin" }
+Notify { withpath => false }
+
+
+##########################################################################
+
+
+# ssh::auth::key
+
+# Declare keys. The approach here is just to define a bunch of
+# virtual resources, representing key files on the keymaster, client,
+# and server. The virtual keys are then realized by
+# ssh::auth::{keymaster,client,server}, respectively. The reason for
+# doing things that way is that it makes ssh::auth::key into a "one
+# stop shop" where users can declare their keys with all of their
+# parameters, whether those parameters apply to the keymaster, server,
+# or client. The real work of creating, installing, and removing keys
+# is done in the private definitions called by the virtual resources:
+# ssh_auth_key_{master,server,client}.
+
+define key ($ensure = "present", $filename = "", $force = false, $group = "puppet", $home = "", $keytype = "rsa", $length = 2048, $maxdays = "", $mindate = "", $options = "", $user = "") {
+
+ ssh_auth_key_namecheck { "${title}-title": parm => "title", value => $title }
+
+ # apply defaults
+ $_filename = $filename ? { "" => "id_${keytype}", default => $filename }
+ $_length = $keytype ? { "rsa" => $length, "dsa" => 1024 }
+ $_user = $user ? {
+ "" => regsubst($title, '^([^@]*)@?.*$', '\1'),
+ default => $user,
+ }
+ $_home = $home ? { "" => "/home/$_user", default => $home }
+
+ ssh_auth_key_namecheck { "${title}-filename": parm => "filename", value => $_filename }
+
+ @ssh_auth_key_master { $title:
+ ensure => $ensure,
+ force => $force,
+ keytype => $keytype,
+ length => $_length,
+ maxdays => $maxdays,
+ mindate => $mindate,
+ }
+ @ssh_auth_key_client { $title:
+ ensure => $ensure,
+ filename => $_filename,
+ group => $group,
+ home => $_home,
+ user => $_user,
+ }
+ @ssh_auth_key_server { $title:
+ ensure => $ensure,
+ group => $group,
+ home => $_home,
+ options => $options,
+ user => $_user,
+ }
+}
+
+
+##########################################################################
+
+
+# ssh::auth::keymaster
+#
+# Keymaster host:
+# Create key storage; create, regenerate, and remove key pairs
+
+class keymaster {
+
+ # Set up key storage
+
+ file { $ssh::auth::keymaster_storage:
+ ensure => directory,
+ owner => puppet,
+ group => puppet,
+ mode => 644,
+ }
+
+ # Realize all virtual master keys
+ Ssh_auth_key_master <| |>
+
+} # class keymaster
+
+
+##########################################################################
+
+
+# ssh::auth::client
+#
+# Install generated key pairs onto clients
+
+define client ($ensure = "", $filename = "", $group = "", $home = "", $user = "") {
+
+ # Realize the virtual client keys.
+ # Override the defaults set in ssh::auth::key, as needed.
+ if $ensure { Ssh_auth_key_client <| title == $title |> { ensure => $ensure } }
+ if $filename { Ssh_auth_key_client <| title == $title |> { filename => $filename } }
+ if $group { Ssh_auth_key_client <| title == $title |> { group => $group } }
+
+ if $user { Ssh_auth_key_client <| title == $title |> { user => $user, home => "/home/$user" } }
+ if $home { Ssh_auth_key_client <| title == $title |> { home => $home } }
+
+ realize Ssh_auth_key_client[$title]
+
+} # define client
+
+
+##########################################################################
+
+
+# ssh::auth::server
+#
+# Install public keys onto clients
+
+define server ($ensure = "", $group = "", $home = "", $options = "", $user = "") {
+
+ # Realize the virtual server keys.
+ # Override the defaults set in ssh::auth::key, as needed.
+ if $ensure { Ssh_auth_key_server <| title == $title |> { ensure => $ensure } }
+ if $group { Ssh_auth_key_server <| title == $title |> { group => $group } }
+ if $options { Ssh_auth_key_server <| title == $title |> { options => $options } }
+
+ if $user { Ssh_auth_key_server <| title == $title |> { user => $user, home => "/home/$user" } }
+ if $home { Ssh_auth_key_server <| title == $title |> { home => $home } }
+
+ realize Ssh_auth_key_server[$title]
+
+} # define server
+
+} # class ssh::auth
+
+
+##########################################################################
+
+
+# ssh_auth_key_master
+#
+# Create/regenerate/remove a key pair on the keymaster.
+# This definition is private, i.e. it is not intended to be called directly by users.
+# ssh::auth::key calls it to create virtual keys, which are realized in ssh::auth::keymaster.
+
+define ssh_auth_key_master ($ensure, $force, $keytype, $length, $maxdays, $mindate) {
+
+ Exec { path => "/usr/bin:/usr/sbin:/bin:/sbin" }
+ File {
+ owner => puppet,
+ group => puppet,
+ mode => 600,
+ }
+
+ $keydir = "${ssh::auth::keymaster_storage}/${title}"
+ $keyfile = "${keydir}/key"
+
+ file {
+ "$keydir":
+ ensure => directory,
+ mode => 644;
+ "$keyfile":
+ ensure => $ensure;
+ "${keyfile}.pub":
+ ensure => $ensure,
+ mode => 644;
+ }
+
+ if $ensure == "present" {
+
+ # Remove the existing key pair, if
+ # * $force is true, or
+ # * $maxdays or $mindate criteria aren't met, or
+ # * $keytype or $length have changed
+
+ $keycontent = file("${keyfile}.pub", "/dev/null")
+ if $keycontent {
+
+ if $force {
+ $reason = "force=true"
+ }
+ if !$reason and $mindate and generate("/usr/bin/find", $keyfile, "!", "-newermt", "${mindate}") {
+ $reason = "created before ${mindate}"
+ }
+ if !$reason and $maxdays and generate("/usr/bin/find", $keyfile, "-mtime", "+${maxdays}") {
+ $reason = "older than ${maxdays} days"
+ }
+ if !$reason and $keycontent =~ /^ssh-... [^ ]+ (...) (\d+)$/ {
+ if $keytype != $1 { $reason = "keytype changed: $1 -> $keytype" }
+ else { if $length != $2 { $reason = "length changed: $2 -> $length" } }
+ }
+ if $reason {
+ exec { "Revoke previous key ${title}: ${reason}":
+ command => "rm $keyfile ${keyfile}.pub",
+ before => Exec["Create key $title: $keytype, $length bits"],
+ }
+ }
+ }
+
+ # Create the key pair.
+ # We "repurpose" the comment field in public keys on the keymaster to
+ # store data about the key, i.e. $keytype and $length. This avoids
+ # having to rerun ssh-keygen -l on every key at every run to determine
+ # the key length.
+ exec { "Create key $title: $keytype, $length bits":
+ command => "ssh-keygen -t ${keytype} -b ${length} -f ${keyfile} -C \"${keytype} ${length}\" -N \"\"",
+ user => "puppet",
+ group => "puppet",
+ creates => $keyfile,
+ require => File[$keydir],
+ before => File[$keyfile, "${keyfile}.pub"],
+ }
+
+ } # if $ensure == "present"
+
+} # define ssh_auth_key_master
+
+
+##########################################################################
+
+
+# ssh_auth_key_client
+#
+# Install a key pair into a user's account.
+# This definition is private, i.e. it is not intended to be called directly by users.
+
+define ssh_auth_key_client ($ensure, $filename, $group, $home, $user) {
+
+ File {
+ owner => $user,
+ group => $group,
+ mode => 600,
+ require => [ User[$user], File[$home]],
+ }
+
+ $key_src_file = "${ssh::auth::keymaster_storage}/${title}/key" # on the keymaster
+ $key_tgt_file = "${home}/.ssh/${filename}" # on the client
+
+ $key_src_content_pub = file("${key_src_file}.pub", "/dev/null")
+ if $ensure == "absent" or $key_src_content_pub =~ /^(ssh-...) ([^ ]+)/ {
+ $keytype = $1
+ $modulus = $2
+ file {
+ $key_tgt_file:
+ ensure => $ensure,
+ content => file($key_src_file, "/dev/null");
+ "${key_tgt_file}.pub":
+ ensure => $ensure,
+ content => "$keytype $modulus $title\n",
+ mode => 644;
+ }
+ } else {
+ notify { "Private key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
+ }
+
+} # define ssh_auth_key_client
+
+
+##########################################################################
+
+
+# ssh_auth_key_server
+#
+# Install a public key into a server user's authorized_keys(5) file.
+# This definition is private, i.e. it is not intended to be called directly by users.
+
+define ssh_auth_key_server ($ensure, $group, $home, $options, $user) {
+
+ # on the keymaster:
+ $key_src_dir = "${ssh::auth::keymaster_storage}/${title}"
+ $key_src_file = "${key_src_dir}/key.pub"
+ # on the server:
+ $key_tgt_file = "${home}/.ssh/authorized_keys"
+
+ File {
+ owner => $user,
+ group => $group,
+ require => User[$user],
+ mode => 600,
+ }
+ Ssh_authorized_key {
+ user => $user,
+ target => $key_tgt_file,
+ }
+
+ if $ensure == "absent" {
+ ssh_authorized_key { $title: ensure => "absent" }
+ }
+ else {
+ $key_src_content = file($key_src_file, "/dev/null")
+ if ! $key_src_content {
+ notify { "Public key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
+ } else { if $ensure == "present" and $key_src_content !~ /^(ssh-...) ([^ ]*)/ {
+ err("Can't parse public key file $key_src_file")
+ notify { "Can't parse public key file $key_src_file for key $title on the keymaster: skipping ensure => $ensure": }
+ } else {
+ $keytype = $1
+ $modulus = $2
+ ssh_authorized_key { $title:
+ ensure => "present",
+ type => $keytype,
+ key => $modulus,
+ options => $options ? { "" => undef, default => $options },
+ }
+ }} # if ... else ... else
+ } # if ... else
+
+} # define ssh_auth_key_server
+
+
+##########################################################################
+
+
+# ssh_auth_key_namecheck
+#
+# Check a name (e.g. key title or filename) for the allowed form
+
+define ssh_auth_key_namecheck ($parm, $value) {
+ if $value !~ /^[A-Za-z0-9]/ {
+ fail("ssh::auth::key: $parm '$value' not allowed: must begin with a letter or digit")
+ }
+ if $value !~ /^[A-Za-z0-9_.:@-]+$/ {
+ fail("ssh::auth::key: $parm '$value' not allowed: may only contain the characters A-Za-z0-9_.:@-")
+ }
+} # define namecheck
|