init.pp 12 KB
Newer Older
1
# Base class to install FreeRADIUS
2
class freeradius (
3
4
5
6
7
8
9
  $control_socket  = false,
  $max_servers     = '4096',
  $max_requests    = '4096',
  $mysql_support   = false,
  $perl_support    = false,
  $utils_support   = false,
  $ldap_support    = false,
10
  $krb5_support    = false,
11
12
  $wpa_supplicant  = false,
  $winbind_support = false,
13
  $log_destination = 'files',
14
  $syslog          = false,
15
  $log_auth        = 'no',
16
  $preserve_mods   = true,
17
18
) inherits freeradius::params {

19
  validate_re($freeradius::fr_version, '^3', 'This module is only compatible with FreeRADIUS 3')
20

21
22
23
  validate_re($log_destination, '^(files|syslog|stdout|stderr)$',
    "log_destination value (${log_destination}) is not a valid value")

24
  if $control_socket == true {
Jonathan Gazeley's avatar
Jonathan Gazeley committed
25
    warning('Use of the control_socket parameter in the freeradius class is deprecated. Please use the freeradius::control_socket class instead.')
26
27
  }

28
  file { 'radiusd.conf':
29
    name    => "${freeradius::fr_basepath}/radiusd.conf",
30
31
    mode    => '0640',
    owner   => 'root',
32
    group   => $freeradius::fr_group,
Jonathan Gazeley's avatar
Jonathan Gazeley committed
33
    content => template('freeradius/radiusd.conf.erb'),
34
35
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
36
  }
37

38
39
  # Create various directories
  file { [
40
41
42
43
44
45
46
47
    "${freeradius::fr_basepath}/statusclients.d",
    $freeradius::fr_basepath,
    "${freeradius::fr_basepath}/conf.d",
    "${freeradius::fr_basepath}/attr.d",
    "${freeradius::fr_basepath}/users.d",
    "${freeradius::fr_basepath}/policy.d",
    "${freeradius::fr_basepath}/dictionary.d",
    "${freeradius::fr_basepath}/scripts",
48
  ]:
49
50
51
    ensure  => directory,
    mode    => '0750',
    owner   => 'root',
52
53
54
    group   => $freeradius::fr_group,
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
55
56
  }

57
  # Create these directories separately so we can set purge option
58
  # Anything in these dirs NOT managed by puppet will be removed!
59
60
61
  file { [
    "${freeradius::fr_basepath}/certs",
    "${freeradius::fr_basepath}/clients.d",
62
    "${freeradius::fr_basepath}/sites-enabled",
63
    "${freeradius::fr_basepath}/mods-enabled",
Jonathan Gazeley's avatar
Jonathan Gazeley committed
64
    "${freeradius::fr_basepath}/instantiate",
65
  ]:
66
67
68
69
70
71
72
73
74
75
    ensure  => directory,
    purge   => true,
    recurse => true,
    mode    => '0750',
    owner   => 'root',
    group   => $freeradius::fr_group,
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
  }

76
  # Preserve some stock modules
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  if ($preserve_mods) {
    freeradius::module { [
      'always',
      'cache_eap',
      'chap',
      'detail',
      'detail.log',
      'dhcp',
      'digest',
      'dynamic_clients',
      'echo',
      'exec',
      'expiration',
      'expr',
      'files',
      'linelog',
      'logintime',
      'mschap',
      'ntlm_auth',
      'pap',
      'passwd',
      'preprocess',
      'radutmp',
      'realm',
      'replicate',
      'soh',
      'sradutmp',
      'unix',
      'unpack',
      'utf8',
    ]:
      preserve => true,
    }
110
111
112
  }


113
114
  # Set up concat policy file, as there is only one global policy
  # We also add standard header and footer
115
  concat { "${freeradius::fr_basepath}/policy.conf":
116
    owner   => 'root',
117
    group   => $freeradius::fr_group,
118
    mode    => '0640',
119
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
120
    notify  => Service[$freeradius::fr_service],
121
122
  }
  concat::fragment { 'policy_header':
123
    target  => "${freeradius::fr_basepath}/policy.conf",
124
125
126
127
    content => "policy {\n",
    order   => 10,
  }
  concat::fragment { 'policy_footer':
128
    target  => "${freeradius::fr_basepath}/policy.conf",
129
130
131
132
    content => "}\n",
    order   => '99',
  }

133
  # Set up concat template file
Jonathan Gazeley's avatar
Jonathan Gazeley committed
134
  concat { "${freeradius::fr_basepath}/templates.conf":
135
136
137
138
139
140
141
    owner   => 'root',
    group   => $freeradius::fr_group,
    mode    => '0640',
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
  }
  concat::fragment { 'template_header':
142
143
144
145
146
    target => "${freeradius::fr_basepath}/templates.conf",
    source => 'puppet:///modules/freeradius/template.header',
    order  => '05',
  }
  concat::fragment { 'template_footer':
Jonathan Gazeley's avatar
Jonathan Gazeley committed
147
    target  => "${freeradius::fr_basepath}/templates.conf",
148
149
    content => "}\n",
    order   => '95',
150
151
  }

152

153
154
155
156
157
158
159
160
  # Set up concat proxy file
  concat { "${freeradius::fr_basepath}/proxy.conf":
    owner   => 'root',
    group   => $freeradius::fr_group,
    mode    => '0640',
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
  }
161
162
163
  concat::fragment { 'proxy_header':
    target  => "${freeradius::fr_basepath}/proxy.conf",
    content => "# Proxy config\n\n",
164
    order   => '05',
165
  }
166

167
168
169
170
171
172
173
174
175
  # Set up attribute filter file
  concat { "${freeradius::fr_modulepath}/attr_filter":
    owner   => 'root',
    group   => $freeradius::fr_group,
    mode    => '0640',
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
  }

176
  # Install default attribute filters
Jonathan Gazeley's avatar
Jonathan Gazeley committed
177
  concat::fragment { 'attr-default':
178
    target  => "${freeradius::fr_modulepath}/attr_filter",
Jonathan Gazeley's avatar
Jonathan Gazeley committed
179
    content => template('freeradius/attr_default.erb'),
180
181
    order   => 10,
  }
182

183
184
  # Install a slightly tweaked stock dictionary that includes
  # our custom dictionaries
185
  concat { "${freeradius::fr_basepath}/dictionary":
186
    owner   => 'root',
187
    group   => $freeradius::fr_group,
188
    mode    => '0640',
189
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
190
191
  }
  concat::fragment { 'dictionary_header':
192
    target => "${freeradius::fr_basepath}/dictionary",
193
194
    source => 'puppet:///modules/freeradius/dictionary.header',
    order  => 10,
195
196
  }
  concat::fragment { 'dictionary_footer':
197
    target => "${freeradius::fr_basepath}/dictionary",
198
199
    source => 'puppet:///modules/freeradius/dictionary.footer',
    order  => 90,
200
201
  }

202
  # Install FreeRADIUS packages
203
204
  package { 'freeradius':
    ensure => installed,
205
    name   => $freeradius::fr_package,
206
  }
207
208
209
210
  if $mysql_support {
    package { 'freeradius-mysql':
      ensure => installed,
    }
211
  }
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  if $perl_support {
    package { 'freeradius-perl':
      ensure => installed,
    }
  }
  if $utils_support {
    package { 'freeradius-utils':
      ensure => installed,
    }
  }
  if $ldap_support {
    package { 'freeradius-ldap':
      ensure => installed,
    }
  }
227
228
229
230
231
  if $krb5_support {
    package { 'freeradius-krb5':
      ensure => installed,
    }
  }
232
233
234
  if $wpa_supplicant {
    package { 'wpa_supplicant':
      ensure => installed,
235
      name   => $freeradius::fr_wpa_supplicant,
236
    }
237
238
239
240
  }

  # radiusd always tests its config before restarting the service, to avoid outage. If the config is not valid, the service
  # won't get restarted, and the puppet run will fail.
241
  service { $freeradius::fr_service:
242
    ensure     => running,
243
244
    name       => $freeradius::fr_service,
    require    => [Exec['radiusd-config-test'], File['radiusd.conf'], User[$freeradius::fr_user], Package[$freeradius::fr_package],],
245
    enable     => true,
246
    hasstatus  => $freeradius::fr_service_has_status,
247
248
249
    hasrestart => true,
  }

250
251
252
  # We don't want to create the radiusd user, just add it to the
  # wbpriv group if the user needs winbind support. We depend on
  # the FreeRADIUS package to be sure that the user has been created
253
  user { $freeradius::fr_user:
254
    ensure  => present,
255
    groups  => $winbind_support ? {
256
      true    => $freeradius::fr_wbpriv_user,
257
258
      default => undef,
    },
259
    require => Package[$freeradius::fr_package],
260
261
  }

262
263
264
  # We don't want to add the radiusd group but it must be defined
  # here so we can depend on it. WE depend on the FreeRADIUS
  # package to be sure that the group has been created.
265
  group { $freeradius::fr_group:
Jonathan Gazeley's avatar
Jonathan Gazeley committed
266
    ensure  => present,
267
    require => Package[$freeradius::fr_package]
268
269
  }

270
  # Syslog rules
271
  if $syslog == true {
272
273
    rsyslog::snippet { '12-radiusd-log':
      content => "if \$programname == \'radiusd\' then ${freeradius::fr_logpath}/radius.log\n&~",
274
    }
275
276
277
278
  }

  # Make the radius log dir traversable
  file { [
279
280
    $freeradius::fr_logpath,
    "${freeradius::fr_logpath}/radacct",
281
282
  ]:
    mode    => '0750',
283
    require => Package[$freeradius::fr_package],
284
285
  }

286
287
288
  file { "${freeradius::fr_logpath}/radius.log":
    owner   => $freeradius::fr_user,
    group   => $freeradius::fr_group,
289
    seltype => 'radiusd_log_t',
290
    require => [Package[$freeradius::fr_package], User[$freeradius::fr_user], Group[$freeradius::fr_group]],
291
292
  }

293
294
295
  logrotate::rule { 'radacct':
    path          => "${freeradius::fr_logpath}/radacct/*/*.log",
    rotate_every  => 'day',
296
    rotate        => '7',
297
298
299
300
301
302
303
304
    create        => false,
    missingok     => true,
    compress      => true,
    postrotate    => 'kill -HUP `cat /var/run/radiusd/radiusd.pid`',
    sharedscripts => true,
  }

  logrotate::rule { 'checkrad':
305
306
    path          => "${freeradius::fr_logpath}/checkrad.log",
    rotate_every  => 'week',
307
    rotate        => '1',
308
309
310
311
312
    create        => true,
    missingok     => true,
    compress      => true,
    postrotate    => 'kill -HUP `cat /var/run/radiusd/radiusd.pid`',
    sharedscripts => true,
313
314
315
  }

  logrotate::rule { 'radiusd':
316
    path          => "${freeradius::fr_logpath}/radius*.log",
317
    rotate_every  => 'week',
318
    rotate        => '26',
319
320
321
322
323
    create        => true,
    missingok     => true,
    compress      => true,
    postrotate    => 'kill -HUP `cat /var/run/radiusd/radiusd.pid`',
    sharedscripts => true,
324
325
  }

326
327
328
329
330
331
  # Placeholder resource for dh and random as they are dynamically generated, so they
  # exist in the catalogue and don't get purged
  file { ["${freeradius::fr_basepath}/certs/dh", "${freeradius::fr_basepath}/certs/random"]:
    require => Exec['dh', 'random'],
  }

332
333
  # Generate global SSL parameters
  exec { 'dh':
334
335
    command => "openssl dhparam -out ${freeradius::fr_basepath}/certs/dh 1024",
    creates => "${freeradius::fr_basepath}/certs/dh",
336
337
338
339
340
    path    => '/usr/bin',
  }

  # Generate global SSL parameters
  exec { 'random':
341
342
    command => "dd if=/dev/urandom of=${freeradius::fr_basepath}/certs/random count=10 >/dev/null 2>&1",
    creates => "${freeradius::fr_basepath}/certs/random",
343
344
345
346
347
348
    path    => '/bin',
  }

  # This exec tests the radius config and fails if it's bad
  # It isn't run every time puppet runs, but only when freeradius is to be restarted
  exec { 'radiusd-config-test':
Jonathan Gazeley's avatar
Jonathan Gazeley committed
349
    command     => 'sudo radiusd -XC | grep \'Configuration appears to be OK.\' | wc -l',
350
351
352
    returns     => 0,
    refreshonly => true,
    logoutput   => on_failure,
Jonathan Gazeley's avatar
Jonathan Gazeley committed
353
    path        => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
354
355
356
357
358
  }

  # Blank a couple of default files that will break our config. This is more effective than deleting them
  # as they won't get overwritten when FR is upgraded from RPM, whereas missing files are replaced.
  file { [
359
    "${freeradius::fr_basepath}/clients.conf",
360
    "${freeradius::fr_basepath}/sql.conf",
361
362
  ]:
    content => "# FILE INTENTIONALLY BLANK\n",
Jonathan Gazeley's avatar
Jonathan Gazeley committed
363
364
    mode    => '0644',
    owner   => 'root',
365
366
367
    group   => $freeradius::fr_group,
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
368
369
370
371
  }

  # Delete *.rpmnew and *.rpmsave files from the radius config dir because
  # radiusd stupidly reads these files in, and they break the config
372
373
374
375
376
  # This should be fixed in FreeRADIUS 2.2.0
  # http://lists.freeradius.org/pipermail/freeradius-users/2012-October/063232.html
  # Only affects RPM-based systems
  if $::osfamily == 'RedHat' {
    exec { 'delete-radius-rpmnew':
377
378
      command => "find ${freeradius::fr_basepath} -name *.rpmnew -delete",
      onlyif  => "find ${freeradius::fr_basepath} -name *.rpmnew | grep rpmnew",
379
380
381
      path    => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
    }
    exec { 'delete-radius-rpmsave':
382
383
      command => "find ${freeradius::fr_basepath} -name *.rpmsave -delete",
      onlyif  => "find ${freeradius::fr_basepath} -name *.rpmsave | grep rpmsave",
384
385
      path    => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
    }
386
  }
387
}