2.8. Configuring SELinux

SELinux restricts non-standard access to the HTTP server by default. If we define a custom port, we need to add configuration that allows SELinux to grant access.
Puppet contains resource types to manage some SELinux functions, such as Booleans and modules. However, we need to execute the semanage command to manage port settings. This tool is a part of the policycoreutils-python package, which is not installed on Red Hat Enterprise Linux systems by default.
Add the following code inside your mymodule::http class:
  exec { 'semanage-port':
    command => "semanage port -a -t http_port_t -p tcp ${httpd_port}",
    path => "/usr/sbin",
    require => Package['policycoreutils-python'],
    before => Service ['httpd'],
    subscribe => Package['httpd'],
    refreshonly => true,
  }
  package { 'policycoreutils-python':
    ensure => installed,
  }
This code performs the following:
  • The require => Package['policycoreutils-python'] attribute makes sure the policycoreutils-python is installed prior to executing the command.
  • Puppet executes semanage to open a port using httpd_port as a variable.
  • The before => Service ['httpd'] makes sure to execute this command before the httpd service starts. If httpd starts before the SELinux command, SELinux denies access to the port and the service fails to start.
  • The code for the SELinux executable resource contains refreshonly => true and subscribe => Package['httpd'] attributes. This ensures the SELinux commands only run after the httpd installs. Without these attributes, subsequent runs result in failure. This is because SELinux detects the port is already enabled and reports an error.
Run the puppet apply command again to test the changes to our module.
# puppet apply mymodule/tests/init.pp --noop
...
Notice: /Stage[main]/Mymodule::Httpd/Package[policycoreutils-python]/ensure: current_value absent, should be present (noop)
...
Notice: /Stage[main]/Mymodule::Httpd/Exec[semanage-port]/returns: current_value notrun, should be 0 (noop)
...
Notice: /Stage[main]/Mymodule::Httpd/Service[httpd]/ensure: current_value stopped, should be running (noop)
...
Puppet installs policycoreutils-python first, then configures port access before starting the httpd service.