Keep unwanted OS users away.

Keep unwanted OS users away One of the elements of making and keeping your system secured is ensuring no unwanted and illegal OS user accounts are available on your system. Puppet has a mechanism for that. It is called auto purging. In this blog post, we will show you how this works and how you can use this safely.

The puppet language

The puppet language has a mechanism for making sure that a resource is NOT available on your system.

user { 'hacker':
  ensure => absent,

When you apply this little snippet of Puppet code to your system, Puppet ensure’s that there is no user ‘hacker’ available on the system. But when your Puppet manifest would have to contain all the things you don’t want on your system, the list could get very long. And it is impossible to make it exhaustive.

Puppet auto-purge to the rescue

This is exactly why Puppet has the auto-purge feature. You can specify it like this:

resources { 'user':
  purge => true,

When you add this snippet of code to your manifest, Puppet will remove all users that are not defined in your manifest. To test this out, let’s first create some users:

$ useradd -u 100 hacker
$ useradd -u 1100 real_user

After we have added these users, let’s try applying the puppet manifest.

$ puppet apply purge.pp --verbose
Info: Loading facts
Notice: Compiled catalog for node in environment production in 0.11 seconds
Info: Applying configuration version '1575463051'
Notice: /Stage[main]/Main/User[real_user]/ensure: removed
Notice: /Stage[main]/Main/User[real_user]/uid: audit change: newly-recorded value 1100
Notice: Applied catalog in 0.11 seconds

That is strange. The user real_user is removed, but the user hacker is still there. Also, there are a lot more users on the system than just these two. What happened to them. Why are they not removed?

I guess Puppet is trying to guard you against disaster. Removing all OS defined users from your system will render it unusable. So Puppet added the unless_system_user parameter to the resources type. The default value for the parameter is true. This means Puppet by default,does not remove users whose UIDs are less than the minimum UID for the system (typically 500 or 1000). This explains why the real_user was removed, but the hacker was not.

But how about hackers?

Although it is good that Puppet tries to guard you against disaster, hackers might misuse this knowledge to create a user in the system uid space. Puppet would then never remove it and keep your system vulnerable for hackers. So what should we do? If we set the unless_system_user to false the system becomes unusable and if we set it to true the system is vulnerable for hackers.

The solution is to add the system accounts to your manifest. But only the bare minimum information required. Puppet manages only the attributes of a resource that are specified in your manifest. For system users, the only property you want to manage is the fact that you want it to be available on the system. Here is a way you can get the list of users on your system:

$ puppet resource user | grep "user {" | awk -F"'" '{print $2}'

If you do this on a pristine system, you get the list of system users. With this list, we can make the next puppet code.

$system_users = [

user { $system_users:
 ensure => 'present'

resources { 'user':
 purge              => true,
 unless_system_user => false,

For testing, we first need to add the real_user again. The hacker user was still there. So there is no need to recreate it.

$ useradd -u 1100 real_user

Now let’s try the Puppet code again:

bash-4.2# puppet apply purge.pp --verbose
Info: Loading facts
Notice: Compiled catalog for node in environment production in 0.14 seconds
Info: Applying configuration version '1575465090'
Notice: /Stage[main]/Main/User[hacker]/ensure: removed
Notice: /Stage[main]/Main/User[real_user]/ensure: removed
Info: Creating state file /opt/puppetlabs/puppet/cache/state/state.yaml
Notice: Applied catalog in 0.21 seconds

Eureka. Now we have a way to ensure no extra users are added to our systems, but also ensuring the system stays in a runnable state.

What’s next?

OS users are not the only resources on a system that can cause vulnerabilities when not managed correctly. In next blog posts, we will investigate auto purging other resources like Oracle users, MQ Message queue’s WebLogic datasources etc.

If you want to receive a notification when the next blog post is published, don’t forget to subscribe to this blog!