# hardening **Repository Path**: mirrors_opencollective/hardening ## Basic Information - **Project Name**: hardening - **Description**: Hardening Ubuntu. Systemd edition. - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-25 - **Last Updated**: 2026-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README image::logo/horizontal.png[Ubuntu Hardening] = Hardening Ubuntu. Systemd edition. :icons: font A quick way to make a Ubuntu server a bit more secure. Tested on `18.04 Bionic Beaver`, `18.10 Cosmic Cuttlefish` and `Ubuntu 19.04 Disco Dingo`. Systemd required. If you're just interested in the security focused systemd configuration, it's available as a link:systemd.adoc[separate document]. If you're interested in testing your host settings, you'll find the link:README.adoc#tests[instructions here]. If you're using Ansible, a playbook with most of the above functions implemented is available in my Ansible repository https://github.com/konstruktoid/ansible-role-hardening[konstruktoid/ansible-role-hardening]. NOTE: This is a constant work in progress. Make sure you understand what it does. `Read the code`. == Index .. link:README.adoc#howto[Howto] ... link:README.adoc#partition-the-system[Partition the system] ... link:README.adoc#login-set-a-grub2-password-configure-and-run-ubuntush[Login, set a Grub2 password, configure and run ubuntu.sh] .. link:README.adoc#configuration-options[Configuration options] .. link:README.adoc#functions[Functions] ... link:README.adoc#function-list[Function list] .... link:README.adoc#01_pre[01_pre] .... link:README.adoc#02_firewall[02_firewall] .... link:README.adoc#03_disablenet[03_disablenet] .... link:README.adoc#04_disablemnt[04_disablemnt] .... link:README.adoc#05_systemdconf[05_systemdconf] .... link:README.adoc#06_journalctl[06_journalctl] .... link:README.adoc#07_timesyncd[07_timesyncd] .... link:README.adoc#08_fstab[08_fstab] .... link:README.adoc#09_prelink[09_prelink] .... link:README.adoc#10_aptget[10_aptget] .... link:README.adoc#11_hosts[11_hosts] .... link:README.adoc#12_logindefs[12_logindefs] .... link:README.adoc#13_sysctl[13_sysctl] .... link:README.adoc#14_limits[14_limits] .... link:README.adoc#15_adduser[15_adduser] .... link:README.adoc#16_rootaccess[16_rootaccess] .... link:README.adoc#17_packages[17_packages] .... link:README.adoc#18_sshdconfig[18_sshdconfig] .... link:README.adoc#19_password[19_password] .... link:README.adoc#20_cron[20_cron] .... link:README.adoc#21_ctraltdel[21_ctraltdel] .... link:README.adoc#22_auditd[22_auditd] .... link:README.adoc#23_disablemod[23_disablemod] .... link:README.adoc#24_aide[24_aide] .... link:README.adoc#25_rhosts[25_rhosts] .... link:README.adoc#26_users[26_users] .... link:README.adoc#27_suid[27_suid] .... link:README.adoc#28_umask[28_umask] .... link:README.adoc#29_apparmor[29_apparmor] .... link:README.adoc#30_path[30_path] .... link:README.adoc#31_logindconf[31_logindconf] .... link:README.adoc#32_resolvedconf[32_resolvedconf] .... link:README.adoc#33_rkhunter[33_rkhunter] .... link:README.adoc#34_issue[34_issue] .... link:README.adoc#35_apport[35_apport] .... link:README.adoc#36_lockroot[36_lockroot] .... link:README.adoc#37_coredump[37_coredump] .... link:README.adoc#38_postfix[38_postfix] .... link:README.adoc#39_motdnews[39_motdnews] .... link:README.adoc#40_usbguard[40_usbguard] .... link:README.adoc#41_compilers[41_compilers] .... link:README.adoc#98_systemddelta[98_systemddelta] .... link:README.adoc#99_reboot[99_reboot] ... link:README.adoc#function-execution-order[Function execution order] .. link:README.adoc#tests[Tests] ... link:README.adoc#test-automation-using-vagrant[Test automation using Vagrant] ... link:README.adoc#testing-a-host[Testing a host] .. link:README.adoc#structure[Structure] .. link:README.adoc#recommended-reading[Recommended reading] .. link:README.adoc#contributing[Contributing] == Howto Start the installation of the server. + Pick language, keyboard layout, timezone and so on as you usually would. === Partition the system [source,shell] ---- / /boot (rw) /home (rw,nosuid,nodev) swap /var /var/log (rw,nosuid,nodev,noexec) /var/log/audit (rw,nosuid,nodev,noexec) ---- Note that `/tmp` and `/var/tmp` will be added automatically by the script. === Login, set a Grub2 password, configure and run ubuntu.sh Do not add any packages. + Log in. + Select a Grub2 password (using `grub-mkpasswd-pbkdf2`). + Download the script using `git clone https://github.com/konstruktoid/hardening.git`. + Change the configuration options in the `ubuntu.cfg` file and last but not least run the script, `sudo bash ubuntu.sh`. + == Configuration options [source,shell] ---- FW_ADMIN='127.0.0.1' // <1> SSH_GRPS='sudo' // <2> SYSCTL_CONF='./misc/sysctl.conf' // <3> AUDITD_MODE='1' // <4> AUDITD_RULES='./misc/audit-base.rules ./misc/audit-aggressive.rules ./misc/audit-docker.rules' // <5> LOGROTATE_CONF='./misc/logrotate.conf' // <6> NTPSERVERPOOL='0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org pool.ntp.org' // <7> TIMEDATECTL='' // <8> VERBOSE='N' // <9> AUTOFILL='N' // <10> CHANGEME='' // <11> # Configuration files ADDUSER='/etc/adduser.conf' AUDITDCONF='/etc/audit/auditd.conf' AUDITRULES='/etc/audit/rules.d/hardening.rules' COMMONPASSWD='/etc/pam.d/common-password' COMMONACCOUNT='/etc/pam.d/common-account' COMMONAUTH='/etc/pam.d/common-auth' DEFAULTGRUB='/etc/default/grub' DISABLEMNT='/etc/modprobe.d/disablemnt.conf' DISABLEMOD='/etc/modprobe.d/disablemod.conf' DISABLENET='/etc/modprobe.d/disablenet.conf' JOURNALDCONF='/etc/systemd/journald.conf' LIMITSCONF='/etc/security/limits.conf' LOGINDCONF='/etc/systemd/logind.conf' LOGINDEFS='/etc/login.defs' LOGROTATE='/etc/logrotate.conf' PAMLOGIN='/etc/pam.d/login' RESOLVEDCONF='/etc/systemd/resolved.conf' RKHUNTERCONF='/etc/default/rkhunter' SECURITYACCESS='/etc/security/access.conf' SSHDFILE='/etc/ssh/sshd_config' SYSCTL='/etc/sysctl.conf' SYSTEMCONF='/etc/systemd/system.conf' TIMESYNCD='/etc/systemd/timesyncd.conf' UFWDEFAULT='/etc/default/ufw' USERADD='/etc/default/useradd' USERCONF='/etc/systemd/user.conf' ---- <1> The IP addresses that will be able to connect with SSH, separated by spaces. <2> Which group the users have to be member of in order to acess via SSH, separated by spaces. <3> Stricter sysctl settings. <4> Auditd failure mode. 0=silent 1=printk 2=panic. <5> Auditd rules. <6> Logrotate settings. <7> NTP server pool. <8> Add a specific time zone or use the system default by leaving it empty. <9> If you want all the details or not. <10> Let the script guess the `FW_ADMIN` and `SSH_GRPS` settings. <11> Add something just to verify that you actually glanced the code. == Functions === Function list ==== 01_pre Setup script, sets APT flags and permission checks. ==== 02_firewall RHEL-07-040520 Enable `ufw`, use `/etc/sysctl.conf`, and allow port 22 from `$FW_ADMIN`. ==== 03_disablenet CCE-26828-4, CCE-27106-4 Disable `dccp` `sctp` `rds` `tipc` protocols. ==== 04_disablemnt CCE-80137-3, CCE-80138-1, CCE-80139-9, CCE-80140-7, CCE-80141-5, CCE-80142-3, CCE-80143-1, UBTU-16-010070 Disable `cramfs` `freevxfs` `jffs2` `hfs` `hfsplus` `squashfs` `udf` `vfat` file systems. ==== 05_systemdconf Disable coredumps and crash shells, set `DefaultLimitNOFILE` and `DefaultLimitNPROC` to 1024. ==== 06_journalctl Compress logs, forward to syslog and make log storage persistent. ==== 07_timesyncd Add four NTP-servers with a latency < 50ms from `$NTPSERVERPOOL`. ==== 08_fstab Configure `/tmp/` and `/var/tmp/`. Remove floppy drivers from `/etc/fstab` and add `hidepid=2` to `/proc`. ==== 09_prelink CCE-27078-5 Undo prelinking, and remove `prelink` package. ==== 10_aptget CCE-26895-3, UBTU-16-010010, UBTU-16-010560, UBTU-16-010570 Configure `dpkg` and `apt-get`. `apt-get` update and upgrade. ==== 11_hosts V-72315 `/etc/hosts.allow` and `/etc/hosts.deny` restrictions. ==== 12_logindefs CCE-80205-8, UBTU-16-010150, UBTU-16-010170, UBTU-16-010190, UBTU-16-010210, UBTU-16-010220, UBTU-16-010640 Modify `/etc/login.defs`, e.g. `UMASK`, password age limits and `SHA_CRYPT_MAX_ROUNDS`. ==== 13_sysctl Update `$SYSCTL` with `$SYSCTL_CONF`. ==== 14_limits CCE-80169-6, V-72049 Set hard and soft limits. ==== 15_adduser UBTU-16-010280 Set `/bin/false` as default shell when adding users. ==== 16_rootaccess Limit `/etc/securetty` to `console`, and `root` from 127.0.0.1 in `/etc/security/access.conf`. ==== 17_packages UBTU-16-010050, UBTU-16-010500, UBTU-16-010600 Installs `acct` `aide-common` `apparmor-profiles` `apparmor-utils` `auditd` `debsums` `haveged` `libpam-apparmor` `libpam-cracklib` `libpam-tmpdir` `openssh-server` `postfix` `rkhunter` `vlock`. Removes `avahi*` `beep` `popularity-contest` `rsh*` `talk*` `telnet*` `tftp*` `yp-tools` `ypbind` `xinetd`. ==== 18_sshdconfig CCE-27471-2, CCE-27082-7, CCE-27433-2, CCE-27314-4, CCE-27363-1, CCE-27413-4, CCE-80222-3, CCE-80223-1, CCE-80225-6, CCE-80224-9, CCE-27445-6, UBTU-16-030200, UBTU-16-030210, UBTU-16-030270, UBTU-16-030350 Configure the `OpenSSH`-daemon. ==== 19_password UBTU-16-010090, UBTU-16-010100, UBTU-16-010110, UBTU-16-010120, UBTU-16-010120, UBTU-16-010130, UBTU-16-010140, UBTU-16-010180, UBTU-16-010230, UBTU-16-010240, UBTU-16-010250, UBTU-16-010290, UBTU-16-010320, UBTU-16-010340 Configure `pam_cracklib.so` and `pam_tally2.so`. ==== 20_cron CCE-27323-5, CCE-80345-2 Allow `root` to use `cron`. Mask `atd`. ==== 21_ctraltdel CCE-27511-5, UBTU-16-010630 Disable Ctrl-alt-delete. ==== 22_auditd CCE-27407-6, UBTU-16-020000 Configure `auditd`, use `$AUDITD_RULES` and set failure mode `$AUDITD_MODE`. ==== 23_disablemod CCE-27327-6, CCE-27277-3, UBTU-16-010580 Disable `bluetooth` `bnep` `btusb` `firewire-core` `n_hdlc` `net-pf-31` `pcspkr` `soundcore` `thunderbolt` `usb-midi` `usb-storage` kernel modules. ==== 24_aide CCE-27096-7, UBTU-16-020000, UBTU-16-020010 Configure `aide`. ==== 25_rhosts CCE-27406-8 Remove `hosts.equiv` and `.rhosts`. ==== 26_users UBTU-16-010650 Remove `games` `gnats` `irc` `list` `news` `sync` `uucp` users. ==== 27_suid Remove `suid` bits from `/bin/fusermount` `/bin/mount` `/bin/ping` `/bin/ping6` `/bin/su` `/bin/umount` `/usr/bin/bsd-write` `/usr/bin/chage` `/usr/bin/chfn` `/usr/bin/chsh` `/usr/bin/mlocate` `/usr/bin/mtr` `/usr/bin/newgrp` `/usr/bin/pkexec` `/usr/bin/traceroute6.iputils` `/usr/bin/wall` `/usr/sbin/pppd`. ==== 28_umask CCE-80202-5, UBTU-16-010060 Set `bash` and `/etc/profile` umask. ==== 29_apparmor UBTU-16-010600, UBTU-16-010610, UBTU-16-010620 Enforce present `apparmor` profiles. ==== 30_path UBTU-16-010780 Set `root` path to `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, and user path to `/usr/local/bin:/usr/bin:/bin`. ==== 31_logindconf Configure `systemd/logind.conf` and use `KillUserProcesses`. ==== 32_resolvedconf Configure `systemd/resolved.conf`. ==== 33_rkhunter Configure `rkhunter`. ==== 34_issue Update `/etc/issue` `/etc/issue.net` `/etc/motd`. ==== 35_apport Disable `apport`, `ubuntu-report` and `popularity-contest`. ==== 36_lockroot Lock the `root` user account. ==== 37_coredump Disable coredumps with `systemd/coredump.conf`. ==== 38_postfix Disable the `VRFY` command, configure `smtpd_banner`, `smtpd_client_restrictions` and `inet_interfaces`. ==== 39_motdnews Disable `motd-news`. ==== 40_usbguard Install and configure `usbguard`. ==== 41_compilers Restrict compiler access. ==== 98_systemddelta If verbose, show `systemd-delta`. ==== 99_reboot Print if a reboot is required. === Function execution order [source,shell] ---- f_pre f_firewall f_disablenet f_disablefs f_disablemod f_systemdconf f_resolvedconf f_logindconf f_journalctl f_timesyncd f_fstab f_prelink f_aptget_configure f_aptget f_hosts f_issue f_logindefs f_sysctl f_limitsconf f_adduser f_rootaccess f_package_remove f_package_install f_coredump f_usbguard f_postfix f_apport f_motdnews f_rkhunter f_sshdconfig f_password f_cron f_ctrlaltdel f_auditd f_aide f_rhosts f_users f_lockroot f_aptget_clean f_suid f_restrictcompilers f_umask f_path f_aa_enforce f_aide_post f_aide_timer f_aptget_noexec f_systemddelta f_checkreboot ---- == Tests There are approximately 500 https://github.com/sstephenson/bats[Bats tests] for most of the above settings available in the link:tests/[tests directory]. [source,shell] ---- git clone https://github.com/konstruktoid/hardening.git cd tests/ sudo bats . ---- === Test automation using Vagrant Running `bash ./runTests.sh` will use https://www.vagrantup.com/[Vagrant] to run all above tests and https://github.com/CISOfy/Lynis[Lynis] on all supported Ubuntu versions. The script will generate link:TESTRESULTS.adoc[TESTRESULTS.adoc]. === Testing a host Running `bash ./runHostTests.sh`, located in the link:tests/[tests directory], will generate a `TESTRESULTS-.adoc` report. == Structure [source,shell] ---- . ├── LICENSE ├── README.adoc ├── Vagrantfile ├── action-shellcheck │   ├── Dockerfile │   ├── README.md │   └── entrypoint.sh ├── checkScore.sh ├── config │   ├── aidecheck.service │   ├── aidecheck.timer │   ├── initpath.sh │   └── tmp.mount ├── createPartitions.sh ├── genIndex.sh ├── logo │   ├── horizontal.png │   ├── icon.png │   └── vertical.png ├── misc │   ├── audit-aggressive.rules │   ├── audit-base.rules │   ├── audit-docker.rules │   ├── audit.footer │   ├── audit.header │   ├── auditgenerator.sh │   ├── fdcount.sh │   ├── logrotate.conf │   ├── proc_check.sh │   ├── sysctl.conf │   └── systemd_scan.sh ├── renovate.json ├── runTests.sh ├── scripts │   ├── 01_pre │   ├── 02_ufw │   ├── 03_disablenet │   ├── 04_disablefs │   ├── 05_systemdconf │   ├── 06_journalctl │   ├── 07_timesyncd │   ├── 08_fstab │   ├── 09_prelink │   ├── 10_aptget │   ├── 11_hosts │   ├── 12_logindefs │   ├── 13_sysctl │   ├── 14_limits │   ├── 15_adduser │   ├── 16_rootaccess │   ├── 17_packages │   ├── 18_sshdconfig │   ├── 19_password │   ├── 20_cron │   ├── 21_ctraltdel │   ├── 22_auditd │   ├── 23_disablemod │   ├── 24_aide │   ├── 25_rhosts │   ├── 26_users │   ├── 27_suid │   ├── 28_umask │   ├── 29_apparmor │   ├── 30_path │   ├── 31_logindconf │   ├── 32_resolvedconf │   ├── 33_rkhunter │   ├── 34_issue │   ├── 35_apport │   ├── 36_lockroot │   ├── 37_coredump │   ├── 38_postfix │   ├── 39_motdnews │   ├── 40_usbguard │   ├── 41_compilers │   ├── 98_systemddelta │   └── 99_reboot ├── systemd.adoc ├── tests │   ├── 01_pre.bats │   ├── 02_ufw.bats │   ├── 03_disablenet.bats │   ├── 04_disablefs.bats │   ├── 05_systemdconf.bats │   ├── 06_journalctl.bats │   ├── 07_timesyncd.bats │   ├── 08_fstab.bats │   ├── 10_aptget.bats │   ├── 11_hosts.bats │   ├── 12_logindefs.bats │   ├── 13_sysctl.bats │   ├── 14_limits.bats │   ├── 15_adduser.bats │   ├── 16_rootaccess.bats │   ├── 17_packages.bats │   ├── 18_sshd.bats │   ├── 19_password.bats │   ├── 20_cron.bats │   ├── 21_ctrlaltdel.bats │   ├── 22_auditd.bats │   ├── 23_disablemod.bats │   ├── 24_aide.bats │   ├── 26_users.bats │   ├── 27_suid.bats │   ├── 28_umask.bats │   ├── 29_apparmor.bats │   ├── 31_logindconf.bats │   ├── 32_resolvedconf.bats │   ├── 33_rkhunter.bats │   ├── 35_apport.bats │   ├── 36_lockroot.bats │   ├── 37_coredump.bats │   ├── 38_postfix.bats │   ├── 39_motdnews.bats │   ├── 40_usbguard.bats │   ├── 41_compilers.bats │   ├── 99_misc.bats │   ├── runHostTests.sh │   └── test_helper.bash ├── ubuntu.cfg └── ubuntu.sh ---- == Recommended reading https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=independentlinux.100[CIS Distribution Independent Linux Benchmark v1.0.0] + https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=operating-systems%2Cunix-linux[Canonical Ubuntu 16.04 LTS STIG - Ver 1, Rel 2] + https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=operating-systems%2Cunix-linux[Red Hat Enterprise Linux 7 - Ver 2, Rel 3 STIG ] + https://www.cisecurity.org/benchmark/ubuntu_linux/[CIS Ubuntu Linux Benchmarks] + https://wiki.ubuntu.com/Security/Features + https://help.ubuntu.com/community/StricterDefaults + https://www.ncsc.gov.uk/collection/end-user-device-security/platform-specific-guidance/ubuntu-18-04-lts[EUD Security Guidance: Ubuntu 18.04 LTS] == Contributing Do you want to contribute? That's great! Contributions are always welcome, no matter how large or small. If you found something odd, feel free to https://github.com/konstruktoid/hardening/issues/[submit a new issue], improve the code by https://github.com/konstruktoid/hardening/pulls[creating a pull request], or by https://opencollective.com/konstruktoid_hardening#sponsor[sponsoring this project]. Logo by https://github.com/reallinfo[reallinfo].