Tuesday 25 October 2016

Locking down a linux system with the help of Puppet

Puppet as well as a great deployment tool is brilliant for ensuring that your systems configuration is as it should be.

When working with Linux (well any operating system really) I like to create a security baseline that acts as an applied standard accross the organization.

I am going to base the core configuration (while ensuring that the configuration is compatible with the vast majority of Linux distributions.):

puppet module install hardening-ssh_hardening
puppet module install hardening-os_hardening
puppet module install puppetlabs-accounts
puppet module install puppetlabs-ntp
puppet module install puppetlabs-firewall
puppet module install saz-sudo

vi /etc/puppet/modules/accounts/manifests/init.pp

import "/etc/puppet/modules/firewall/manifests/pre.pp"
import "/etc/puppet/modules/firewall/manifests/post.pp"

node default {

  ########### Replace firewalld with IPTables ############
  package { tcpdump: ensure => installed; }
  package { nano: ensure => installed; }
  package { wget: ensure => installed; }
  package { firewalld: ensure => absent; }

  service { 'firewalld':
    ensure     => stopped,
    enable     => false,
    hasstatus  => true,
  }

  service { 'iptables':
    ensure     => running,
    enable     => true,
    hasstatus  => true,
  }

  ########### Configure firewall ###########
  resources { "firewall":
    purge   => true
  }

  Firewall {
    before  => Class['fw::post'],
    require => Class['fw::pre'],
  }

  class { ['fw::pre', 'fw::post']: }
 
}

Note: We can generate the password hash with:

makepasswd --clearfrom=- --crypt-md5

We can now apply our host specific configuration:

import "/etc/puppet/manifests/nodes.pp"

and in our nodes.pp file we will define our settings for the induvidual hosts:

vi /etc/puppet/manifests/nodes.pp

node 'hostname.domain.com' {

  include privileges

  ########### Custom Firewall Rules ###########
  firewall { '100 Allow inbound access to tcp/8000':
  dport     => 8000,
  proto    => tcp,
  action   => accept,
  }
 
  firewall { '101 Allow inbound access to tcp/80':
  dport     => 80,
  proto    => tcp,
  action   => accept,
  }

  ########### Configure Groups ###########
  group { 'admins':
   ensure => 'present',
   gid    => '501',
        }
     
  ########### Configure NTP ###########
  class { 'ntp':
    servers => ['0.uk.pool.ntp.org','1.uk.pool.ntp.org','2.uk.pool.ntp.org','3.uk.pool.ntp.org']
  }
 
  ########### Configure OS Hardening ###########
  class { 'os_hardening':
    enable_ipv4_forwarding => true,
  }
 
  ########### Configure User Accounts ############
  accounts::user { 'youruser':
  ensure => "present",
  uid      => 500,
  shell    => '/bin/bash',
  password => '$11234567890987654.',
  locked   => false,
  groups   => [admins],
  }
 
  ########### SSH Hardening #############
  class { 'ssh_hardening::server': }

  ########### Configure SSH Keys #############
  ssh_authorized_key { 'user@domain.com':
  user => 'youruser',
  type => 'ssh-rsa',
  key  => '345kj345kl34j534k5j345k34j5kl345[...]',
}

}

We need to create a new module to handle sudo for us:

mkdir -p /etc/puppet/modules/privileges/manifests && cd /etc/puppet/modules/privileges/manifests

vi init.pp

class privileges {
   user { 'root':
     ensure   => present,
     password => '$1$54j534h5j345345',
     shell    => '/bin/bash',
     uid      => '0',
   }

   sudo::conf { 'admins':
     ensure  => present,
     content => '%admin ALL=(ALL) ALL',
   }

   sudo::conf { 'wheel':
     ensure  => present,
     content => '%wheel ALL=(ALL) ALL',
   }
}

And make sure our include statement is present in our nodes.pp file.

we should also create our firewall manifiests:

vi /etc/puppet/modules/firewall/manifests/pre.pp

class fw::pre {

  Firewall {
    require => undef,
  }

  # basic in/out
  firewall { "000 accept all icmp":
    chain    => 'INPUT',
    proto    => 'icmp',
    action   => 'accept',
  }

  firewall { '001 accept all to lo interface':
    chain    => 'INPUT',
    proto    => 'all',
    iniface  => 'lo',
    action   => 'accept',
  }

  firewall { '006 Allow inbound SSH':
    dport     => 22,
    proto    => tcp,
    action   => accept,
  }

  firewall { '003 accept related established rules':
    chain    => 'INPUT',
    proto    => 'all',
    state    => ['RELATED', 'ESTABLISHED'],
    action   => 'accept',
  }

  firewall { '004 accept related established rules':
    chain    => 'OUTPUT',
    proto    => 'all',
    state    => ['RELATED', 'ESTABLISHED'],
    action   => 'accept',
  }

  firewall { '005 allow all outgoing traffic':
    chain    => 'OUTPUT',
    state    => ['NEW','RELATED','ESTABLISHED'],
    proto    => 'all',
    action   => 'accept',
  }

}

vi /etc/puppet/modules/firewall/manifests/post.pp

class fw::post {

  firewall { '900 log dropped input chain':
    chain      => 'INPUT',
    jump       => 'LOG',
    log_level  => '6',
    log_prefix => '[IPTABLES INPUT] dropped ',
    proto      => 'all',
    before     => undef,
  }

  firewall { '900 log dropped forward chain':
    chain      => 'FORWARD',
    jump       => 'LOG',
    log_level  => '6',
    log_prefix => '[IPTABLES FORWARD] dropped ',
    proto      => 'all',
    before     => undef,
  }

  firewall { '900 log dropped output chain':
    chain      => 'OUTPUT',
    jump       => 'LOG',
    log_level  => '6',
    log_prefix => '[IPTABLES OUTPUT] dropped ',
    proto      => 'all',
    before     => undef,
  }

  firewall { "910 deny all other input requests":
    chain      => 'INPUT',
    action     => 'drop',
    proto      => 'all',
    before     => undef,
  }

  firewall { "910 deny all other forward requests":
    chain      => 'FORWARD',
    action     => 'drop',
    proto      => 'all',
    before     => undef,
  }

  firewall { "910 deny all other output requests":
    chain      => 'OUTPUT',
    action     => 'drop',
    proto      => 'all',
    before     => undef,
  }

}

Ensure all of our mainifests are valid:

puppet parser validate site.pp

Sources: https://docs.puppet.com/pe/latest/quick_start_sudo.html
https://www.linode.com/docs/applications/puppet/install-and-configure-puppet

0 comments:

Post a Comment