From e249ba513bc97b06f7808373294c249aa14bbda1 Mon Sep 17 00:00:00 2001 From: Jamie McClelland Date: Tue, 29 Mar 2011 22:08:13 -0400 Subject: adding ability for monkeysphere user setup --- README | 66 +++++++++++++++------ manifests/init.pp | 119 ++++++++++++++++++++++++++++++++++---- templates/authorized_user_ids.erb | 6 ++ 3 files changed, 163 insertions(+), 28 deletions(-) create mode 100644 templates/authorized_user_ids.erb diff --git a/README b/README index cc44499..a1d3595 100644 --- a/README +++ b/README @@ -1,31 +1,61 @@ The monkeysphere puppet module is designed to help you manage your servers -using the monkeysphere[0]. +and users using the monkeysphere[0]. -Example usage: +Example usage for server setup: - # assuming you are using the sshd puppet module... + # Assuming you are using the sshd puppet module... $sshd_authorized_keys_file = "/var/lib/monkeysphere/authorized_keys/%u" include sshd - # import the generated ssh key into the server's gpg ring - include monkeysphere::import_key + # Optionally, indicate your preferred keyserver. You can specify a server + # under your control and not accessible to the public or + # pool.sks-keyservers.net if you want to publish to the public pool. The + # value you specify here will be used for all monkeysphere and gpg commands + $monkeysphere_keyserver = "zimmermann.mayfirst.org" + include monkeysphere - # add host names to the array below if you do not want them published to the - # web of trust - $monkeysphere_no_publish = [ "animal.mayfirst.org", "test.mayfirst.org" ] - include monkeysphere::publish_key + # Ensure the server's ssh key is imported into your monkeysphere key ring + monkeysphere::import_key { "main": } - # add the fingerprints of the gpgids that should be certifiers - monkeysphere::add_certifiers { dkg: - keyid => "0EE5BE979282D80B9F7540F1CCD2ED94D21739E9" - } - monkeysphere::add_certifiers { jamie: + # Optionally publish the server key to a keyserver (as indicated above) + monkeysphere::publish_server_keys { "main": } + + # Optionally email the server key to your self + monkeysphere::email_server_keys { "we@ourdomain.org": } + + # Be sure to sign the server's key! + + # Indiciate the fingerprint of the gpg key that should be used + # to verify user ids. You can repeat this for as many certifiers + # as you need + monkeysphere::add_id_certifier { "jamie": keyid => "1CB57C59F2F42470238F53ABBB0B7EE15F2E4935" } - - # add a authorized_user_ids file for the root user - monkeysphere::root_authorized_user_ids { main: - file => "puppet:///files/monkeysphere/root/authorized_user_ids" + + # Indicate who should have root access on the server + monkeysphere::authorized_user_ids { "root": + user_ids => [ "sarah " , "jose "0EE5BE979282D80B9F7540F1CCD2ED94D21739E9" + } + + 0. http://monkeysphere.info/ diff --git a/manifests/init.pp b/manifests/init.pp index 0487bb7..64331e8 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -69,7 +69,7 @@ define monkeysphere::import_key ( $scheme = 'ssh://', $port = '', $path = '/etc/ } # Server host key publication -define monkeysphere::publish_keys ( $keyid = '--all' ) { +define monkeysphere::publish_server_keys ( $keyid = '--all' ) { exec { "monkeysphere-host publish-keys $keyid": environment => "MONKEYSPHERE_PROMPT=false", require => [ Package["monkeysphere"], Exec["monkeysphere-import-key"], File["monkeysphere_host_conf"] ], @@ -77,7 +77,8 @@ define monkeysphere::publish_keys ( $keyid = '--all' ) { } # optionally, mail key somehwere -define monkeysphere::email_keys ( $email = 'root' ) { +define monkeysphere::email_server_keys ( ) { + $email = $title exec { "mail -s 'monkeysphere host pgp keys for $fqdn' $email < /var/lib/monkeysphere/host_keys.pub.pgp": require => [ Package["monkeysphere"], Exec["monkeysphere-import-key"] ], } @@ -92,28 +93,46 @@ define monkeysphere::add_id_certifier( $keyid ) { } } -define monkeysphere::authorized_user_ids( $source, $dest_dir = '/root/.monkeysphere', $dest_file = 'authorized_user_ids', $group = '') { +define monkeysphere::authorized_user_ids( $user_ids, $dest_dir = '/root/.monkeysphere', $dest_file = 'authorized_user_ids', $group = '') { $user = $title $calculated_group = $group ? { '' => $user, default => $group } - file { - $dest_dir: - owner => $user, - group => $calculated_group, - mode => 755, - ensure => directory, + # don't require user if it's root because root is not handled + # by puppet + case $user { + root: { + file { + $dest_dir: + owner => $user, + group => $calculated_group, + mode => 755, + ensure => directory, + } + } + default: { + file { + $dest_dir: + owner => $user, + group => $calculated_group, + mode => 755, + ensure => directory, + require => $require_user + } + } } + file { "${dest_dir}/${dest_file}": owner => $user, group => $calculated_group, mode => 644, - source => $source, + content => template('monkeysphere/authorized_user_ids.erb'), ensure => present, recurse => true, + require => File[$dest_dir] } exec { "monkeysphere-authentication update-users $user": @@ -122,3 +141,83 @@ define monkeysphere::authorized_user_ids( $source, $dest_dir = '/root/.monkeysp subscribe => File["${dest_dir}/${dest_file}"] } } + +# ensure that the user has a gpg key created and it is authentication capable +# in the monkeysphere. This is intended to be the same as generated a +# password-less ssh key +# +define monkeysphere::auth_capable_user ( $expire = "1y", $length = "2048", + $uid_name = undef, $email = undef ) { + + $user = $title + + # The goal is no passphrase, monkeysphere won't work without a passphrase. + $calculated_passphrase = $gpg_auto_password ? { + '' => 'monkeys', + default => $gpg_auto_password + } + + $calculated_name = $uid_name ? { + '' => "$user user", + default => $uid_name + } + $calculated_email = $email ? { + '' => "$user@$fqdn", + default => $email + } + exec { "monkeysphere-gen-key-$user": + command => "printf 'Key-Type: RSA\nKey-Length: 2048\nKey-Usage: encrypt,sign\nSubkey-Type: RSA\nSubkey-Length: 2048\nSubkey-Usage: encrypt\nName-Real: $calculated_name\nName-Email: $calculated_email\nPassphrase: $calculated_passphrase\nExpire-Date: 1y\n' | gpg --batch --gen-key", + require => [ Package["monkeysphere"] ], + user => $user, + unless => "gpg --list-secret-key | grep ^sec >/dev/null" + } + + #FIXME - we should check expiration date and extend it if we're < n days before expiration + + # handle auth subkey + exec { "monkeysphere-gen-subkey-$user": + command => "printf '$calculated_passphrase\n' | monkeysphere gen-subkey", + require => [ Package["monkeysphere"], Exec["monkeysphere-gen-key-$user" ] ], + user => $user, + unless => "gpg --list-key --with-colons $(gpg --list-secret-key --with-colons | grep ^sec | cut -d: -f5) | grep ^sub | cut -d: -f12 | grep a >/dev/null" + } + +} + +define monkeysphere::publish_user_key ( ){ + $user = $title + + $keyserver_arg = $monkeysphere_keyserver ? { + '' => '', + default => "--keyserver $monkeysphere_keyserver" + } + + exec { "monkeysphere-gpg-send-key-$user": + command => "gpg $keyserver_arg --send-key $(gpg --list-secret-key --with-colons | grep ^sec | cut -d: -f5)", + require => [ Package["monkeysphere"], Exec["monkeysphere-gen-key-$user" ] ], + user => $user, + } + +} + +define monkeysphere::owner_trust( $fingerprint, $user = 'root', $level = 6 ) { + $keyserver_arg = $monkeysphere_keyserver ? { + '' => '', + default => "--keyserver $monkeysphere_keyserver" + } + + # ensure the key is in the key ring + exec { "monkeysphere-gpg-recv-key-$user-$fingerprint": + command => "gpg $keyserver_arg --recv-key $fingerprint", + require => [ Package["monkeysphere"] ], + user => $user, + unless => "gpg --list-key $fingerprint 2>&1 >/dev/null" + } + # provide ownertrust + exec { "monkeysphere-gpg-ownertrust-$user-$fingerprint": + command => "printf '$fingerprint:$level\n'\$(gpg --export-ownertrust) | gpg --import-ownertrust", + require => [ Package["monkeysphere"] ], + user => $user, + unless => "gpg --export-ownertrust | grep $fingerprint >/dev/null" + } +} diff --git a/templates/authorized_user_ids.erb b/templates/authorized_user_ids.erb new file mode 100644 index 0000000..9313c6b --- /dev/null +++ b/templates/authorized_user_ids.erb @@ -0,0 +1,6 @@ +# This file is maintained by puppet, changes will be overwritten +<% if user_ids.is_a? String -%> +<%= user_ids %> +<% elsif user_ids.is_a? Array -%> +<%= user_ids.map { |i| "#{i}" }.join("\n") %> +<% end -%> -- cgit v1.2.3