init.pp 12.1 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
  $correct_escapes = true,
18
19
) inherits freeradius::params {

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

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

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

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

39
40
  # Create various directories
  file { [
41
42
43
44
45
46
47
48
    "${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",
49
  ]:
50
51
52
    ensure  => directory,
    mode    => '0750',
    owner   => 'root',
53
54
55
    group   => $freeradius::fr_group,
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
56
57
  }

58
  # Create these directories separately so we can set purge option
59
  # Anything in these dirs NOT managed by puppet will be removed!
60
61
62
  file { [
    "${freeradius::fr_basepath}/certs",
    "${freeradius::fr_basepath}/clients.d",
63
    "${freeradius::fr_basepath}/sites-enabled",
64
    "${freeradius::fr_basepath}/mods-enabled",
Jonathan Gazeley's avatar
Jonathan Gazeley committed
65
    "${freeradius::fr_basepath}/instantiate",
66
  ]:
67
68
69
70
71
72
73
74
75
76
    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],
  }

77
  # Preserve some stock modules
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
110
  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,
    }
111
112
113
  }


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

134
  # Set up concat template file
Jonathan Gazeley's avatar
Jonathan Gazeley committed
135
  concat { "${freeradius::fr_basepath}/templates.conf":
136
137
138
139
140
141
142
    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':
143
144
145
146
147
    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
148
    target  => "${freeradius::fr_basepath}/templates.conf",
149
150
    content => "}\n",
    order   => '95',
151
152
  }

153

154
155
156
157
158
159
160
161
  # 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],
  }
162
163
164
  concat::fragment { 'proxy_header':
    target  => "${freeradius::fr_basepath}/proxy.conf",
    content => "# Proxy config\n\n",
165
    order   => '05',
166
  }
167

168
169
170
171
172
173
174
175
176
  # 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],
  }

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

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

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

  # 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.
242
  service { $freeradius::fr_service:
243
    ensure     => running,
244
245
    name       => $freeradius::fr_service,
    require    => [Exec['radiusd-config-test'], File['radiusd.conf'], User[$freeradius::fr_user], Package[$freeradius::fr_package],],
246
    enable     => true,
247
    hasstatus  => $freeradius::fr_service_has_status,
248
249
250
    hasrestart => true,
  }

251
252
253
  # 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
254
  user { $freeradius::fr_user:
255
    ensure  => present,
256
    groups  => $winbind_support ? {
257
      true    => $freeradius::fr_wbpriv_user,
258
259
      default => undef,
    },
260
    require => Package[$freeradius::fr_package],
261
262
  }

263
264
265
  # 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.
266
  group { $freeradius::fr_group:
Jonathan Gazeley's avatar
Jonathan Gazeley committed
267
    ensure  => present,
268
    require => Package[$freeradius::fr_package]
269
270
  }

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

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

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

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

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

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

327
328
329
330
331
332
  # 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'],
  }

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

  # Generate global SSL parameters
  exec { 'random':
342
343
    command => "dd if=/dev/urandom of=${freeradius::fr_basepath}/certs/random count=10 >/dev/null 2>&1",
    creates => "${freeradius::fr_basepath}/certs/random",
344
345
346
347
348
349
    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
350
    command     => 'sudo radiusd -XC | grep \'Configuration appears to be OK.\' | wc -l',
351
352
353
    returns     => 0,
    refreshonly => true,
    logoutput   => on_failure,
Jonathan Gazeley's avatar
Jonathan Gazeley committed
354
    path        => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
355
356
357
358
359
  }

  # 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 { [
360
    "${freeradius::fr_basepath}/clients.conf",
361
    "${freeradius::fr_basepath}/sql.conf",
362
363
  ]:
    content => "# FILE INTENTIONALLY BLANK\n",
Jonathan Gazeley's avatar
Jonathan Gazeley committed
364
365
    mode    => '0644',
    owner   => 'root',
366
367
368
    group   => $freeradius::fr_group,
    require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
    notify  => Service[$freeradius::fr_service],
369
370
371
372
  }

  # Delete *.rpmnew and *.rpmsave files from the radius config dir because
  # radiusd stupidly reads these files in, and they break the config
373
374
375
376
377
  # 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':
378
379
      command => "find ${freeradius::fr_basepath} -name *.rpmnew -delete",
      onlyif  => "find ${freeradius::fr_basepath} -name *.rpmnew | grep rpmnew",
380
381
382
      path    => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
    }
    exec { 'delete-radius-rpmsave':
383
384
      command => "find ${freeradius::fr_basepath} -name *.rpmsave -delete",
      onlyif  => "find ${freeradius::fr_basepath} -name *.rpmsave | grep rpmsave",
385
386
      path    => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'],
    }
387
  }
388
}