/[adm]/puppet/modules/ssh/manifests/auth.pp
ViewVC logotype

Annotation of /puppet/modules/ssh/manifests/auth.pp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 368 - (hide annotations) (download)
Mon Nov 22 00:25:33 2010 UTC (13 years, 4 months ago) by blino
Original Path: puppet/modules/ssh/manifests/init.pp
File size: 15302 byte(s)
move modules/ssh_auth as modules/ssh
1 blino 367 # =========
2     # ssh::auth
3     # =========
4     #
5     # The latest official release and documentation for ssh::auth can always
6     # be found at http://reductivelabs.com/trac/puppet/wiki/Recipes/ModuleSSHAuth .
7     #
8     # Version: 0.3.2
9     # Release date: 2009-12-29
10    
11     class ssh::auth {
12    
13     $keymaster_storage = "/var/lib/keys"
14    
15     Exec { path => "/usr/bin:/usr/sbin:/bin:/sbin" }
16     Notify { withpath => false }
17    
18    
19     ##########################################################################
20    
21    
22     # ssh::auth::key
23    
24     # Declare keys. The approach here is just to define a bunch of
25     # virtual resources, representing key files on the keymaster, client,
26     # and server. The virtual keys are then realized by
27     # ssh::auth::{keymaster,client,server}, respectively. The reason for
28     # doing things that way is that it makes ssh::auth::key into a "one
29     # stop shop" where users can declare their keys with all of their
30     # parameters, whether those parameters apply to the keymaster, server,
31     # or client. The real work of creating, installing, and removing keys
32     # is done in the private definitions called by the virtual resources:
33     # ssh_auth_key_{master,server,client}.
34    
35     define key ($ensure = "present", $filename = "", $force = false, $group = "puppet", $home = "", $keytype = "rsa", $length = 2048, $maxdays = "", $mindate = "", $options = "", $user = "") {
36    
37     ssh_auth_key_namecheck { "${title}-title": parm => "title", value => $title }
38    
39     # apply defaults
40     $_filename = $filename ? { "" => "id_${keytype}", default => $filename }
41     $_length = $keytype ? { "rsa" => $length, "dsa" => 1024 }
42     $_user = $user ? {
43     "" => regsubst($title, '^([^@]*)@?.*$', '\1'),
44     default => $user,
45     }
46     $_home = $home ? { "" => "/home/$_user", default => $home }
47    
48     ssh_auth_key_namecheck { "${title}-filename": parm => "filename", value => $_filename }
49    
50     @ssh_auth_key_master { $title:
51     ensure => $ensure,
52     force => $force,
53     keytype => $keytype,
54     length => $_length,
55     maxdays => $maxdays,
56     mindate => $mindate,
57     }
58     @ssh_auth_key_client { $title:
59     ensure => $ensure,
60     filename => $_filename,
61     group => $group,
62     home => $_home,
63     user => $_user,
64     }
65     @ssh_auth_key_server { $title:
66     ensure => $ensure,
67     group => $group,
68     home => $_home,
69     options => $options,
70     user => $_user,
71     }
72     }
73    
74    
75     ##########################################################################
76    
77    
78     # ssh::auth::keymaster
79     #
80     # Keymaster host:
81     # Create key storage; create, regenerate, and remove key pairs
82    
83     class keymaster {
84    
85     # Set up key storage
86    
87     file { $ssh::auth::keymaster_storage:
88     ensure => directory,
89     owner => puppet,
90     group => puppet,
91     mode => 644,
92     }
93    
94     # Realize all virtual master keys
95     Ssh_auth_key_master <| |>
96    
97     } # class keymaster
98    
99    
100     ##########################################################################
101    
102    
103     # ssh::auth::client
104     #
105     # Install generated key pairs onto clients
106    
107     define client ($ensure = "", $filename = "", $group = "", $home = "", $user = "") {
108    
109     # Realize the virtual client keys.
110     # Override the defaults set in ssh::auth::key, as needed.
111     if $ensure { Ssh_auth_key_client <| title == $title |> { ensure => $ensure } }
112     if $filename { Ssh_auth_key_client <| title == $title |> { filename => $filename } }
113     if $group { Ssh_auth_key_client <| title == $title |> { group => $group } }
114    
115     if $user { Ssh_auth_key_client <| title == $title |> { user => $user, home => "/home/$user" } }
116     if $home { Ssh_auth_key_client <| title == $title |> { home => $home } }
117    
118     realize Ssh_auth_key_client[$title]
119    
120     } # define client
121    
122    
123     ##########################################################################
124    
125    
126     # ssh::auth::server
127     #
128     # Install public keys onto clients
129    
130     define server ($ensure = "", $group = "", $home = "", $options = "", $user = "") {
131    
132     # Realize the virtual server keys.
133     # Override the defaults set in ssh::auth::key, as needed.
134     if $ensure { Ssh_auth_key_server <| title == $title |> { ensure => $ensure } }
135     if $group { Ssh_auth_key_server <| title == $title |> { group => $group } }
136     if $options { Ssh_auth_key_server <| title == $title |> { options => $options } }
137    
138     if $user { Ssh_auth_key_server <| title == $title |> { user => $user, home => "/home/$user" } }
139     if $home { Ssh_auth_key_server <| title == $title |> { home => $home } }
140    
141     realize Ssh_auth_key_server[$title]
142    
143     } # define server
144    
145     } # class ssh::auth
146    
147    
148     ##########################################################################
149    
150    
151     # ssh_auth_key_master
152     #
153     # Create/regenerate/remove a key pair on the keymaster.
154     # This definition is private, i.e. it is not intended to be called directly by users.
155     # ssh::auth::key calls it to create virtual keys, which are realized in ssh::auth::keymaster.
156    
157     define ssh_auth_key_master ($ensure, $force, $keytype, $length, $maxdays, $mindate) {
158    
159     Exec { path => "/usr/bin:/usr/sbin:/bin:/sbin" }
160     File {
161     owner => puppet,
162     group => puppet,
163     mode => 600,
164     }
165    
166     $keydir = "${ssh::auth::keymaster_storage}/${title}"
167     $keyfile = "${keydir}/key"
168    
169     file {
170     "$keydir":
171     ensure => directory,
172     mode => 644;
173     "$keyfile":
174     ensure => $ensure;
175     "${keyfile}.pub":
176     ensure => $ensure,
177     mode => 644;
178     }
179    
180     if $ensure == "present" {
181    
182     # Remove the existing key pair, if
183     # * $force is true, or
184     # * $maxdays or $mindate criteria aren't met, or
185     # * $keytype or $length have changed
186    
187     $keycontent = file("${keyfile}.pub", "/dev/null")
188     if $keycontent {
189    
190     if $force {
191     $reason = "force=true"
192     }
193     if !$reason and $mindate and generate("/usr/bin/find", $keyfile, "!", "-newermt", "${mindate}") {
194     $reason = "created before ${mindate}"
195     }
196     if !$reason and $maxdays and generate("/usr/bin/find", $keyfile, "-mtime", "+${maxdays}") {
197     $reason = "older than ${maxdays} days"
198     }
199     if !$reason and $keycontent =~ /^ssh-... [^ ]+ (...) (\d+)$/ {
200     if $keytype != $1 { $reason = "keytype changed: $1 -> $keytype" }
201     else { if $length != $2 { $reason = "length changed: $2 -> $length" } }
202     }
203     if $reason {
204     exec { "Revoke previous key ${title}: ${reason}":
205     command => "rm $keyfile ${keyfile}.pub",
206     before => Exec["Create key $title: $keytype, $length bits"],
207     }
208     }
209     }
210    
211     # Create the key pair.
212     # We "repurpose" the comment field in public keys on the keymaster to
213     # store data about the key, i.e. $keytype and $length. This avoids
214     # having to rerun ssh-keygen -l on every key at every run to determine
215     # the key length.
216     exec { "Create key $title: $keytype, $length bits":
217     command => "ssh-keygen -t ${keytype} -b ${length} -f ${keyfile} -C \"${keytype} ${length}\" -N \"\"",
218     user => "puppet",
219     group => "puppet",
220     creates => $keyfile,
221     require => File[$keydir],
222     before => File[$keyfile, "${keyfile}.pub"],
223     }
224    
225     } # if $ensure == "present"
226    
227     } # define ssh_auth_key_master
228    
229    
230     ##########################################################################
231    
232    
233     # ssh_auth_key_client
234     #
235     # Install a key pair into a user's account.
236     # This definition is private, i.e. it is not intended to be called directly by users.
237    
238     define ssh_auth_key_client ($ensure, $filename, $group, $home, $user) {
239    
240     File {
241     owner => $user,
242     group => $group,
243     mode => 600,
244     require => [ User[$user], File[$home]],
245     }
246    
247     $key_src_file = "${ssh::auth::keymaster_storage}/${title}/key" # on the keymaster
248     $key_tgt_file = "${home}/.ssh/${filename}" # on the client
249    
250     $key_src_content_pub = file("${key_src_file}.pub", "/dev/null")
251     if $ensure == "absent" or $key_src_content_pub =~ /^(ssh-...) ([^ ]+)/ {
252     $keytype = $1
253     $modulus = $2
254     file {
255     $key_tgt_file:
256     ensure => $ensure,
257     content => file($key_src_file, "/dev/null");
258     "${key_tgt_file}.pub":
259     ensure => $ensure,
260     content => "$keytype $modulus $title\n",
261     mode => 644;
262     }
263     } else {
264     notify { "Private key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
265     }
266    
267     } # define ssh_auth_key_client
268    
269    
270     ##########################################################################
271    
272    
273     # ssh_auth_key_server
274     #
275     # Install a public key into a server user's authorized_keys(5) file.
276     # This definition is private, i.e. it is not intended to be called directly by users.
277    
278     define ssh_auth_key_server ($ensure, $group, $home, $options, $user) {
279    
280     # on the keymaster:
281     $key_src_dir = "${ssh::auth::keymaster_storage}/${title}"
282     $key_src_file = "${key_src_dir}/key.pub"
283     # on the server:
284     $key_tgt_file = "${home}/.ssh/authorized_keys"
285    
286     File {
287     owner => $user,
288     group => $group,
289     require => User[$user],
290     mode => 600,
291     }
292     Ssh_authorized_key {
293     user => $user,
294     target => $key_tgt_file,
295     }
296    
297     if $ensure == "absent" {
298     ssh_authorized_key { $title: ensure => "absent" }
299     }
300     else {
301     $key_src_content = file($key_src_file, "/dev/null")
302     if ! $key_src_content {
303     notify { "Public key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
304     } else { if $ensure == "present" and $key_src_content !~ /^(ssh-...) ([^ ]*)/ {
305     err("Can't parse public key file $key_src_file")
306     notify { "Can't parse public key file $key_src_file for key $title on the keymaster: skipping ensure => $ensure": }
307     } else {
308     $keytype = $1
309     $modulus = $2
310     ssh_authorized_key { $title:
311     ensure => "present",
312     type => $keytype,
313     key => $modulus,
314     options => $options ? { "" => undef, default => $options },
315     }
316     }} # if ... else ... else
317     } # if ... else
318    
319     } # define ssh_auth_key_server
320    
321    
322     ##########################################################################
323    
324    
325     # ssh_auth_key_namecheck
326     #
327     # Check a name (e.g. key title or filename) for the allowed form
328    
329     define ssh_auth_key_namecheck ($parm, $value) {
330     if $value !~ /^[A-Za-z0-9]/ {
331     fail("ssh::auth::key: $parm '$value' not allowed: must begin with a letter or digit")
332     }
333     if $value !~ /^[A-Za-z0-9_.:@-]+$/ {
334     fail("ssh::auth::key: $parm '$value' not allowed: may only contain the characters A-Za-z0-9_.:@-")
335     }
336     } # define namecheck

  ViewVC Help
Powered by ViewVC 1.1.30