aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README68
-rw-r--r--files/etc/cron.d/update-monkeysphere-auth1
-rw-r--r--lib/facter/monkeysphere.rb2
-rw-r--r--manifests/add_id_certifier.pp8
-rw-r--r--manifests/auth_capable_user.pp44
-rw-r--r--manifests/authorized_user_ids.pp53
-rw-r--r--manifests/email_server_keys.pp9
-rw-r--r--manifests/import_key.pp20
-rw-r--r--manifests/init.pp70
-rw-r--r--manifests/owner_trust.pp25
-rw-r--r--manifests/publish_server_keys.pp7
-rw-r--r--manifests/publish_user_key.pp15
-rw-r--r--manifests/sshserver.pp10
-rw-r--r--templates/authorized_user_ids.erb6
-rw-r--r--templates/monkeysphere-authentication.conf.erb37
-rw-r--r--templates/monkeysphere-host.conf.erb15
-rw-r--r--templates/monkeysphere.conf.erb39
17 files changed, 372 insertions, 57 deletions
diff --git a/README b/README
index 569e512..e5f72e9 100644
--- a/README
+++ b/README
@@ -1,21 +1,65 @@
-puppet module for monkeysphere
+The monkeysphere puppet module is designed to help you manage your servers
+and users using the monkeysphere[0].
-for information about monkeysphere, see http://web.monkeysphere.info/
+To install the monkeypshere module, storeconfigs should be enabled in
+your puppet server to use certain features. See:
-To install the monkeypshere module:
+http://projects.puppetlabs.com/projects/1/wiki/Using_Stored_Configuration#Configuring+basic+storeconfigs
-* storeconfigs should be enabled in your puppet server to use certain features.
- see: http://projects.puppetlabs.com/projects/1/wiki/Using_Stored_Configuration#Configuring+basic+storeconfigs
+Example usage for server setup:
-* in node definitions that should export a ssh host key via
- monkeyshere, add:
+ # Assuming you are using the sshd puppet module...
+ $sshd_authorized_keys_file = "/var/lib/monkeysphere/authorized_keys/%u"
+ include sshd
- include monkeysphere::sshserver
+ # 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
-* You can specify pgpids of identity certifiers:
+ # Ensure the server's ssh key is imported into your monkeysphere key ring
+ monkeysphere::import_key { "main": }
- identity_certifier { "A3AE44A4":
- ensure => present
+ # 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"
+ }
+
+ # Indicate who should have root access on the server
+ monkeysphere::authorized_user_ids { "root":
+ user_ids => [ "sarah <sarah@ourgroup.org>" , "jose <josue@ourgroup.org" ]
+ }
+
+In addition, you may want to create a password-less key for a user to use
+when logging into another server (e.g. if you want automated backups from
+one server to another).
+
+Example usage for user setup:
+
+ # Ensure that the root user has authentication capable
+ # monkeysphere key
+ monkeysphere::auth_capable_user { "root": }
+
+ # Optionally publish the key
+ monkeysphere::publish_user_key { "root": }
+
+ # Grant full trust to a gpg key so the root user can properly
+ # authenticate servers to which it connects
+ # You can run this as many times as you want
+ monkeysphere::owner_trust { "jamie":
+ fingerprint => "0EE5BE979282D80B9F7540F1CCD2ED94D21739E9"
}
A host can be configured as a host you would use to sign the gpg keys by placing:
@@ -26,3 +70,5 @@ into the node definition. ON this host, a file will be placed in
/var/lib/puppet/modules/monkeysphere/hosts for each host configured as a
sshserver. Each file will contin the gpg id, the gpg fingerprint, and
the ssh fingerprint of the sshserver.
+
+0. http://monkeysphere.info/
diff --git a/files/etc/cron.d/update-monkeysphere-auth b/files/etc/cron.d/update-monkeysphere-auth
deleted file mode 100644
index 06bb5ae..0000000
--- a/files/etc/cron.d/update-monkeysphere-auth
+++ /dev/null
@@ -1 +0,0 @@
-*/5 * * * * root /usr/sbin/monkeysphere-authentication update-users
diff --git a/lib/facter/monkeysphere.rb b/lib/facter/monkeysphere.rb
index 1d7d68e..6f48a4d 100644
--- a/lib/facter/monkeysphere.rb
+++ b/lib/facter/monkeysphere.rb
@@ -5,7 +5,7 @@ ssh_fingerprint = ' '
if File.exist?('/usr/sbin/monkeysphere-host')
- sk = %x{/usr/sbin/monkeysphere-host show-keys}
+ sk = %x{/usr/sbin/monkeysphere-host show-keys 2>/dev/null}
if $? == 0
has_hostkey = true
sk.lines.each do |line|
diff --git a/manifests/add_id_certifier.pp b/manifests/add_id_certifier.pp
new file mode 100644
index 0000000..726551e
--- /dev/null
+++ b/manifests/add_id_certifier.pp
@@ -0,0 +1,8 @@
+# add certifiers
+define monkeysphere::add_id_certifier( $keyid ) {
+ exec { "monkeysphere-authentication add-id-certifier $keyid":
+ environment => "MONKEYSPHERE_PROMPT=false",
+ require => [ Package["monkeysphere"], File["monkeysphere_authentication_conf"] ],
+ unless => "/usr/sbin/monkeysphere-authentication list-id-certifiers | grep $keyid > /dev/null"
+ }
+}
diff --git a/manifests/auth_capable_user.pp b/manifests/auth_capable_user.pp
new file mode 100644
index 0000000..497407c
--- /dev/null
+++ b/manifests/auth_capable_user.pp
@@ -0,0 +1,44 @@
+# 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"
+ }
+
+}
diff --git a/manifests/authorized_user_ids.pp b/manifests/authorized_user_ids.pp
new file mode 100644
index 0000000..09fd182
--- /dev/null
+++ b/manifests/authorized_user_ids.pp
@@ -0,0 +1,53 @@
+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
+ }
+
+ # 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 => User[$user]
+ }
+ }
+ }
+
+ file {
+ "${dest_dir}/${dest_file}":
+ owner => $user,
+ group => $calculated_group,
+ mode => 644,
+ content => template('monkeysphere/authorized_user_ids.erb'),
+ ensure => present,
+ recurse => true,
+ require => File[$dest_dir]
+ }
+
+ exec { "monkeysphere-authentication update-users $user":
+ refreshonly => true,
+ require => [ File["monkeysphere_authentication_conf"], Package["monkeysphere"] ],
+ subscribe => File["${dest_dir}/${dest_file}"]
+ }
+}
diff --git a/manifests/email_server_keys.pp b/manifests/email_server_keys.pp
new file mode 100644
index 0000000..0a0bd4b
--- /dev/null
+++ b/manifests/email_server_keys.pp
@@ -0,0 +1,9 @@
+# optionally, mail key somehwere
+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"],
+ subscribe => Exec["monkeysphere-import-key"],
+ refreshonly => true,
+ }
+}
diff --git a/manifests/import_key.pp b/manifests/import_key.pp
new file mode 100644
index 0000000..ba965ce
--- /dev/null
+++ b/manifests/import_key.pp
@@ -0,0 +1,20 @@
+define monkeysphere::import_key (
+ $scheme = 'ssh://',
+ $port = '',
+ $path = '/etc/ssh/ssh_host_rsa_key',
+ $hostname = $fqdn ) {
+
+ # if we're getting a port number, prefix with a colon so it's valid
+ $prefixed_port = $port ? {
+ '' => '',
+ default => ":$port"
+ }
+
+ $key = "${scheme}${fqdn}${prefixed_port}"
+
+ exec { "monkeysphere-host import-key $path $key":
+ alias => "monkeysphere-import-key",
+ require => [ Package["monkeysphere"], File["monkeysphere_host_conf"] ],
+ unless => "/usr/sbin/monkeysphere-host s | grep $key > /dev/null"
+ }
+}
diff --git a/manifests/init.pp b/manifests/init.pp
index 6885b45..31c341d 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -19,56 +19,50 @@
#
# Class for monkeysphere management
#
+
class monkeysphere(
$ssh_port = '',
- $publish_key = false,
- $ensure_version = 'installed'
+ $ensure_version = 'installed',
+ # if not false, will override the path for MONKEYSPHERE_RAW_AUTHORIZED_KEYS
+ # use 'none' to disable appending the authorized_keys file
+ # see monkeysphere-authentication for more information
+ $raw_authorized_keys = false,
+ $keyserver = 'pool.sks-keyservers.net'
) {
# The needed packages
- package{'monkeysphere':
+ package { 'monkeysphere':
ensure => $ensure_version,
}
- $port = $monkeysphere::ssh_port ? {
- '' => '',
- default => ":${monkeysphere::ssh_port}",
- }
-
$key = "ssh://${::fqdn}${port}"
- common::module_dir { [ 'monkeysphere', 'monkeysphere/hosts', 'monkeysphere/plugins' ]: }
+ modules_dir { [ 'monkeysphere', 'monkeysphere/hosts', 'monkeysphere/plugins' ]: }
+
file {
+ # This was the old way which the module checked monkeysphere keys
'/usr/local/sbin/monkeysphere-check-key':
- ensure => present,
+ ensure => absent,
owner => root,
group => root,
- mode => '0755',
- content => "#!/bin/bash\n/usr/bin/gpg --homedir /var/lib/monkeysphere/host --list-keys '=${key}' &> /dev/null || false",
- }
-
- # Server host key publication
- Exec{
- unless => '/usr/local/sbin/monkeysphere-check-key',
- user => 'root',
- require => [ Package['monkeysphere'], File['/usr/local/sbin/monkeysphere-check-key'] ],
- }
- case $monkeysphere::publish_key {
- false: {
- exec { "/usr/sbin/monkeysphere-host import-key /etc/ssh/ssh_host_rsa_key ${key}": }
- }
- 'mail': {
- $mail_loc = $::operatingsystem ? {
- 'centos' => '/bin/mail',
- default => '/usr/bin/mail',
- }
- exec { "/usr/sbin/monkeysphere-host import-key /etc/ssh/ssh_host_rsa_key ${key} && \
- ${mail_loc} -s 'monkeysphere host pgp key for ${::fqdn}' root < /var/lib/monkeysphere/host_keys.pub.pgp":
- }
- }
- default: {
- exec { "/usr/sbin/monkeysphere-host import-key /etc/ssh/ssh_host_rsa_key ${key} && \
- echo Y | /usr/sbin/monkeysphere-host publish-key":
- }
- }
+ mode => 0755,
+ content => "#!/bin/bash\n/usr/bin/gpg --homedir /var/lib/monkeysphere/host --list-keys '=$key' &> /dev/null || false";
+ 'monkeysphere_conf':
+ path => '/etc/monkeysphere/monkeysphere.conf',
+ mode => 644,
+ ensure => present,
+ content => template('monkeysphere/monkeysphere.conf.erb'),
+ require => Package['monkeysphere'];
+ 'monkeysphere_host_conf':
+ path => '/etc/monkeysphere/monkeysphere-host.conf',
+ mode => 644,
+ ensure => present,
+ content => template('monkeysphere/monkeysphere-host.conf.erb'),
+ require => Package['monkeysphere'];
+ 'monkeysphere_authentication_conf':
+ path => '/etc/monkeysphere/monkeysphere-authentication.conf',
+ mode => 644,
+ ensure => present,
+ content => template('monkeysphere/monkeysphere-authentication.conf.erb'),
+ require => Package['monkeysphere'];
}
}
diff --git a/manifests/owner_trust.pp b/manifests/owner_trust.pp
new file mode 100644
index 0000000..0e0af7f
--- /dev/null
+++ b/manifests/owner_trust.pp
@@ -0,0 +1,25 @@
+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/manifests/publish_server_keys.pp b/manifests/publish_server_keys.pp
new file mode 100644
index 0000000..33e070e
--- /dev/null
+++ b/manifests/publish_server_keys.pp
@@ -0,0 +1,7 @@
+# Server host key publication
+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"] ];
+ }
+}
diff --git a/manifests/publish_user_key.pp b/manifests/publish_user_key.pp
new file mode 100644
index 0000000..f76c408
--- /dev/null
+++ b/manifests/publish_user_key.pp
@@ -0,0 +1,15 @@
+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,
+ }
+
+}
diff --git a/manifests/sshserver.pp b/manifests/sshserver.pp
index 43c0f6f..a525b55 100644
--- a/manifests/sshserver.pp
+++ b/manifests/sshserver.pp
@@ -10,12 +10,10 @@ class monkeysphere::sshserver {
}
}
- file{'/etc/cron.d/update-monkeysphere-auth':
- ensure => present,
- source => 'puppet:///modules/monkeysphere/etc/cron.d/update-monkeysphere-auth',
+ cron {'update-monkeysphere-auth':
+ command => '/usr/sbin/monkeysphere-authentication update-users > /dev/null 2>&1',
+ user => root,
+ minute => fqdn_rand(60),
require => Package['monkeysphere'],
- mode => '0644',
- owner => root,
- group => root,
}
}
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 -%>
diff --git a/templates/monkeysphere-authentication.conf.erb b/templates/monkeysphere-authentication.conf.erb
new file mode 100644
index 0000000..b489a68
--- /dev/null
+++ b/templates/monkeysphere-authentication.conf.erb
@@ -0,0 +1,37 @@
+# Monkeysphere authentication configuration file.
+
+# This is an sh-style shell configuration file. Variable names should
+# be separated from their assignments by a single '=' and no spaces.
+# Environment variables with the same names as these variables but
+# prefaced by "MONKEYSPHERE_" will take precedence over the values
+# specified here.
+
+# Log level. Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
+# increasing order of verbosity.
+#LOG_LEVEL=INFO
+
+# OpenPGP keyserver
+#KEYSERVER=pool.sks-keyservers.net
+<%= 'KEYSERVER='+keyserver if keyserver and keyserver != 'pool.sks-keyservers.net' %>
+# User who controls the monkeysphere 'sphere' keyring.
+#MONKEYSPHERE_USER=monkeysphere
+
+# Whether or not to query keyservers by default
+#CHECK_KEYSERVER=true
+
+# Path to authorized_user_ids file to process to create
+# authorized_keys file. '%h' will be replaced by the home directory
+# of the user, and '%u' will be replaced by the username of the user.
+# For purely admin-controlled authorized_user_ids, you might put them
+# in /etc/monkeysphere/authorized_user_ids/%u, for instance.
+#AUTHORIZED_USER_IDS="%h/.monkeysphere/authorized_user_ids"
+
+# Path to a user controlled authorized_keys file to be added to the
+# monkeysphere-generated authorized_keys file. '%h' will be replaced
+# by the home directory of the user, and '%u' will by replaced by the
+# username of the user. Setting this variable to 'none' prevents the
+# inclusion of user controlled authorized_keys file.
+#RAW_AUTHORIZED_KEYS="%h/.ssh/authorized_keys"
+<% if @raw_authorized_keys -%>
+RAW_AUTHORIZED_KEYS=<%= @raw_authorized_keys -%>
+<% end -%>
diff --git a/templates/monkeysphere-host.conf.erb b/templates/monkeysphere-host.conf.erb
new file mode 100644
index 0000000..418c696
--- /dev/null
+++ b/templates/monkeysphere-host.conf.erb
@@ -0,0 +1,15 @@
+# Monkeysphere host configuration file.
+
+# This is an sh-style shell configuration file. Variable names should
+# be separated from their assignments by a single '=' and no spaces.
+# Environment variables with the same names as these variables but
+# prefaced by "MONKEYSPHERE_" will take precedence over the values
+# specified here.
+
+# Log level. Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
+# increasing order of verbosity.
+#LOG_LEVEL=INFO
+
+# OpenPGP keyserver
+#KEYSERVER=pool.sks-keyservers.net
+<%= 'KEYSERVER='+keyserver if keyserver and keyserver != 'pool.sks-keyservers.net' %>
diff --git a/templates/monkeysphere.conf.erb b/templates/monkeysphere.conf.erb
new file mode 100644
index 0000000..53e4b9e
--- /dev/null
+++ b/templates/monkeysphere.conf.erb
@@ -0,0 +1,39 @@
+# Monkeysphere system-wide client configuration file.
+
+# This is an sh-style shell configuration file. Variable names should
+# be separated from their assignments by a single '=' and no spaces.
+# Environment variables with the same names as these variables but
+# prefaced by "MONKEYSPHERE_" will take precedence over the values
+# specified here.
+
+# Log level. Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
+# increasing order of verbosity.
+#LOG_LEVEL=INFO
+
+# GPG home directory. If not specified either here or in the
+# MONKEYSPHERE_GNUPGHOME environment variable, then the value of the
+# GNUPGHOME environment variable will be used. If GNUPGHOME is not
+# set either, then the default value is listed below.
+#GNUPGHOME=~/.gnupg
+
+# GPG keyserver to search for keys.
+#KEYSERVER=pool.sks-keyservers.net
+<%= 'KEYSERVER='+keyserver if keyserver and keyserver != 'pool.sks-keyservers.net' %>
+# Set whether or not to check keyservers at every monkeysphere
+# interaction, including all ssh connections if you use the
+# monkeysphere ssh-proxycommand. Leave unset for default behavior
+# (see KEYSERVER CHECKING in monkeysphere(1)), or set to true or false.
+# NOTE: setting CHECK_KEYSERVER explicitly to true will leak
+# information about the timing and frequency of your ssh connections
+# to the maintainer of the keyserver.
+#CHECK_KEYSERVER=true
+
+# The path to the SSH known_hosts file.
+#KNOWN_HOSTS=~/.ssh/known_hosts
+
+# Whether or not to hash the generated known_hosts lines.
+# Should be "true" or "false".
+#HASH_KNOWN_HOSTS=false
+
+# The path to the SSH authorized_keys file.
+#AUTHORIZED_KEYS=~/.ssh/authorized_keys