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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 368 - (show 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 # =========
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