A collection of task oriented solutions in Puppet

 

Run services on non-standard ports

Challenge

You want to run a service on a non-standard port but SELinux prevents it

Solution

Puppet doesn't provide a native way to manage SELinux port configuration so you'll need to install a module to manage it.

$ sudo /opt/puppetlabs/bin/puppet module install puppet-selinux

...
Notice: Installing -- do not interrupt ...
/etc/puppetlabs/code/environments/production/modules
 - puppet-selinux (v1.5.2)
  - puppetlabs-stdlib (v4.25.1)
...

Once the module is installed you can use selinux::port to manage which processes SELinux allows to bind to a given port.

class sshport {

  selinux::port { 'non-standard-ssh-port':
    ensure   => 'present',
    seltype  => 'ssh_port_t',
    protocol => 'tcp',
    port     => 222, # still restricted to root but not standard port
  }

}

Explanation

This is an advanced SELinux topic for which we only cover the puppet specifics. If you're new to SELinux you should read the official documents before rolling this kind of change out with Puppet.

In our use case we want to change the port SSH listens to in order to reduce the amount of optimistic brute force attempts we see in our logs. If we 'just' change the port from 22 to 222, which is easy to remember but still in the restricted to root port range, and reload the service we'll see that sshd is no longer listening to any ports as SELinux has prevented it from binding to something unexpected.

We can confirm the internal SELinux port to label mappings with the semanage port command:

$ semanage port -l | grep ssh
SELinux Port Type              Proto    Port Number
ssh_port_t                     tcp      22

We can then use our selinux::port puppet resource to permit an additional port:

class sshport {

  selinux::port { 'non-standard-ssh-port':
    ensure   => 'present',
    seltype  => 'ssh_port_t',
    protocol => 'tcp',
    port     => 222, # still restricted to root but not standard port
  }

}
Notice: /Stage[main]/Selinux_port/Selinux::Port[non-standard-ssh-port]
  /Selinux_port[tcp_222-222]/ensure: created

$ semanage port -l | grep ssh
SELinux Port Type              Proto    Port Number
ssh_port_t                     tcp      222, 22

If we restart our ssh daemon, with the Listen directive changed to match our chosen port, we should see it start and bind successfully to the specified port. In addition to the ssh use case above you'll often want to allow extra ports when running multiple web servers for local development.

See also