Skip to content

pyllyukko/harden.yml

Repository files navigation

harden.yml

Ansible playbook to harden your Linux system.

lint

asciicast of harden.yml 1294b6f

Supported distros

  • Debian (Bookworm)
    • Kali
    • Raspberry Pi OS
  • Slackware (>= 15.0)
  • Limited hardening for CentOS 7 (see CentOS specific tasks with ansible-playbook --list-tasks --tags centos harden.yml)

Why I made this

  • Bastille is obsolete
  • Not a member of CIS, so no downloading of the ready made scripts
  • For learning
  • For minimizing the effort needed to tweak fresh installations
    • Also for consistency

What does it do?

For a complete list you can run ansible-playbook --list-tasks harden.yml.

Network

  • Enables TCP wrappers
    • Some people consider TCP wrappers as obsolete and unnecessary, because nowadays firewall(s) take care of this kind of network level access. I disagree, because TCP wrappers still provide an additional layer of control in a case where the firewall(s) might fail for any number of reasons (usually misconfiguration). TCP wrappers also work as an network level ACL for the programs that utilize it and is a "native" control for those programs.
  • IP stack hardening via sysctl settings
  • Creates a basic firewall

Logging

  • Configure log retention time to be 6 months
  • Configures logrotate to shred files
    • NOTE: Read the fine print in SHRED(1): "CAUTION: shred assumes the file system and hardware overwrite data in place. Although this is common, many platforms operate otherwise."
  • Run ansible-playbook --list-tasks --tags logging harden.yml for a full list

Accounting

  • Enables system accounting (sysstat)
    • Sets it's log retention to 99999 days (the logs are really small, so it doesn't eat up disk space)
  • Enables process accounting
  • Run ansible-playbook --list-tasks --tags accounting harden.yml for a full list

Kernel

  • Disables the use of certain kernel modules via modprobe
  • sysctl settings hardening
  • Run ansible-playbook --list-tasks --tags kernel harden.yml for a full list

Filesystem

  • Hardens mount options (creates /etc/fstab.new) (see fstab.awk)
  • Sets strict permissions to users home directories
  • Limits permissions to various configuration files and directories that might contain sensitive content (see permissions tag for a complete list)
  • Clean up /tmp during boot
  • Removes SUID and/or SGID bits from various binaries (see ansible-playbook --list-tasks --tags suid,sgid harden.yml for details)

Application specific

