/[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 380 - (hide annotations) (download)
Mon Nov 22 07:20:25 2010 UTC (13 years, 5 months ago) by blino
File size: 15354 byte(s)
home should be tested as a directory

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 blino 380 file { $home:
241     ensure => "directory",
242     }
243    
244 blino 367 File {
245     owner => $user,
246     group => $group,
247     mode => 600,
248     require => [ User[$user], File[$home]],
249     }
250    
251     $key_src_file = "${ssh::auth::keymaster_storage}/${title}/key" # on the keymaster
252     $key_tgt_file = "${home}/.ssh/${filename}" # on the client
253    
254     $key_src_content_pub = file("${key_src_file}.pub", "/dev/null")
255     if $ensure == "absent" or $key_src_content_pub =~ /^(ssh-...) ([^ ]+)/ {
256     $keytype = $1
257     $modulus = $2
258     file {
259     $key_tgt_file:
260     ensure => $ensure,
261     content => file($key_src_file, "/dev/null");
262     "${key_tgt_file}.pub":
263     ensure => $ensure,
264     content => "$keytype $modulus $title\n",
265     mode => 644;
266     }
267     } else {
268     notify { "Private key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
269     }
270    
271     } # define ssh_auth_key_client
272    
273    
274     ##########################################################################
275    
276    
277     # ssh_auth_key_server
278     #
279     # Install a public key into a server user's authorized_keys(5) file.
280     # This definition is private, i.e. it is not intended to be called directly by users.
281    
282     define ssh_auth_key_server ($ensure, $group, $home, $options, $user) {
283    
284     # on the keymaster:
285     $key_src_dir = "${ssh::auth::keymaster_storage}/${title}"
286     $key_src_file = "${key_src_dir}/key.pub"
287     # on the server:
288     $key_tgt_file = "${home}/.ssh/authorized_keys"
289    
290     File {
291     owner => $user,
292     group => $group,
293     require => User[$user],
294     mode => 600,
295     }
296     Ssh_authorized_key {
297     user => $user,
298     target => $key_tgt_file,
299     }
300    
301     if $ensure == "absent" {
302     ssh_authorized_key { $title: ensure => "absent" }
303     }
304     else {
305     $key_src_content = file($key_src_file, "/dev/null")
306     if ! $key_src_content {
307     notify { "Public key file $key_src_file for key $title not found on keymaster; skipping ensure => present": }
308     } else { if $ensure == "present" and $key_src_content !~ /^(ssh-...) ([^ ]*)/ {
309     err("Can't parse public key file $key_src_file")
310     notify { "Can't parse public key file $key_src_file for key $title on the keymaster: skipping ensure => $ensure": }
311     } else {
312     $keytype = $1
313     $modulus = $2
314     ssh_authorized_key { $title:
315     ensure => "present",
316     type => $keytype,
317     key => $modulus,
318     options => $options ? { "" => undef, default => $options },
319     }
320     }} # if ... else ... else
321     } # if ... else
322    
323     } # define ssh_auth_key_server
324    
325    
326     ##########################################################################
327    
328    
329     # ssh_auth_key_namecheck
330     #
331     # Check a name (e.g. key title or filename) for the allowed form
332    
333     define ssh_auth_key_namecheck ($parm, $value) {
334     if $value !~ /^[A-Za-z0-9]/ {
335     fail("ssh::auth::key: $parm '$value' not allowed: must begin with a letter or digit")
336     }
337     if $value !~ /^[A-Za-z0-9_.:@-]+$/ {
338     fail("ssh::auth::key: $parm '$value' not allowed: may only contain the characters A-Za-z0-9_.:@-")
339     }
340     } # define namecheck

  ViewVC Help
Powered by ViewVC 1.1.30