In a time when a VPS or cloud instance is set up in minutes and exposed to the Internet from the very first boot, interest has grown in automated hardening tools that implement best practices without leaving loose ends. One of the most mentioned recently within the community is the konstruktoid/hardening repository: a hardening script for Ubuntu (systemd edition) that executes, in a strict order, dozens of controls over kernel, network, systemd, fstab, SSH, logging, packages and more, resulting in a system with a high and consistent security profile.
The goal is not “a bash that does everything without explanation”. On the contrary: the project lists all functions (prefixed with f_) in execution order, details what each changes, and warns about operational consequences (for example, disabling usb-storage blocks USB drives unless USBGuard is configured). The aim: bring reference controls (many aligned with CIS, Ubuntu, and Mozilla guidelines) closer to teams and admins seeking to automate the baseline without yet engaging in complex compliance frameworks.
An orchestration in multiple movements: from kernel to systemd, from network to user
The script follows a logical order that minimizes risks and resolves dependencies between blocks. The sequence, broadly, is:
1) Preflight: permissions and apt
The pre function sets flags of APT and checks basic permissions. Without these foundations, some later steps (installation, cleanup, noexec in /tmp) could fail.
2) Kernel and network: firewall and unnecessary modules
firewall: if UFW is installed, it configures it. Allows SSH from addresses defined in$FW_ADMINto$SSH_PORT(script variable), enables logging, and setsIPT_SYSCTL=/etc/sysctl.conf.disablenet: disables less common network modules (dccp, sctp, rds, tipc).disablefs: turns off rarely used filesystems on modern servers (cramfs, freevxfs, jffs2, ksmbd, hfs, hfsplus, udf).disablemod: disables risky or unnecessary modules (bluetooth, firewire, pcspkr, uvcvideo, usb-storage, etc.). Important note: disablingusb-storageprevents use of USB disks; if external media is needed, the script later contemplates USBGuard.
3) systemd: default coherence and limits
systemdconf: setsCrashShell=no,DumpCore=no, and conservative limits for files and processes (by default,DefaultLimitNOFILE=1024,DefaultLimitNPROC=1024,DefaultLimitCORE=0) both in the globalsystem.confand inuser.conf.resolvedconf: configuressystemd-resolvedwith DNS entries from/etc/resolv.conf>, enabling DNS over TLS in opportunistic mode, DNSSEC in allow-downgrade mode, and fallback DNS to 1.0.0.1.logindconf: hardens login sessions:IdleAction=lockafter 15 minutes,KillUserProcesses=1,RemoveIPC=yes, excludingroot.journalctl: makes the journal persistent (Storage=persistent), compresses, and forwards to syslog. If the rsyslog file is writable, sets$FileCreateMode 0600to protect permissions.
4) Time and files: timesyncd and fstab with secure options
timesyncd: sets NTTP servers (up to four with < 50 ms latency) andRootDistanceMaxSec=1.fstab: adds or adjusts mounts withnosuid,nodev,noexecwhere applicable:/bootand/homewithnosuid,nodevif they exist./var/log,/var/log/audit, and/var/tmpwithnosuid,nodev,noexecif they exist.- Mount
/run/shmand/dev/shmastmpfswithrw,noexec,nosuid,nodev. - Mount
/procwithnosuid,nodev,noexec,relatime,hidepid=2(users can only see their own processes), a classic hardening measure. - Replace
/tmpin fstab and activatetmp.mountfrom systemd to usetmpfs.
5) Package chain and binary cleanup
prelink: reverts pre-linked binaries and uninstalls prelink (avoids altered signatures and helps integrity).aptget_configure: adjusts APT options to harden: prohibits insecure repos, disables recommended suggestions, enables seccomp sandbox, autoclean every 7 days, autoremove automatically, etc.aptget: upgrades the system with available updates.
6) Banners, permissions, and host access
hosts: configures/etc/hosts.allowand/etc/hosts.deny(TCP Wrappers): allowssshd : ALL : ALLOW,ALL: LOCAL, 127.0.0.1, and denies the rest (ALL: ALL).issue: writes authorized use notices into/etc/issue,/etc/issue.net, and/etc/motd, removing the executable permission from/etc/update-motd.d/to prevent dynamic messages that could leak info.
7) Users, PAM, and passwords
sudo: restrictssuto members ofsudogroup withpam_wheeland sets options such asuse_pty,logfile=/var/log/sudo.log,!pwfeedback,!visiblepw,passwd_timeout=1,timestamp_timeout=5.logindefs: hardens/etc/login.defs:UMASK 077,PASS_MIN_DAYS 1,PASS_MAX_DAYS 60,DEFAULT_HOME no,ENCRYPT_METHOD SHA512, and limits of SHA_CRYPT between 10,000 and 65,536 rounds.limitsconf: adds limits in/etc/security/limits.conf: maximum of 10 sessions, core at 0, nproc at 512/1024.adduseranduseradd: reinforce default modes and shell:DIR_MODE=0750,DSHELL=/bin/false,INACTIVE=30.password: installs and copies/etc/security/pwquality.conffor password policies, and removes nullok from PAM to prevent empty passwords.users: removes non-essential system accounts (games, gnats, irc, list, news, sync, uucp).lockroot: locks the root account.
8) Server SSH: a modern and aggressive config
sshconfig/sshdconfig: configuration is generally dumped into/etc/ssh/sshd_config.d/hardening.confifIncludeis used; otherwise, into the mainsshd_config. Among the settings:- Ciphers/KEX/MACs:
Ciphers [email protected],[email protected],aes256-ctr;KexAlgorithms [email protected],ecdh-sha2-...;Macs hmac-sha2-512(-etm),hmac-sha2-256(-etm). - Access:
PasswordAuthentication no,PermitRootLogin no,AllowGroups sudo,Port 22(can be combined with firewall to use an alternative port). - Channels:
AllowTcpForwarding no,AllowAgentForwarding no,X11Forwarding no,Compression no. - Control:
LoginGraceTime 20,MaxAuthTries 3,MaxSessions 3,ClientAliveInterval 200,ClientAliveCountMax 3. - Auditing:
LogLevel VERBOSEandBanner /etc/issue.net. - Hygiene:
StrictModes yes,UseDNS no,UsePAM yes,IgnoreUserKnownHosts yes,PermitUserEnvironment no.
- Ciphers/KEX/MACs:
9) Logging and auditing: journal, rsyslog, AIDE, rkhunter
- Already mentioned journal; the script also adjusts
/etc/rsyslog.confif writable. aide: excludes Docker and LXCFS, generates a baseline, and creates a systemd timer for periodic checks.rkhunter: enables daily cron, auto-generation, and alerts.aide_post,aide_timer: complete the integrity schedule.
10) Email and core dumps
postfix: installs and configures withinet_interfaces=loopback-only,disable_vrfy_command=yes, a sober banner, and default client restrictions; prepared for local alerts.coredump: disables core dumps (Storage=none,ProcessSizeMax=0) to prevent sensitive data leakage on disk.
11) USBGuard, AppArmor, PATH, umask
usbguard: installs and activates rules to control allowed USB devices.aa_enforce: enforces available AppArmor profiles.pathandumask: setsumask 077and secure PATHs: for root (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin) and others (/usr/local/bin:/usr/sbin:/usr/bin:/bin:/snap/bin).
12) Packages: installing protective ones and removing unnecessary ones
package_install: installs acct, aide-common, cracklib-runtime, debsums, gnupg2, haveged, libpam-pwquality, libpam-tmpdir, needrestart, openssh-server, postfix, psad, rkhunter, sysstat, systemd-coredump, tcpd, update-notifier-common, vlock.package_remove: removes apport*, autofs, avahi*, beep, git (if not needed on server), pastebinit, popularity-contest, rsh*, rsync, talk*, telnet*, tftp*, whoopsie, xinetd, yp-tools/ypbind.restrictcompilers: changes mode to 0750 on installed compilers to prevent misuse.
13) Cron, at, host configuration, and console access
cron: disablesatdand allowscron/atonly for root.rhosts: deleteshosts.equivand any.rhosts.rootaccess: restricts access via/etc/security/access.confand/etc/securetty.
14) Cleanup and final checks
aptget_noexec: adds hooksPre-Invoke/Post-Invoketo APT so that updates won't fail on systems with/tmpmounted asnoexec.aptget_clean: runs clean/autoremove.systemddeltaandpost: housekeeping.checkreboot: alerts if a reboot is needed.
Advantages: order, coherence, and alerts about "what might break"
The strength of the script lies in doing many things in the correct order and leaving a clear trail. Typical cases:
- fstab secured without breaking
/tmp: switches totmpfsmanaged by systemd and adds APT hooks to preventdpkgfrom failing due tonoexec. - USB: blocks
usb-storagebut installs USBGuard to permit authorized devices if needed. - SSH: moves hardening configurations to
/etc/ssh/sshd_config.d/ifIncludeis used, avoiding overwriting local configs; and documents where it writes. - Logging: consolidates journalctl with persistence, compression, and forwarding to syslog, while protecting permissions on files created by rsyslog.
It's not “magic”: in complex environments, it's advisable to review each function, adapt whitelists, groups, and ports, and test on test machines or snapshots before production.
Who is it for? What are the benefits over doing it manually?
For administrators and teams wanting a robust baseline on Ubuntu without rewriting policies from scratch. Compared to manual setup, it offers:
- Idempotency (if you respect order and variables),
- Coherence (all blocks are considered as a set), and
- Time savings (install, configure, clean, and verify in one pass).
It does not replace CIS Benchmarks or compliance frameworks, but brings the system closer to those recommendations.
FAQs
Can it break my production server?
Any aggressive hardening can cause regressions if there are unforeseen dependencies (e.g., usb-storage if you use USB disks, or noexec on /tmp if a build requires it). The safe approach: snapshot, test in staging, review variables (admin IPs, $SSH_PORT, groups, and services), and apply step by step.
Can I pick which features to run and which to skip?
Yes. The repository documents the ordered list; you can comment out or invoke selectively functions (all start with f_). Keep the relative order (for example, do not configure fstab “at the end” if you depend on tmpfs in /tmp earlier).
Does it replace CIS Benchmarks or tools like Ansible?
No. It's a practical hardening tool for Ubuntu systemd. For compliance (CIS, ISO 27001, etc.), you'll need to map controls and, if scaling, convert or wrap these functions in Ansible/Terraform with inventories and tests.
Which changes are most “sensitive”?
Mounting options (noexec/nosuid/nodev on /tmp, /proc, /var/*), module deactivations (especially usb-storage), strict SSH policies (no password, banner, disabled port forwards), and package cleanup (removing rsync if it was used, for example). Review these according to your case.
Sources
Note: All details in this piece derive from the documentation of the linked repository (function descriptions, parameters, and warnings). It is recommended to review the README and included config files (
config/*) before running in critical environments.