User accounts / authentication / authorization

  • Sets default umask to a more stricter 077 (see https://github.com/pyllyukko/harden.yml/wiki/umask)
  • Sets console session timeout via $TMOUT (Bash)
  • Properly locks down system accounts (0 - SYS_UID_MAX && !root)
    • Lock the user's password
    • Sets shell to /sbin/nologin
    • Expire the account
    • Set RLIMIT_NPROC to 0 in pam_limits for those system accounts that don't need to run any processes
  • Configures the default password inactivity period
    • Run ansible-playbook --list-tasks --tags passwords harden.yml to list all password related tasks
  • Makes minor modifications to existing accounts. See ansible-playbook --list-tasks --tags accounts harden.yml for details.

Authorization

  • Create a strict securetty
  • Creates /etc/ftpusers
  • Restricts the use of cron and at
  • Run ansible-playbook --list-tasks --tags authorization for a full list

PAM

  • Configures /etc/security/namespace.conf
  • Configures /etc/security/access.conf for pam_access (authorization) (see access.conf.j2)
  • Configures /etc/security/pwquality.conf if available
  • Require pam_wheel in /etc/pam.d/su
  • Creates a secure /etc/pam.d/other
  • Configures /etc/security/limits.conf as follows:
    • Disable core dumps
    • Sets maximum amount of processes (or threads, see setrlimit(2))
    • Sets nproc to 0 for system users that don't need to run any processes
  • Run ansible-playbook --list-tasks --tags pam harden.yml to list all PAM related tasks
  • You can also run ansible-playbook --check --diff --tags pam harden.yml to see details of the changes

Miscellaneous

Slackware specific

  • Run ansible-playbook --list-tasks --tags slackware harden.yml for a full list
  • Make Xorg rootless
  • Makes default log files group adm readable (as in Debian)
  • Restricts the use of cron so that only users in the wheel group are able to create cronjobs (as described in /usr/doc/dcron-4.5/README)
  • Mount /proc with hidepid=2
  • Make installpkg store the MD5 checksums
  • Enable process accounting (acct)
  • Does some housekeeping regarding group memberships (see login_defs-slackware.yml)
  • Configures inittab to use shutdown -a (and /etc/shutdown.allow)
  • Reconfigured bunch of services (run ansible-playbook --list-tasks --tags slackware harden.yml | grep '\bservices\b' for a full list)
  • Configures cgroups (v1, because of too old libcgroup) into /etc/cg{config,rules}.conf
  • Enables bootlogd

PAM

  • Creates a custom /etc/pam.d/system-auth, which has the following changes:
    • Use pam_faildelay
    • Use pam_faillock
    • Use pam_access
    • Removes nullok from pam_unix
    • Sets crypt rounds for pam_unix
    • Change password minlen from 6 to 14
  • The following PAM modules are added to /etc/pam.d/postlogin:
    • pam_umask
    • pam_cgroup
    • pam_keyinit
  • Add pam_namespace to /etc/pam.d/{login,sddm,sshd,xdm}
  • Removes auth include postlogin from several files, as postlogin should (and has) only session module types
  • Creates /etc/pam.d/sudo, as that seemed to be missing
  • Disallows the use of su (see su.new)
  • Block /etc/pam.d/remote (see /etc/pam.d/remote)

Debian specific

  • Disables unnecessary systemd services
  • Enables AppArmor
  • Configure SUITE in debsecan
  • Install debsums and enable weekly cron job
  • Installs a bunch of security related packages (see debian_packages.yml)
  • Configures chkrootkit and enables daily checks
  • Configures APT not to install suggested packages

pam-configs

Creates bunch of pam-configs that are toggleable with pam-auth-update:

PAM module Type Description
pam_wheel1 auth Require wheel group membership (su)
pam_succeed_if auth & account Require UID >= 1000 && UID <= 60000 (or 0 & login)
pam_unix1 auth Remove nullok
pam_faildelay auth Delay on authentication failure
pam_ssh_agent_auth auth SSH agent authentication for sudo3
pam_faillock auth & account Deter brute-force attacks
pam_access account Use login ACL (/etc/security/access.conf)
pam_time account /etc/security/time.conf
pam_lastlog account Lock out inactive users (no login in 90 days)
pam_namespace session Polyinstantiated temp directories
pam_umask session Set file mode creation mask
pam_lastlog session Display info about last login and update the lastlog and wtmp files2
pam_pwhistory password Limit password reuse
  1. Not a pam-config, but a modification to existing /etc/pam.d/ files
  2. For all login methods and not just the console login
  3. Disabled by default and requires libpam-ssh-agent-auth package. Needs to have higher priority than krb5 or other password auths.
    • sshd needs to have AllowAgentForwarding yes
    • You need to configure sudo with Defaults env_keep += "SSH_AUTH_SOCK"

Usage

  • Edit the harden.yml and modify hosts or create a completely new playbook by making a copy of the harden.yml file
    • You can comment out the "task sets" that you don't need
  • Check vars.yml in case you want to tweak some of the settings
  • You can check all the tasks before running the playbook by running ansible-playbook --list-tasks harden.yml
  • Harden your system by running ansible-playbook harden.yml
    • You might need to provide credentials with -K or via inventory

Notes

  • Make sure regular users that should be able to login are members of the allowed_group group
  • Sudo hardening:
    • noexec is on by default, so you need to take this into account in your custom rules
    • Interactive shells to root have timeout, so use screen for those longer administrative tasks
  • Rebooting the system after running this is highly recommended
  • The AIDE DB creation is made asynchronously and without polling, so let that finish before rebooting
  • You might want to get additional (unofficial) rules for ClamAV with clamav-unofficial-sigs (although see #425). At least the following rulesets are freely available:
    • Sanesecurity
      • Porcupine ("The following databases are distributed by Sanesecurity, but produced by Porcupine Signatures")
      • bofhland ("The following databases are distributed by Sanesecurity, but produced by bofhland")
    • Linux Malware Detect
    • InterServer
    • URLhaus
  • WARNING: There is a hazard with immutable loginuid enabled in auditing in non-systemd systems (Slackware). See longer description of this in the wiki.
  • Review /etc/fstab.new manually and deploy applicable changes to /etc/fstab

Tags

Tags that you can use with ansible-playbook --tags:

  • pki
  • kernel
  • rng
  • network
    • firewall
    • ipv6
  • logging
  • Filesystem related:
    • permissions
    • fstab
    • suid & sgid
  • Specific software:
    • sysstat
    • ssh
    • rkhunter
    • chkrootkit
    • aide
    • audit (use --skip-tags audit in Slackware if you don't have audit installed)
    • debsecan
    • debsums
    • lynis (to only configure Lynis you can use --tags lynis --skip-tags packages)
    • sudo
    • kerberos
    • clamav (use --skip-tags clamav in Slackware if you don't have clamav installed)
      • yara
    • apparmor
    • cron (also includes tasks regarding at)
    • php
    • apache
      • hsts
    • ntp
    • lightdm
    • gnome
    • tiger
    • john
  • banners
  • AAA:
    • accounting (includes sysstat)
    • authorization
    • passwords
    • accounts
    • pam
      • limits
  • cgroup (Slackware)
  • hidepid (Slackware)
  • shells
  • umask

There are also operating system tags for tasks that only apply to specific OS. You can speed up the hardening by skipping OSs that don't apply. E.g. if you're hardening a Slackware system you can use --skip-tags debian,centos.

Other tags are just metadata for now. You can list all the tags with ansible-playbook --list-tags harden.yml.

Other features

  • There is a lock_account.yml playbook that you can use to lock user accounts. Just modify the hosts & user.
  • Limited hardening for FreeBSD (see freebsd.yml)
  • Experimental feature: If you enable sudo_ids in vars.yml, it enables "Sudo Intrusion Detection" as seen in chapter 9 of Sudo Mastery
    • Only for SHELLS Cmnd_Alias for now
  • You can run make pamcheck to see how the hardening modifies your PAM configurations in Slackware

References

Hardening guides

Some of these documents are quite old, but most of the stuff still applies.

Other docs