init.pp 11.9 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
  $syslog          = false,
14
  $log_auth        = 'no',
15
  $preserve_mods   = true,
16
17
) inherits freeradius::params {

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

20
  if $control_socket == true {
Jonathan Gazeley's avatar
Jonathan Gazeley committed
21
    warning('Use of the control_socket parameter in the freeradius class is deprecated. Please use the freeradius::control_socket class instead.')
22
23
  }

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

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

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

72
  # Preserve some stock modules
73
74
75
76
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
  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,
    }
106
107
108
  }


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

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

148

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

163
164
165
166
167
168
169
170
171
  # 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],
  }

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

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

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

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

246
247
248
  # 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
249
  user { $freeradius::fr_user:
250
    ensure  => present,
251
    groups  => $winbind_support ? {
252
      true    => $freeradius::fr_wbpriv_user,
253
254
      default => undef,
    },
255
    require => Package[$freeradius::fr_package],
256
257
  }

258
259
260
  # 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.
261
  group { $freeradius::fr_group:
Jonathan Gazeley's avatar
Jonathan Gazeley committed
262
    ensure  => present,
263
    require => Package[$freeradius::fr_package]
264
265
  }

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

  # Make the radius log dir traversable
  file { [
275
276
    $freeradius::fr_logpath,
    "${freeradius::fr_logpath}/radacct",
277
278
  ]:
    mode    => '0750',
279
    require => Package[$freeradius::fr_package],
280
281
  }

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

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

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

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

322
323
324
325
326
327
  # 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'],
  }

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

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

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

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