Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for installing and managing radsniff #157

Merged
merged 4 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ fixtures:
logrotate: "puppet/logrotate"
rsyslog: "saz/rsyslog"
stdlib: "puppetlabs/stdlib"
systemd: "camptocamp/systemd"
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,22 @@ Whether the control socket should be read-only or read-write. Choose from `ro`,
}
```

#### `freeradius::radsniff`

The `freeradius::radsniff` class configures and runs the [RADSNIFF](https://freeradius.org/radiusd/man/radsniff.html) service.
It requires freeradius-utils to be installed, so will fail if `utils_support` is not enabled on the `freeradius` class.

Note: This is only supported on RedHat like systems at present.

##### `options`
Command line options to be passed to radsniff. Quotes are escaped
```puppet
# Enable radsniff, with a filter, sending data to collectd (requires freeradius to be compiled for this)
class { 'freeradius::radsniff':
options => '-m -p1812,1813 -O unix:/var/run/collectd.sock -N freeradius -W 10 -i eth0 -f "src not 192.0.2.1"',
}
```

### Resources

#### `freeradius::attr`
Expand Down
2 changes: 1 addition & 1 deletion manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@
concat { "${freeradius::fr_basepath}/dictionary":
owner => 'root',
group => $freeradius::fr_group,
mode => '0640',
mode => '0644',
require => [Package[$freeradius::fr_package], Group[$freeradius::fr_group]],
}
concat::fragment { 'dictionary_header':
Expand Down
10 changes: 10 additions & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,14 @@
}

$radacctdir = "\${logdir}/radacct"

# Default radsniff environment file location
$fr_radsniff_envfile = $::osfamily ? {
'RedHat' => '/etc/sysconfig/radsniff',
'Debian' => '/etc/defaults/radsniff',
default => undef,
}

# Default radsniff pid file location
$fr_radsniff_pidfile = "/var/run/${fr_service}/radsniff.pid"
}
57 changes: 57 additions & 0 deletions manifests/radsniff.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# @summary configure and run radsniff
#
# @param envfile path to the environment file, used by the systemd unit
# @param options commandline options passed to radsniff when it runs
# @param
class freeradius::radsniff (
Optional[String] $envfile = undef,
String $options = '',
Optional[String] $pidfile = undef,
) inherits freeradius::params {
unless $::freeradius::utils_support {
fail('freeradius::radsniff requires freeradius have utils_support enabled')
}

# Calculate the envfile to use - specified, then calculated, then error if none
if $envfile {
$final_envfile = $envfile
} else {
if $freeradius::radsniff::fr_radsniff_envfile {
$final_envfile = $freeradius::radsniff::fr_radsniff_envfile
} else {
fail('freeradius::radsniff requires envfile to be explicitly set on this OS')
}
}

# Calculate the pidfile to use - specified, then calculated, then error if none
if $pidfile {
$final_pidfile = $pidfile
} else {
if $freeradius::radsniff::fr_radsniff_pidfile {
$final_pidfile = $freeradius::radsniff::fr_radsniff_pidfile
} else {
fail('freeradius::radsniff requires pidfile to be explicitly set on this OS')
}
}

$escaped_cmd = $options.regsubst('"','\\\\"','G')

file { $final_envfile:
content => @("SYSCONFIG"),
RADSNIFF_OPTIONS="${escaped_cmd}"
| SYSCONFIG
owner => 'root',
group => 'root',
mode => '0644',
require => Package['freeradius-utils'],
}
~> service { 'radsniff':
ensure => running,
enable => true,
}

systemd::unit_file {'radsniff.service':
content => template('freeradius/radsniff.service.erb'),
notify => Service['radsniff'],
}
}
4 changes: 4 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
{
"name": "puppetlabs/concat",
"version_requirement": ">=1.0.0 <7.0.0"
},
{
"name": "camptocamp/systemd",
"version_requirement": ">=2.0.0 <3.0.0"
}
],
"operatingsystem_support": [
Expand Down
2 changes: 1 addition & 1 deletion spec/classes/freeradius_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
is_expected.to contain_concat('/etc/raddb/dictionary')
.with(
'group' => 'radiusd',
'mode' => '0640',
'mode' => '0644',
'owner' => 'root',
)
.that_requires('Package[freeradius]')
Expand Down
123 changes: 123 additions & 0 deletions spec/classes/radsniff_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
require 'spec_helper'

describe 'freeradius::radsniff' do
on_supported_os.each do |os, os_facts|
include_context 'freeradius_with_utils'

context "on #{os}" do
let(:facts) { os_facts }

let(:params) do
{
options: 'radsniff cmd "line" options',
}
end

let(:pre_condition) do
precondition = case os_facts[:osfamily]
when 'RedHat'
'class freeradius::params {
$fr_basepath = "/etc/raddb"
$fr_radsniff_pidfile = "/var/run/radiusd/radsniff.pid"
$fr_radsniff_envfile = "/etc/sysconfig/radsniff"
}
include freeradius::params'
when 'Debian'
'class freeradius::params {
$fr_basepath = "/etc/freeradius"
$fr_radsniff_pidfile = "/var/run/freeradius/radsniff.pid"
$fr_radsniff_envfile = "/etc/defaults/radsniff"
}
include freeradius::params'
else
'class freeradius::params {
$fr_basepath = "/etc/raddb"
$fr_radsniff_pidfile = "/var/run/radiusd/radsniff.pid"
$fr_radsniff_envfile = undef
}
include freeradius::params'
end

super().push(precondition)
end

if os_facts[:osfamily] =~ %r{^RedHat|Debian$}
it do
is_expected.to contain_service('radsniff')
.with_ensure('running')
.with_enable(true)
end
end

case os_facts[:osfamily]
when 'RedHat'
it do
is_expected.to contain_file('/etc/sysconfig/radsniff')
.with_content(%r{RADSNIFF_OPTIONS="radsniff cmd \\"line\\" options"})
.that_notifies('Service[radsniff]')
.that_requires('Package[freeradius-utils]')
end

it do
is_expected.to contain_systemd__unit_file('radsniff.service')
.with_content(%r{^Pidfile=/var/run/radiusd/radsniff.pid$})
.with_content(%r{^EnvironmentFile=/etc/sysconfig/radsniff$})
.with_content(%r{^ExecStart=/usr/bin/radsniff -P /var/run/radiusd/radsniff.pid -d /etc/raddb \$RADSNIFF_OPTIONS$})
.that_notifies('Service[radsniff]')
end
when 'Debian'
it do
is_expected.to contain_file('/etc/defaults/radsniff')
.with_content(%r{RADSNIFF_OPTIONS="radsniff cmd \\"line\\" options"})
.that_notifies('Service[radsniff]')
.that_requires('Package[freeradius-utils]')
end

it do
is_expected.to contain_systemd__unit_file('radsniff.service')
.with_content(%r{^Pidfile=/var/run/freeradius/radsniff.pid$})
.with_content(%r{^EnvironmentFile=/etc/defaults/radsniff$})
.with_content(%r{^ExecStart=/usr/bin/radsniff -P /var/run/freeradius/radsniff.pid -d /etc/freeradius \$RADSNIFF_OPTIONS$})
.that_notifies('Service[radsniff]')
end
else
it do
is_expected.to compile.and_raise_error(%r{freeradius::radsniff requires envfile to be explicitly set on this OS})
is_expected.to compile.and_raise_error(%r{freeradius::radsniff requires pidfile to be explicitly set on this OS})
end
end

context 'with envfile and pidfile set' do
let(:params) do
super().merge(
envfile: '/test/env/file',
pidfile: '/a/pid/file',
)
end

if os_facts[:osfamily] !~ %r{^RedHat|Debian$}
it do
is_expected.to contain_service('radsniff')
.with_ensure('running')
.with_enable(true)
end
end

it do
is_expected.to contain_file('/test/env/file')
.with_content(%r{RADSNIFF_OPTIONS="radsniff cmd \\"line\\" options"})
.that_notifies('Service[radsniff]')
.that_requires('Package[freeradius-utils]')
end

it do
is_expected.to contain_systemd__unit_file('radsniff.service')
.with_content(%r{^Pidfile=/a/pid/file$})
.with_content(%r{^EnvironmentFile=/test/env/file$})
.with_content(%r{^ExecStart=/usr/bin/radsniff -P /a/pid/file -d .* \$RADSNIFF_OPTIONS$})
.that_notifies('Service[radsniff]')
end
end
end
end
end
14 changes: 14 additions & 0 deletions spec/spec_helper_local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@
end
end

# Same as above but enable utils
shared_context 'freeradius_with_utils' do
let(:pre_condition) do
[
'class freeradius {
$utils_support = true
}
include freeradius

package { "freeradius-utils": }',
]
end
end

# Some common dependencies for things based on names for redhat systems
shared_context 'redhat_common_dependencies' do
let(:pre_condition) do
Expand Down
13 changes: 13 additions & 0 deletions templates/radsniff.service.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Capture RADIUS statistics
After=syslog.target network.target
After=radiusd.target

[Service]
Type=forking
Pidfile=<%=scope['::freeradius::radsniff::final_pidfile']%>
EnvironmentFile=<%=scope['::freeradius::radsniff::final_envfile']%>
ExecStart=/usr/bin/radsniff -P <%=scope['::freeradius::radsniff::final_pidfile']%> -d <%=scope['::freeradius::radsniff::fr_basepath']%> $RADSNIFF_OPTIONS

[Install]
WantedBy=multi-user.target