Defined Type: selinux::module

Defined in:
manifests/module.pp

Summary

Manage a SELinux module on a running system

Overview

This class will either install or uninstall a SELinux module from a running system. This module allows an admin to keep .te files in text form in a repository, while allowing the system to compile and manage SELinux modules.

Concepts incorporated from: stuckinadoloop.wordpress.com/2011/06/15/puppet-managed-deployment-of-selinux-modules/

Examples:

compile and load the apache module - does not require make or the policy

devel package
selinux::module{ 'apache':
  ensure    => 'present',
  source_te => 'puppet:///modules/selinux/apache.te',
  builder   => 'simple'
}

compile a module the refpolicy way. It will install the policy devel and

dependent packages like make.
selinux::module{ 'mymodule':
  ensure    => 'present',
  source_te => 'puppet:///modules/profile/selinux/mymodule.te',
  source_fc => 'puppet:///modules/profile/selinux/mymodule.fc',
  source_if => 'puppet:///modules/profile/selinux/mymodule.if',
  builder   => 'refpolicy'
}

compile and load a module from inline content

$content = @("END")
  policy_module(zabbix_fix, 0.1)
  require {
    type zabbix_t;
    type unreserved_port_t;
    class tcp_socket name_connect;
  }
  allow zabbix_t unreserved_port_t:tcp_socket name_connect;
  | END
selinux::module{ 'zabbix_fix':
  ensure     => 'present',
  content_te => $content,
  builder    => 'simple'
}

Parameters:

  • ensure (Enum['absent', 'present']) (defaults to: 'present')

    present or absent

  • source_pp (Optional[String]) (defaults to: undef)

    the source file (either a puppet URI or local file) of a pre-compiled SELinux policy package. Mutually excludsive with using source files.

  • source_te (Optional[String]) (defaults to: undef)

    the source file (either a puppet URI or local file) of the SELinux .te file

  • source_fc (Optional[String]) (defaults to: undef)

    the source file (either a puppet URI or local file) of the SELinux .fc file

  • source_if (Optional[String]) (defaults to: undef)

    the source file (either a puppet URI or local file) of the SELinux .if file

  • content_te (Optional[String]) (defaults to: undef)

    content of the SELinux .te file

  • content_fc (Optional[String]) (defaults to: undef)

    content of the SELinux .fc file

  • content_if (Optional[String]) (defaults to: undef)

    content of the SELinux .if file

  • builder (Optional[Enum['simple', 'refpolicy']]) (defaults to: undef)

    either ‘simple’ or ‘refpolicy’. The simple builder attempts to use checkmodule to build the module, whereas ‘refpolicy’ uses the refpolicy framework, but requires ‘make’



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'manifests/module.pp', line 55

define selinux::module (
  Optional[String] $source_pp = undef,
  Optional[String] $source_te = undef,
  Optional[String] $source_fc = undef,
  Optional[String] $source_if = undef,
  Optional[String] $content_te = undef,
  Optional[String] $content_fc = undef,
  Optional[String] $content_if = undef,
  Enum['absent', 'present'] $ensure = 'present',
  Optional[Enum['simple', 'refpolicy']] $builder = undef,
) {
  include selinux
  require selinux::build

  $_builder = pick($builder, $selinux::default_builder, 'none')

  if $_builder == 'refpolicy' {
    require selinux::refpolicy_package
  }

  if ($builder == 'simple' and ($source_if != undef or $content_if != undef)) {
    fail("The simple builder does not support the 'source_if' parameter")
  }

  $module_dir = $selinux::build::module_build_dir
  $module_file = "${module_dir}/${title}"

  $build_command = $_builder ? {
    'simple'    => shellquote($selinux::build::module_build_simple, $title, $module_dir),
    'refpolicy' => shellquote('make', '-f', $selinux::refpolicy_makefile, "${title}.pp"),
    'none'      => undef
  }

  Anchor['selinux::module pre']
  -> Selinux::Module[$title]
  -> Anchor['selinux::module post']

  if $facts['os']['selinux']['enabled'] {
    $has_source = (pick($source_te, $source_fc, $source_if, $content_te, $content_fc, $content_if, false) != false)
    if $has_source and $build_command == undef {
      fail('No builder or default builder specified')
    }

    if $has_source and $source_pp != undef {
      fail('Specifying source files and a pre-compiled policy package are mutually exclusive options')
    }

    if $has_source and $ensure == 'present' {
      file { "${module_file}.te":
        ensure  => 'file',
        source  => $source_te,
        content => $content_te,
        notify  => Exec["clean-module-${title}"],
      }

      $content_fc_real = $content_fc ? { undef => $source_fc ? { undef => '', default => undef }, default => $content_fc }
      file { "${module_file}.fc":
        ensure  => 'file',
        source  => $source_fc,
        content => $content_fc_real,
        notify  => Exec["clean-module-${title}"],
      }

      $content_if_real = $content_if ? { undef => $source_if ? { undef => '', default => undef }, default => $content_if }
      file { "${module_file}.if":
        ensure  => 'file',
        source  => $source_if,
        content => $content_if_real,
        notify  => Exec["clean-module-${title}"],
      }
      # ensure it doesn't get purged if it exists
      file { "${module_file}.pp": selinux_ignore_defaults => true }

      exec { "clean-module-${title}":
        path        => '/bin:/usr/bin',
        cwd         => $module_dir,
        command     => "rm -f '${module_file}.pp' '${module_file}.loaded'",
        refreshonly => true,
        notify      => Exec["build-module-${title}"],
      }

      exec { "build-module-${title}":
        path    => '/bin:/usr/bin',
        cwd     => $module_dir,
        command => "${build_command} || (rm -f '${module_file}.pp' '${module_file}.loaded' && exit 1)",
        creates => "${module_file}.pp",
        notify  => Exec["install-module-${title}"],
      }
      $install = true
    } elsif $source_pp != undef and $ensure == 'present' {
      file { "${module_file}.pp":
        ensure => 'file',
        source => $source_pp,
        notify => Exec["clean-module-${title}"],
      }

      exec { "clean-module-${title}":
        path        => '/bin:/usr/bin',
        cwd         => $module_dir,
        command     => "rm -f '${module_file}.loaded'",
        refreshonly => true,
        notify      => Exec["install-module-${title}"],
      }

      $install = true
    } else {
      # no source and no .pp, just do plain selmodule {$title:}
      $install = false
    }

    if $install {
      # we need to install the module manually because selmodule is kind of dumb. It ends up
      # working fine, though.
      exec { "install-module-${title}":
        path    => '/sbin:/usr/sbin:/bin:/usr/bin',
        cwd     => $module_dir,
        command => "semodule -i '${module_file}.pp' && touch '${module_file}.loaded'",
        creates => "${module_file}.loaded",
        before  => Selmodule[$title],
      }

      # ensure it doesn't get purged if it exists
      file { "${module_file}.loaded": }
    }

    $module_path = ($has_source or $source_pp != undef) ? {
      true  => "${module_file}.pp",
      false => undef
    }

    selmodule { $title:
      ensure        => $ensure,
      selmodulepath => $module_path,
    }
  }
}