2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00
2025-06-12 20:07:19 +02:00

Table of Contents

Static Badge   Static Badge   Static Badge   Static Badge   Static Badge   Static Badge   Static Badge   Static Badge   Static Badge   Static Badge  

1. CISS.2024.vps.bookworm.hardening

Centurion Intelligence Consulting Agency Information Security Standard 2024
Debian Bookworm Hardening Script
Mainline Version 5.42
V5.42.128.2024.10.30

This is a digitally signed, self-verifying shell script for setting up a hardened Debian Bookworm Server environment that relies on the latest best practices in server and service hardening, incl. LUKS2 /boot encryption, Ephemeral SWAP encryption, Ephemeral /tmp encryption and LVM on RAID on dm-crypt incl. dm-integrity HA setup, including locked root, deactivated remote root login via SSH, a tcp wrapper for SSH and 2FA hardened sudoer user access, achieving a relative Lynis score of up to 95% without breaking functionality. Complete bash error handling, including the interception of unintended SIGINT, CTRL-C, user input.

Check out more CenturionNet Services | CenturionDNS Resolver | CenturionDNS Blocklist | CenturionNet Status | CenturionMeet | Contact the author

Please note: All my signing keys are contained in a HSM and the signing environment is air gapped. Next step: move to a room gapped environment ^^

Please read carefully before installation!

2. Key Words

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14], [RFC2119], [RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Quick start

  1. You SHOULD check Prerequisites, Tested and recommended VPS Provider and Troubleshooting for known issues before installation.
  2. You MUST note the warning. Especially regarding the SSH Ultra Hardening and Root Ultra Hardening modules.
  3. For further preparations refer to the following Tutorial on how to install a fresh Debain Bookworm Server: CISS.2024.bookworm.installation.
  4. A detailed Tutorial for this script is available at: CISS.2024.vps.bookworm.hardening.
  5. If you are installing Debian GNU/Linux from a minimal CD by using the network, you MUST install curl package before you can download the hardening script.
  6. You MUST be root to run this script.
apt install curl --no-install-recommends -y
mkdir /root/server-scripts
cd /root/server-scripts
alias scurl="curl --proto '=https' --tlsv1.3 -sSf -O"
SHA_CNF="16ee3d8aa240ac676b720a841f79e01443348978b8beecf4d89e85d10c347654b1e9ac66e88d2e2838e8c48002f1f3c9 hardening.conf"
SHA_SCP="a9b7defcc0f460d6867cb0768e64b3efc00e3f2be2058ec489257c31112caed60963ceaf378c73786ae81d82ce177439 hardening.sh"
SHA_TXT="4d49927adb4f1a1585d8ff807008aef4371be218c830ecb69fca8cffd23eac27ecb7febd2ce63e176b3aaeb270da110a password.txt"

Download hardening.conf

scurl https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening/raw/branch/main/hardening.conf
clear
if echo "${SHA_CNF}" | sha384sum -c; then
  echo -e "\e[92mhardening.conf: SHA-384 checksum: OK \e[0m"
  chmod 0600 hardening.conf
else
  echo -e "\e[91mhardening.conf: SHA-384 checksum: failed! You MUST NOT proceed. You SHOULD contact the author please. \e[0m"
  yes | rm -f hardening.conf
fi

Download hardening.sh

scurl https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening/raw/branch/main/hardening.sh
clear
if echo "${SHA_SCP}" | sha384sum -c; then
  echo -e "\e[92mhardening.sh: SHA-384 checksum: OK \e[0m"
  chmod 0700 hardening.sh
else
  echo -e "\e[91mhardening.sh: SHA-384 checksum: failed! You MUST NOT proceed. You SHOULD contact the author please. \e[0m"
  yes | rm -f hardening.sh
fi

Download password.txt

scurl https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening/raw/branch/main/password.txt
clear
if echo "${SHA_TXT}" | sha384sum -c; then
  echo -e "\e[92mpassword.txt: SHA-384 checksum: OK \e[0m"
  chmod 0600 password.txt
else
  echo -e "\e[91mpassword.txt: SHA-384 checksum: failed! You MUST NOT proceed. You SHOULD contact the author please. \e[0m"
  yes | rm -f password.txt
fi

You MUST edit hardening.conf, and if you are using the LVM on RAID on dm-integrity HA setup also the ./password.txt file in advance, before you start the script. Then run:

./hardening.sh --install 

or

./hardening.sh --install --debug --priority -19

for detailed debugging information logged in /root/hardening/log/${SCRIPT_START}_debug.log and to change the nice priority value of the script and its children to something like -19 (allowed values are -19 to 19).

  1. Select the NIC if applicable and you will be prompted to check and edit hardening.conf to suit your needs if you have not already done so, in which case simply quit nano with CTRL-X.
  2. For detailed installation instructions for Contabo, Hetzner, Netcup and Proxmox installations, please see Main Installation

4. Background of this script

A short summary for the existence of the script as it is. You will notice - and this is obvious - that I trust Netcup, Hetzner and Contabo, and when it comes to hypervisors, I strongly recommend using Proxmox. Surely it can be argued that in the political situation and the ever shrinking space to express one's opinion it is a good choice to choose Germany as the location of the VPS / Bare Metal provider. But that is another discussion.

Also, when it comes to setting up servers, I am focused on Debian due to the vast community that supports this distro.

Stating this, I was looking to automate all my running and still to come services in a way that I could easily handle these three different types of Hosters and the Proxmox case in a reliable and smoothless way to secure the freshly installed server setups to a very high level and the trade off that many of the services to be installed later will not break or at least require a minimum of maintencane and tweaks.

5. Upcoming Features

  • Work in progress as of 30.10.2024:
    • More granular selection of which modules to install and harden.
    • Support for arm64. Still issues to be addressed.
    • Tutorials: Update to new V5 Mainline in progress.
    • Modularisation.
    • Additional SSH hardening via:
      • /etc/ssh/sshd_config Match Address.
      • ufw allow from <JUMPHOST_IP> to any port <SERVER_PORT> proto tcp limit.
      • ufw deny to any port <SERVER_PORT> proto tcp.
    • Long-run features:
      • Rollback capabilities.
      • Idempotent capabilities.

6. Features of the script

  • The script and all modules and assets downloaded by my scripts are cryptographically signed with my private OpenPGP key, see the public key fingerprint here, which resides in an HSM. All signing operations are performed on an air-gapped system. Help me move to the next level of security: a room-gapped signing environment. All cryptographic verification operations can be disabled for easy and convenient script editing. A comprehensive list of all my keys and certificates in use is available here via DANE/TLSA and DNSSEC secured https only and https preloaded website.

  • Self verification of all downloaded assets. Can be disabled for easy and convenient script editing.

  • If there are any errors in the verification process of cryptographically signed scripts, assets and modules, the script will automatically fail immediately.

  • Advanced error and signal and debug trap functions. Returns exit code, line number, executed command, module name and PID both on screen and in the respective log files:

    • /root/hardening/log/${SCRIPT_START}_debug.log.
    • /root/hardening/log/${SCRIPT_START}_error.log.
    • /root/hardening/log/${SCRIPT_START}_install.log.
  • Further detailed logs available in /root/hardening/log, including logging of user input (without logging of credentials, for clarity) and coloured log file.

  • Debug mode can be invoked with ./hardening.sh --install --debug.

  • You will be prompted and the SSH hardening module will pause to check that you have access via the new SSH settings. A rollback capability is offered.

  • Double-checking of the grub password settings (if selected), the fstab hardening feature, the root password change module and the /boot encryption module (if selceted).

  • All files touched by the script are copied /root/hardening/backup/*.bak. No files are overwritten: see bash environment settings below.

  • Select the trust level of the signing key I have provided.

  • For security reasons, the bash history is also deleted and cleared after the setup routine.

  • Take advantage of the following bash error handling options:

set -o errexit   # Exit script when a command exits with non-zero status, same as "set -e".
set -o errtrace  # Any trap on ERR are inherited in a subshell environment.
set -o functrace # Any trap on DEBUG and RETURN are inherited in a subshell environment.
set -o nounset   # Exit script on use of an undefined variable, same as "set -u".
set -o pipefail  # Makes pipeline return the exit status of the last command in the pipe that failed.
set -o noclobber # Prevent overwriting.
set +o history   # Temporarily turn off history, to avoid sensitive information leakage.

6.1. Main Hardening Features

See the Tutorial for a more detailed overview of the implemented hardening settings.

6.1.1. Extended Full Disk Encryption Routine including /boot encryption

  • Optional full disk encryption, including /boot - Unlocking LUKS devices from GRUB. So called "full disk encryption" is often a misnomer, because there is typically a separate plaintext partition holding /boot. For instance the Debian Installer does this in its "encrypted LVM" partitioning method. Since not all bootloaders are able to unlock LUKS devices, a plaintext /boot is the only solution that works for all of them. However, GRUB2 is (since Jessie) able to unlock LUKS devices with its cryptomount command, which therefore enables encryption of the /boot partition as well: using that feature reduces the amount of plaintext data written to disk. Works on UEFI and BIOS environments.

6.1.2. Ephemeral Swap Encryption

6.1.3. Ephemeral /tmp Encryption

  • Optional ephemeral encryption of the /tmp partition. In this scenario, the encrypted /tmp partition is initialised with a new random key at boot time to maximise security. The permissions are also set to 1777 at boot time.

6.1.4. LVM on RAID on dm-integrity encrypted High Availability Setup

  • Optional module to set up a complete LVM on mdadm on dm-crypt, including dm-integrity setup. Just specify the disks, RAID level and other variables in a separate section of the hardening.conf file, and set a password for the setup process in password.txt. The script will do the rest. Please note that dm-integrity needs to wipe the entire disk to initialise the integrity checksum, so depending on the size and speed of your disks, this can take up to several hours. Therefore, each operation is done in parallel by the script, so that you only have to wait once to initialise the disks.

6.1.5. Boot parameters

  • Slab merging is disabled which significantly increases the difficulty of heap exploitation by preventing overwriting objects from merged caches and by making it harder to influence slab cache layout.
    GRUB_CMDLINE_LINUX="slab_nomerge"

  • Memory zeroing at allocation and free time is enabled to mitigate some use-after-free vulnerabilities and erase sensitive information in memory.
    GRUB_CMDLINE_LINUX="init_on_alloc=1 init_on_free=1"

  • Page allocator freelist randomization is enabled.
    GRUB_CMDLINE_LINUX="page_alloc.shuffle=1"

  • Kernel Page Table Isolation is enabled to mitigate Meltdown and increase KASLR effectiveness.
    GRUB_CMDLINE_LINUX="pti=on"

  • vsyscalls are disabled as they are obsolete, are at fixed addresses and thus, are a potential target for ROP.
    GRUB_CMDLINE_LINUX="vsyscall=none"

  • The kernel panics on oopses to thwart certain kernel exploits.
    GRUB_CMDLINE_LINUX="oops=panic"

  • Enables randomisation of the kernel stack offset on syscall entries (introduced in kernel 5.13).
    GRUB_CMDLINE_LINUX="randomize_kstack_offset=on"

  • Enable a subset of known mitigations for CPU vulnerabilities and disable SMT.
    GRUB_CMDLINE_LINUX="mitigations=auto,nosmt"

  • Enables strict enforcement of IOMMU TLB invalidation so devices will never be able to access stale data contents.
    GRUB_CMDLINE_LINUX="iommu=force iommu.passthrough=0 iommu.strict=1"

  • Enables IOMMU to prevent DMA attacks.
    GRUB_CMDLINE_LINUX="intel_iommu=on amd_iommu=force_isolation"

  • Disable the busmaster bit on all PCI bridges during very early boot to avoid holes in IOMMU.
    GRUB_CMDLINE_LINUX="efi=disable_early_pci_dma"

  • Restrict access to debugfs since it can contain a lot of sensitive information.
    GRUB_CMDLINE_LINUX="debugfs=off"

  • Distrusts the bootloader for initial entropy at boot.
    GRUB_CMDLINE_LINUX="random.trust_bootloader=off"

  • Entropy collection improvements.
    /usr/lib/modules-load.d/30_security-misc.conf jitterentropy_rng

6.1.6. Enables known mitigations for CPU vulnerabilities

  • Enable mitigations for both Spectre Variant 2 (indirect branch speculation) and Intel branch history injection (BHI) vulnerabilities.
    GRUB_CMDLINE_LINUX="spectre_v2=on spectre_bhi=on"

  • Disable Speculative Store Bypass (Spectre Variant 4).
    GRUB_CMDLINE_LINUX="spec_store_bypass_disable=on"

  • Enable mitigations for the L1TF vulnerability through disabling SMT and L1D flush runtime control.
    GRUB_CMDLINE_LINUX="l1tf=full,force"

  • Enable mitigations for the MDS vulnerability through clearing buffer cache and disabling SMT.
    GRUB_CMDLINE_LINUX="mds=full,nosmt"

  • Patches the TAA vulnerability by disabling TSX and enables mitigations using TSX Async Abort along with disabling SMT.
    GRUB_CMDLINE_LINUX=tsx=off tsx_async_abort=full,nosmt"

  • Mark all huge pages in the EPT as non-executable to mitigate iTLB multihit.
    GRUB_CMDLINE_LINUX="kvm.nx_huge_pages=force"

  • Force disable SMT as it has caused numerous CPU vulnerabilities. The only full mitigation of cross-HT attacks is to disable SMT.
    GRUB_CMDLINE_LINUX="nosmt=force"

  • Enables the prctl interface to prevent leaks from L1D on context switches.
    GRUB_CMDLINE_LINUX=l1d_flush=on"

  • Mitigates numerous MMIO Stale Data vulnerabilities and disables SMT.
    GRUB_CMDLINE_LINUX="mmio_stale_data=full,nosmt"

  • Enable mitigations for RETBleed (Arbitrary Speculative Code Execution with Return Instructions) vulnerability and disable SMT.
    GRUB_CMDLINE_LINUX="retbleed=auto,nosmt"

6.1.7. Kernel self-protection

  • Kernel reboot scripts to choose which presets to load 'default' or 'hardened' preset to avoid installation problems of future upgrades.

  • Disable loading new modules. Be careful with using this option.
    kernel.modules_disabled=1

  • Restricting access to kernel pointers.
    kernel.kptr_restrict=2

  • Restricting access to kernel logs.
    kernel.dmesg_restrict=1

  • Despite the value of dmesg_restrict, the kernel log will still be displayed in the console during boot. This option prevents those information leaks.
    kernel.printk=3 3 3 3

  • Restricting eBPF to the CAP_BPF capability
    kernel.unprivileged_bpf_disabled=1
    net.core.bpf_jit_harden=2

  • Restricting loading TTY line disciplines to the CAP_SYS_MODULE capability
    dev.tty.ldisc_autoload=0

  • The userfaultfd() syscall is often abused to exploit use-after-free flaws. This sysctl is used to restrict this syscall to the CAP_SYS_PTRACE capability.
    vm.unprivileged_userfaultfd=0

  • kexec is a system call that is used to boot another kernel during runtime. This functionality can be abused to load a malicious kernel and gain arbitrary code execution in kernel mode, so this sysctl disables it.
    kernel.kexec_load_disabled=1

  • The SysRq key exposes a lot of potentially dangerous debugging functionality to unprivileged users. You can simply set the value to 0 to disable SysRq completely.
    kernel.sysrq=0

  • Randomise memory space.
    kernel.randomize_va_space=2

  • These prevent creating files in potentially attacker-controlled environments, such as world-writable directories.
    fs.protected_fifos=2 fs.protected_regular=2

  • This only permits symlinks to be followed when outside of a world-writable sticky directory, when the owner of the symlink and follower match or when the directory owner matches the symlink's owner.
    fs.protected_symlinks=1 fs.protected_hardlinks=1

  • ptrace is a system call that allows a program to alter and inspect another running process, which allows attackers to trivially modify the memory of other running programs.
    kernel.yama.ptrace_scope=2

  • Use filename based on core_pattern value.
    kernel.core_uses_pid=1

  • Performance events add considerable kernel attack surface and have caused abundant vulnerabilities. Be careful, performance might be affected. Deactivated by default.
    #kernel.perf_event_paranoid=2

  • ASLR is a common exploit mitigation which randomises the position of critical parts of a process in memory. This can make a wide variety of exploits harder to pull off, as they first require an information leak. The above settings increase the bits of entropy used for mmap ASLR, improving its effectiveness. The values of these sysctls must be set in relation to the CPU architecture. The values are compatible with x86, but other architectures may differ.
    vm.mmap_rnd_bits=32 vm.mmap_rnd_compat_bits=16

  • Deactivation of Core Dumps via sysctl.
    kernel.core_pattern=|/bin/false

6.1.8. Certain Kernel modules are disabled and blacklisted

  • Deactivates Netfilter's connection tracking helper - this module increases kernel attack surface by enabling superfluous functionality such as IRC parsing in the kernel. Hence, this feature is disabled.
  • The vivid kernel module is only required for testing and has been the cause of multiple vulnerabilities so it is disabled.

6.1.8.1. Disable Uncommon Network Protocols

  • DCCP - Datagram Congestion Control Protocol
  • SCTP - Stream Control Transmission Protocol
  • RDS - Reliable Datagram Sockets
  • TIPC - Transparent Inter-process Communication
  • HDLC - High-Level Data Link Control
  • AX25 - Amateur X.25
  • NetRom
  • X25
  • ROSE
  • DECnet
  • Econet
  • af_802154 - IEEE 802.15.4
  • IPX - Internetwork Packet Exchange
  • AppleTalk
  • PSNAP - Subnetwork Access Protocol
  • p8023 - Novell raw IEEE 802.3
  • p8022 - IEEE 802.2
  • CAN - Controller Area Network
  • ATM

6.1.8.2. Disable Uncommon Filesystems

  • cramfs
  • fat # Not disabled in case of UEFI setup
  • freevxfs
  • jffs2
  • hfs
  • hfsplus
  • squashfs
  • udf

6.1.8.3. Disable Uncommon Network Filesystems

  • cifs
  • nfs
  • nfsv3
  • nfsv4
  • ksmbd
  • gfs2

6.1.9. Network Hardening Settings

  • ICMP redirect acceptance, ICMP redirect sending, source routing and IPv6 router advertisements are disabled to prevent man-in-the-middle attacks.
    net.ipv4.conf.all.accept_redirects=0
    net.ipv4.conf.default.accept_redirects=0
    net.ipv4.conf.all.secure_redirects=0
    net.ipv4.conf.default.secure_redirects=0
    net.ipv6.conf.all.accept_redirects=0
    net.ipv6.conf.default.accept_redirects=0
    net.ipv4.conf.all.send_redirects=0
    net.ipv4.conf.default.send_redirects=0

  • The kernel is configured to ignore all ICMP requests to avoid Smurf attacks, make the device more difficult to enumerate on the network and prevent clock fingerprinting through ICMP timestamps.
    net.ipv4.icmp_echo_ignore_all=1

  • RFC1337 is enabled to protect against time-wait assassination attacks by dropping RST packets for sockets in the time-wait state.
    net.ipv4.tcp_rfc1337=1

  • TCP syncookies are enabled to prevent SYN flood attacks.
    net.ipv4.tcp_syncookies=1

  • IP source routing is disabled, we are not a router:
    net.ipv4.conf.all.accept_source_route=0
    net.ipv4.conf.default.accept_source_route=0
    net.ipv6.conf.all.accept_source_route=0
    net.ipv6.conf.default.accept_source_route=0

  • Ignoring broadcasts request.
    net.ipv4.icmp_echo_ignore_broadcasts=1

  • Ssource validation of packets received from all interfaces of the machine enabled. This protects against IP spoofing, in which an attacker sends a packet with a fraudulent IP address.
    net.ipv4.conf.all.rp_filter=1
    net.ipv4.conf.default.rp_filter=1

  • Logging martian packets, which is a packet with a source address which is obviously wrong - nothing could possibly be routed back to that address.
    net.ipv4.conf.all.log_martians=1
    net.ipv4.conf.default.log_martians=1

6.1.10. Restrictive mount options

  • Further hardening of the already recommended CISS Partition scheme, incl. apt preparation to handle updates to the fact that the mounted /tmp is hardened:
/proc           proc  nosuid,nodev,noexec,hidepid=2      0  0
/dev/shm        tmpfs rw,nodev,nosuid,noexec,relatime    0  0

/boot           ext4  defaults,nodev,nosuid,noexec       0  2
/home           ext4  defaults,rw,nosuid,nodev,relatime  0  2
/tmp            ext4  defaults,rw,nodev,nosuid,noexec    0  0
/usr            ext4  defaults,rw,nodev                  0  2
/var            ext4  defaults,rw,nosuid,nodev,relatime  0  2
/var/log        ext4  defaults,rw,nodev,nosuid,noexec    0  2
/var/tmp        ext4  defaults,rw,nodev,nosuid,noexec    0  2
/var/log/audit  ext4  defaults,rw,nodev,nosuid,noexec    0  2

/etc/apt/apt.conf.d/50apthardening

Dir::Cache::Archives "/etc/hardening/aptcache";
Dir::State::status "/etc/hardening/varlibdpkg/status";
DPkg::Pre-Install-Pkgs {"mount -o remount,exec /tmp";};
DPkg::Post-Invoke {"mount -o remount /tmp";};
APT::ExtractTemplates::TempDir "/etc/hardening/tmp";

6.1.11. Further Hardening

6.1.11.1. Additional Kernel Hardening

  • Kernel update to zabbly project if selected. Warning !!! As those kernels aren't signed by a trusted distribution key, you may need to turn off Secure Boot on your system in order to boot this kernel.

  • Coredumps are disabled as they may contain important information such as encryption keys or passwords. See also Kernel self protection

6.1.11.2. Apt Hardening

  • Enabling "apt-get --error-on=any" which makes apt exit non-zero for transient failures. /etc/apt/apt.conf.d/40error-on-any

  • Enabling APT seccomp-BPF sandboxing. /etc/apt/apt.conf.d/40sandbox

  • Changing sources.list to use only Debian https sources.

6.1.11.3. DNS Server

  • The following free DNS-Server are used, to not rely on standard ISP non-free server: coresecret.eu DNS)
IPv4: 135.181.207.105
IPv4: 89.58.62.53
IPv6: 2a01:4f9:c012:a813:135:181:207:105
IPv6: 2a0a:4cc0:1:e6:89:58:62:53

6.1.11.4. Entropy collection improvements

  • The jitterentropy_rng kernel module is loaded as early as possible during boot to gather more entropy via:
    /usr/lib/modules-load.d/30_security-misc.conf jitterentropy_rng

  • Distrusts the CPU for initial entropy at boot as it is not possible to audit, may contain weaknesses or a backdoor.

  • Gathers more entropy during boot if using the linux-hardened kernel patch.

  • Installation of haveged 'Linux entropy source using the HAVEGE algorithm'.

6.1.11.5. Permissions, Authentication

  • Adding a sudoer user.

  • Further hardening such as umask 0077 (not for root: because then configuration files created in /etc by the system administrator would be unreadable by "others" and break applications.) This means, files created by non-root users cannot be read by other non-root users by default.

  • Setting up a cron.allow file to restrict access to cron to authorised users.

  • Hardening of files like grub, cron and many more, replaced issue, issue.net, banner with generic text.

  • Overwrite protection module to opt in. In each case of redirection, copying, moving the goal is to add an extra hurdle when the operation may have the side effect of erasing some existing data, even though erasing existing data is not the primary goal of the operation.

  • Hardening the grub bootloader with password protection to increase the security of your full disk encrypted setup ( this is not a big burden to overcome if someone has direct access to the server, therefore the /boot encryption is recommended ).

  • Changing the machine ID to the whonix ID.

  • Change the login.defs and the pam module to yescrypt, including a costfactor of '8'.

  • Preparation for the Google Authenticator 2FA module. This step must be performed after setup and a reboot.

6.1.11.6. Software tools installation

  • Ansible preparation either as control or managed node.
  • Lynis integration.
  • eza installation.
  • htop installation.
  • makepasswd installation.
  • mtr installation.
  • neofetch installation.
  • nvim installation.
  • pwgen installation.
  • zsh installation.

6.1.11.7. Security Extensions installation

  • SELinux or AppArmor installation and setup, select which security extensions you want to prepare in the .conf file.

  • Installation of a SELinux policy generator script.

6.1.11.8. SSH, ufw, fail2ban

  • SSH hardening, choose your port, choose whether to use a bastion or jump host, restrict KEX, ciphers, MACs to the most secure options available, restrict access via allow user policy. Your added sudoer will automatically be added to the SSH allow users list.

  • ufw hardening, default deny incoming and default deny outgoing if selected in .conf file, incl. preset of selected outgoing ports to open to ensure smooth operation of freshly hardened server.

  • fail2ban incl. better-than-honeypot hardening: Anyone who touches the server on a port that is not open will be immediately banned for 24 hours. Be careful not to ban yourself. If you are using a Bastion or Jump server, the designated IPv4 and IPv6 /64 subnet will be added to the default fail2ban ignore-ip list. Otherwise the touching Server will be banned after the 16th attempt.

  • Also the fail2ban service itself is hardened via systemd /etc/systemd/system/fail2ban.service.d/override.conf policy file.

6.1.11.9. QEMU Guest Agent Hardening

  • Removal of the QEMU guest agent: if you are using a VM with full disk encryption, there is still a chance to gain access to the VM via password reset. Therefore the QEMU guest agent will be removed. Also consider using a Netcup Root VPS: they are using memory encryption, so this gives you a bit more security.

6.1.11.10. Several other hardening setting

  • Hardening of the ntp servers so that the PTB NTPSec server are selected, therefore chrony is installed and NTPSec is requried to retrieve the timestamps.

  • Preparation of SSL hardening to accept only TLSv1.3 AES256 bit ciphers.

  • Retrieval of an auditd ruleset, preparation of auditd, aide and debsums.

7. Main Installation

7.1. ! Warnings !

  • This script MUST be run after a fresh Debian Bookworm installation.

  • This script MUST NOT be run on an active server in a production environment - it may cause data loss, damage and/or malfunction. You have been warned.

  • If you are installing Debian GNU/Linux from a minimal CD by using the network, you MUST install wget and curl packages before you can use the hardening script.

  • Only x86_64 architectures are supported (arm64 support is still under development).

  • GRUB2 uses the US keyboard layout by default, it is strongly RECOMMENDED to choose your password/passphrase accordingly. Keep this in mind when setting the password for GRUB2 and/or /boot encryption.

  • You MAY upgrade the kernel to the zabbly project if selected. As these kernels are not signed by a trusted distribution key, you MUST disable secure boot on your system to boot this kernel.

  • USBGuard is installed and to avoid a complete lockout by mistake, PresentDevicePolicy=allow is set instead of the default PresentDevicePolicy=apply-policy.

  • It is highly RECOMMENDED that you use an SSH jump host / Bastion or at least a dedicated VPN setup to access your machines via SSH.

    • Note that the fail2ban setup will ban any IP in the non-jump host configuration that hits a closed port 32 times in a 24-hour rolling window.
  • If you choose the SSH Ultra Hardening Module, you MUST provide a proper Jumphost, Bastion or at least a dedicated and non-dynamic IPv4 AND IPv6 VPN exit node. You MAY add a static exit node domain.tld for the tcp wrapper to be added to /etc/hosts.allow.

  • For the Root Ultra Hardening Module, remember that the root account is locked via passwd -l root AND root access is set to no in /etc/ssh/sshd_config AND the sudoer user created by the script is additionally hardened via 2FA TOTP. Therefore, a triple-checking routine is implemented, where after each hardening step you MUST confirm that you could have logged into the server from another terminal. Once the hardening module has been successfully completed, there is only one way to access the hardened machine:

    • You MUST use the specified static IPs or domain of your remote client.

    • You MUST have access to your sudoer users SSH public key.

    • You MUST have access to your sudoer users 2FA TOTP creation device.

    • Then log in as user and become root via sudo -i. It is up to you to implement other user accounts to NOT get locked out. The only way to bypass a lockout is to mount the volumes on another machine. In this case you MUST have access to all your full disk encryption keys.

  • As of ML5.32.128, this script is not idempotent. Although the script has been thoroughly tested against the advanced ERR and SIGNAL traps and any known apparent false positives have been mitigated, if your specific configuration fails at the first attempt and you can rule out that neither the recommendations and/or requirements have been violated, it is up to you to decide if you want to rely on a setup that hasn't been run successfully. It is therefore highly RECOMMENDED that you thoroughly analyse any errors that have occurred.

7.2. Prerequisites

  • Root Server RECOMMENDED:

    • netcup Root VPS RS Series G11

    • Hetzner shared AMD VPS CPXnn Series

    • Hetzner dedicated VPS CCXnn Series

    • own Proxmox installation

  • CPU family RECOMMENDED:

  • The script MUST be run after a fresh Debian Bookworm installation. For further preparations refer to CISS.2024.bookworm.installation Tutorial.

  • You MUST be root to run the script.

  • A SSH public key for root MUST be provided before starting the script.

  • A SSH public key for the sudoer user to create, if selected, MUST be provided before starting the script.

  • All variables in hardening.conf MUST be enclosed in double quotes. The detailed naming scheme in the description section of hardening.conf MUST be strictly followed.

  • One of the following Partition schemes MUST be prepared and used:

7.3. Partition Scheme

Please install a fresh instance of Debian Bookworm using the Netinstaller, and partition the harddrive using one of the following schemes for

where

To minimise the attack surface, make sure that your freshly installed Debian Bookworm server is set up with

and you SHOULD follow best practices that at least:

  • /boot
  • /
  • /tmp
  • /home
  • /var
  • /usr
  • /var/log
  • /var/log/audit
  • /var/tmp
  • swap

are on separate partitions. For further preparation please refer to the following examples.


7.3.1. Example Configuration CISS.2024 Partition Scheme BIOS

  • BIOS mode.

  • GPT Table MUST be used.

  • ext4 filesystem MUST be used for the hardening.sh script.

  • Full-Disk-Encryption is RECOMMENDED.

  • LUKS2 /boot encryption is RECOMMENDED.

  • Ephemeral SWAP encryption is RECOMMENDED.

  • Ephemeral /tmp encryption is RECOMMENDED.

7.3.1.1. CISS.2024 Partition Scheme BIOS Preparation

Prepare the partitions as in this example. Note that ephemeral SWAP and ephemeral /tmp are left unformatted, as this is done by the script.

Example Configuration CISS.2024 Partition Scheme BIOS Preparation

7.3.1.2. Final CISS.2024 Partition Scheme BIOS setup

Once the script has finished and after a final reboot, the partitioning should look like this:

Example Configuration CISS.2024 Partition Scheme BIOS


7.3.2. Example Configuration CISS.2024 Partition Scheme UEFI

  • UEFI mode.

  • GPT Table MUST be used.

  • ext4 filesystem MUST be used for the hardening.sh script.

  • Full-Disk-Encryption is RECOMMENDED.

  • LUKS2 /boot encryption is RECOMMENDED.

  • Ephemeral SWAP encryption is RECOMMENDED.

  • Ephemeral /tmp encryption is RECOMMENDED.

7.3.2.1. CISS.2024 Partition Scheme UEFI Preparation

Prepare the partitions as in this example. Note that ephemeral SWAP and ephemeral /tmp are left unformatted, as this is done by the script.

Example Configuration CISS.2024 Partition Scheme UEFI Preparation

7.3.2.2. Final CISS.2024 Partition Scheme UEFI setup

Once the script has finished and after a final reboot, the partitioning should look like this:

Example Configuration CISS.2024 Partition Scheme UEFI


7.3.3. Example Configuration CISS.2024 Partition Scheme UEFI High Availability

  • UEFI mode.

  • GPT Table MUST be used.

  • ext4 filesystem MUST be used for the hardening.sh script.

  • Full-Disk-Encryption is RECOMMENDED.

  • LUKS2 /boot encryption is RECOMMENDED.

  • Ephemeral SWAP encryption is RECOMMENDED.

  • Ephemeral /tmp encryption is RECOMMENDED.

  • One of the following RAID levels MUST be used:

    • 1: Striping.

    • 5: Block-level striping with distributed parity.

    • 6: Block-level striping with two parity blocks distributed across all member disks.

  • You MUST specify the minimum number of drives required for the selected RAID level.

  • LVM on RAID on dm-integrity on dm-crypt HA setup.

7.3.3.1. CISS.2024 Partition Scheme UEFI High Availability Preparation

Prepare the partitions as shown in this example. Note that the ephemeral SWAP and ephemeral /tmp are left unformatted and also that your RAID disks are completely untouched as all steps like creating the partition table, partitioning, formatting and encrypting are done by the script.

Example Configuration CISS.2024 Partition Scheme HA Preparation

7.3.3.2. Final CISS.2024 Partition Scheme UEFI High Availability setup

Once the script has finished and after a final reboot, the partitioning should look like this:

Example Configuration CISS.2024 Partition Scheme HA


7.4. Tested and recommended VPS Provider

7.4.1. Latest: Tested and recommended VPS Provider

Tested & Recommended VPS Provider Date Version tested Notes Lynis Score
Netcup Root-Server Generation 11 30.10.2024 V5.42.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) ?) +) #) ~) R) X) W) 95 (3.1.2)
Netcup Root-Server Generation 11 23.10.2024 V5.33.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) ?) +) #) ~) R) 93 (3.1.2)
Netcup Root-Server Generation 11 23.10.2024 V5.33.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) ?) +) #) ~) 93 (3.1.2)

7.4.2. History: Tested and recommended VPS Provider

Tested & Recommended VPS Provider Date Version tested Notes Lynis Score
Netcup Root-Server Generation 11 30.10.2024 V5.42.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) ?) +) #) ~) R) X) W) 95 (3.1.2)
Netcup Root-Server Generation 11 23.10.2024 V5.33.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) ?) +) #) ~) R) 93 (3.1.2)
Netcup Root-Server Generation 11 23.10.2024 V5.33.128 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) ?) +) #) ~) 93 (3.1.2)
Netcup Root-Server Generation 11 20.10.2024 V5.32.256 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) ?) +) #) !) 92 (3.1.2)
Netcup Root-Server Generation 11 19.08.2024 V5.02.512 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) *) +) #) 94 (3.1.1)
Hetzner Shared vCPU (AMD64) CPXn 14.08.2024 V5.00.768 B) E) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) **) +) 92
Contabo Cloud VPS 26.05.2024 V4.04.256 1) 5) 6) 7) 8) 9) 10) 11) 92
Contabo Storage VPS 27.05.2024 V4.04.256 1) 5) 6) 7) 8) 9) 10) 11) 92
Hetzner Shared vCPU (AMD64) CPXn 14.08.2024 V5.00.768 B) E) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 16) **) +) 92
Hetzner Shared vCPU (x86) 30.06.2024 V4.07.512 B) E) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 94
Hetzner Dedicated vCPU tba
Netcup vServer ARM64 Generation 11 tba P) U) E)
Netcup Root-Server Generation 11 19.08.2024 V5.02.512 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) *) +) #) 94
Netcup Root-Server Generation 11 18.08.2024 V5.02.384 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) *) +) #) 94
Netcup Root-Server Generation 11 08.08.2024 V5.00.768 U) E) 2) 3) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) *) +) #) 94
Netcup Root-Server Generation 11 07.08.2024 V5.00.512 U) E) 2) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) *) +) #) 94
Netcup Root-Server Generation 11 05.08.2024 V5.00.256 U) E) 2) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) *) +) #) 94
Netcup Root-Server Generation 11 04.08.2024 V5.00.128 U) E) 2) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) *) +) 94
Netcup Root-Server Generation 11 03.08.2024 V5.00.128 U) E) 2) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) *) 94
Generic Proxmox 8.2.4 based VM 22.06.2024 V4.07.128 B) G) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 94

7.4.3.1. Notes

 B) BIOS Boot Setup tested.
 U) UEFI Boot Setup tested.
 E) Locale en_US.UTF-8 tested.
 G) Locale de_DE.UTF-8 tested.
 P) No disk encryption applied at all due to password input problems in the web console.
 R) RAID Level 6 tested incl. 4 Disks and 1 Spare Disk.
 W) Wazuh Agent installed manually.
 X) SSH Ultra and Root Ultra Hardening applied.
 1) No KVM or Webconsole available.
 2) Grub Password Installation: checked.
 3) Full Disk Enryption: checked.
 4) /boot encryption LUKS1: checked.
 5) journalctl --boot=0: checked.
 6) systemctl status -- failed: checked.
 7) Reboot scripts: checked.
 8) Network - mtr, ping (-4 && -6): checked.
 9) fail2ban-client status: checked.
10) chronyc: NTPSec: checked.
11) No Lynis warnings.
12) spectre-meltdown-checker: not vulnerable.
13) Ephemeral SWAP encryption: tested.
14) Full Disk Enryption LUKS2: checked.
15) LVM on RAID6 on dm-crypt incl. dm-integrity: checked.
16) Ephemeral `/tmp` encryption: tested.
 +) Run with debug mode enabled.
 #) All modules tested.
 *) Tested against: 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1
**) Tested against: 6.9.7+bpo-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.7-1
 ?) Tested against: 6.10.11+bpo-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.10.11-1~bpo12+1 (2024-10-03) x86_64 GNU/Linux
 ~) Tested against: 6.10.11+bpo-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.10.11-1~bpo12+1 (2024-10-03) x86_64 GNU/Linux
 !) Terminal output on webconsole after GRUB menu is snowy, so entering passwords for FDE can be extremely difficult. After regular boot, the system works without any known or spotted issues.

7.5. sha384 Hashes

16ee3d8aa240ac676b720a841f79e01443348978b8beecf4d89e85d10c347654b1e9ac66e88d2e2838e8c48002f1f3c9 *hardening.conf
a9b7defcc0f460d6867cb0768e64b3efc00e3f2be2058ec489257c31112caed60963ceaf378c73786ae81d82ce177439 *hardening.sh
4d49927adb4f1a1585d8ff807008aef4371be218c830ecb69fca8cffd23eac27ecb7febd2ce63e176b3aaeb270da110a *password.txt

7.6. Server Preparation and Setup

A detailed Tutorial is available at CISS.2024.vps.bookworm.hardening Tutorial.
(Will be revised soon. Also, the tutorial on installing a Debian Bookworm server using Netinstaller will be revised soon.)

7.6.1. .conf file values

All variables MUST be entered in double quotes.

#!/bin/bash
###########################################################################################
# Debian Bookworm VPS Hardening Setup Script Config File             V5.42.128.2024.10.30 #
###########################################################################################
# Copyright (c) 2018 - 2024, Marc Simon Weidner, Centurion Intelligence Consulting Agency #
# https://coresecret.eu/                                                                  #
# Licensed under the EUROPEAN UNION PUBLIC LICENCE v. 1.2 https://eupl.eu/1.2/en/         #
###########################################################################################
# https://keys.openpgp.org/vks/v1/by-fingerprint/A6D46A56AE17A185AB0F6DB77095A8A13CBE0FA3 #
# Fingerprint A6D4 6A56 AE17 A185 AB0F 6DB7 7095 A8A1 3CBE 0FA3 ## valid till: 01.01.2031 #
###########################################################################################
# Please change the variables according to your needs.                                    #
# Variables that are not set MUST have at least a NUL value, e.g: ""                      #
###########################################################################################

###########################################################################################
# Encryption related                                                                      #
###########################################################################################
BOOTENCRYPTION="Yes"
# Only required if BOOTENCRYPTION="Yes":
  BOOTENCRYPTION_FORMAT="LUKS2"
### Only required if BOOTENCRYPTION_FORMAT="LUKS1":
    LUKSITERATION="2097152"
#####
EPHEMERAL_SWAP="Yes"
# Only required if EPHEMERAL_SWAP="Yes":
  EPHEMERAL_SWAP_PARTITION="sda4"     # https://coresecret.eu/tutorials/ciss-2024-bookworm/
#####
EPHEMERAL_TMP="Yes"
# Only required if EPHEMERAL_TMP="Yes":
  EPHEMERAL_TMP_PARTITION="sda5"      # https://coresecret.eu/tutorials/ciss-2024-bookworm/
#####
GRUB_PSSWD="Yes"

###########################################################################################
# Script related                                                                          #
###########################################################################################
SELFCHECK="Yes"
SELFCHECKDL="Yes"
TRUSTKEY="Yes"
TRUSTLEVEL="5"

###########################################################################################
# Server related                                                                          #
###########################################################################################
ANSIBLE="Managed"
ARCHITECTURE="AMD64"
CURRENTTIMEZONE="Europe/Lisbon"
FQDN="fully.qualified.domain.name"
IPV4="123.123.123.123"
IPV6="AAAA:BBBB:CCCC:DDDD:EEEE:FFFF::1"
JUMPHOST="Yes"
# Only required if JUMPHOST="Yes":
  JUMPHOST_IPV4="123.123.123.123"
  JUMPHOST_IPV6="AAAA:BBBB:CCCC:DDDD:EEEE:FFFF:9999:1111"
#####
KERNELUPDATE="Yes"
LOGROTATE_CHANGE="Yes"
# Only required if LOGROTATE_CHANGE="Yes":
  LOGROTATE_COUNT="90"
#####
OPENSSL_SECLEVEL="2"
QEMUREMOVAL="Yes"
SECEXTENSIONS="selinux"
UFW_OUT_POLICY="deny"
VPSPROVIDER="Netcup"

###########################################################################################
# SSH related                                                                             #
###########################################################################################
SSHKEYROUNDS="1024"
SSHPORT="64000"
SSHULTRA="Yes"
# Only required if SSHULTRA="Yes":
  ADDITIONAL_IPV4=""                     # Leave empty, if you do not need additional IPs.
  JUMPHOST_DOMAIN="mydomain.tld"         # Subdomains are included.
  INTERNAL_NETWORK="10.0.0.0/8"          # Internal Network IP in CIDR notation.

###########################################################################################
# User related                                                                            #
###########################################################################################
ADDUSER="Yes"
# Only required if ADDUSER="Yes":
  USER_SSHPUBKEY="ssh-ed25519 BBBBC3NzaC1lZDI1NTE5DDDDIFNRPjNUxyfCE5LYZArxx/u/RdMfGz4uTxiiPAziIhel 2024_255.255.255.255_user"
  USER_NAME="testuser"
#####
ADDSHORTCUTS="Yes"
OVERWRITEPROTECTION="Yes"
ROOTULTRA="No"
ZSH_INST="Yes"

###########################################################################################
# LVM on mdadm on dm-crypt incl. dm-integrity related                                     #
###########################################################################################
# ! Important ! - Also change the password in the password.txt file !
LVM_RAID_INTEGRITY="No"
# Only required if LVM_RAID_INTEGRITY="Yes":
  DISK_01="/dev/sdb"
  DISK_02="/dev/sdc"
  DISK_03="/dev/sdd"
  DISK_04="/dev/sde"
  DISK_05="/dev/sdf"
  DISK_06="/dev/sdg"
  # Just uncomment or add more disks to the .conf file. The script will auto-iterate through
  # all the device-variables. You MUST follow the naming scheme of the disk-variables.
  DISK_USAGE_PERCENTAGE="99"
  NAME_RAID="md_data"
  NAME_VG="vg_data"
  NAME_VOLUME="vl_data"
  NAME_MOUNTPOINT="dir_data"
  RAID_LEVEL="6"
  RAID_SPARE_USE="Yes"
### Only required if RAID_SPARE_USE="Yes":
    RAID_COUNT_DISKS="5"
    RAID_COUNT_SPARE="1"

###########################################################################################
# ! No changes below this line !                                                          #
###########################################################################################
BRANCH="Main"
CONFVERS="V5.42.128.2024.10.30"
DETECTED_LOCALE="$(grep LANG= /etc/default/locale | cut -d'=' -f2- | tr -d '"')"
SLEEPTIMER="1"
TARGET_DIR="/root/hardening"
UBUNTU_CODENAME="jammy"
USER_PASSWD="$(pwgen -n 32 -B -c -s -1)"
ZSH_PROMPT="PROMPT='\$USER_COLOR%D%f|\$USER_COLOR%n%f@%F{005}%M%f:%F{006}%d%f/>>%(?.%F{002}%?.%F{001}%?)%f|~%#> '"
ZSH_RPROMPT="RPROMPT='%h|[\$USER_COLOR%*%f]'"

7.6.1.1. ADDUSER

Please select if you would like to add a Sudoer User as well. Allowed values are:
"Yes" or "No"

7.6.1.2. ADDSHORTCUTS

Please specify if you want to add few shortcuts. Allowed values are:
"Yes" or "No"

7.6.1.3. ANSIBLE

Please select if you want to install the Ansible Server Controle or the Managed Node or if you want to Skip the installation at all. Allowed values are:
"Controle" or "Managed" or "Skip"

7.6.1.4. ARCHITECTURE

Please select the architecture of the CPU. Allowed values are:
"AMD64" or "INTEL64" or "arm64"

7.6.1.5. BOOTENCRYPTION

Please specify if you want to encrypt the /boot partition to further harden your system. Note that GRUB will load the US keyboard layout by default unless you change it. So choose your /boot password carefully in the interactive dialog. Allowed values are:
"Yes" or "No"

7.6.1.6. BOOTENCRYPTION_FORMAT

Please specify the format version for /boot encryption. For LUKS2 /boot encryption the following backported package will also be installed: grub-common (2.12-1~bpo12+1). Note that GRUB will load the US keyboard layout by default unless you change it. So choose your /boot password carefully in the interactive dialog. Allowed values are:
"LUKS2" or "LUKS1"

7.6.1.7. CURRENTTIMEZONE

Allowed values are:
"Europe/Lisbon" or any other specified Timezone (TZ) identifier: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

7.6.1.8. EPHEMERAL_SWAP

Please indicate if you have prepared the Debian Bookworm server for the ephemeral SWAP partition. In this scenario, the SWAP area will be initialised with a random new key every boot time to maximise security considerations. Allowed values are:
"Yes" or "No"

7.6.1.9. EPHEMERAL_SWAP_PARTITION

If you opt in to the ephemeral SWAP setup, please specify the prepared dedicated partition here.

7.6.1.10. EPHEMERAL_TMP

Please indicate if you have prepared the Debian Bookworm server for the ephemeral /tmp partition. In this scenario, the /tmp area will be initialised with a random new key every boot time to maximise security considerations. Allowed values are:
"Yes" or "No"

7.6.1.11. EPHEMERAL_TMP_PARTITION

If you opt in to the ephemeral /tmp setup, please specify the prepared dedicated partition here.

7.6.1.12. GRUB_PSSWD

Please select if you want to harden the Grub Booloader with a password. Please note that you will need KVM capabilities to be able to enter the password before the server has booted into the system. This feature is only tested on Netcup VPS servers 2024 and later and on Hetzner VPS 2024 and later and on own Proxmox Servers. Allowed values are:
"Yes" or "No"

7.6.1.13. FQDN

Please specify the desired FQDN ot the server. Allowed values are:
any valid FQDN: https://en.wikipedia.org/wiki/Fully_qualified_domain_name

7.6.1.14. IPV4

Please provide the IPv4 of the server in question.

7.6.1.15. IPV6

As a good practice, it is recommended that you have entered a PTR record that matches the FQDN that you have set up in the DNS section of your DNS service provider, stating that the following IPv6 convention is used and suggested:
Consider your IPv4 to be: 123.123.123.123
Consider your IPv6 Prefix to be: 2a10:ABCD:1111:FFFF::1/64
Then the server IPv6 is as follows: 2a10:ABCD:1111:FFFF:123:123:123:123/128
For Contabo: Please enter the IPv6 you have entered in the PTR Record section.
For Hetzner: Please enter the IPv6 you have entered in the Networking tab.
For Netcup: Please enter the IPv6 you have specified in the Netcup Server Control Panel.

7.6.1.16. JUMPHOST

Please specify if your new server is reachable via a Bastion / Jump Server. Allowed values are:
"Yes" or "No"

7.6.1.17. JUMPHOST_IPV4

Please provide the IPv4 of the server in question. In case you are using a Jumphost, please add here the IPv4 and IPv6 of the respective Bastion / Jump Server which will be added to the fail2ban ignoreip list.

7.6.1.18. JUMPHOST_IPV6

Please provide the IPv4 of the server in question. In case you are using a Jumphost, please add here the IPv4 and IPv6 of the respective Bastion / Jump Server which will be added to the fail2ban ignoreip list.

7.6.1.19. KERNELUPDATE

Please specify if you want to change the kernel image. If you select "Yes", you will be prompted to select an available kernel during setup; if you select "No", no kernel update will be installed at all. Enter "Zabbly" to install the latest Linux kernel available from Zabbly project
Allowed values are:
"Yes" or "No" or "Zabbly"

7.6.1.20. LOGROTATE_CHANGE

Please specify if you want to change the log rotation frequency of the fail2ban and ufw logs from weekly to daily. Allowed values are:
"Yes" or "No"

7.6.1.21. LOGROTATE_COUNT

Please specify the number of days the above logs should be kept. Allowed values are:
"96" or any other postive integer you prefer

7.6.1.22. LUKSITERATION

The PBKDF parameters are determined by benchmark when the key slot is created (or updated). Thus, they only make sense if the environment in which the LUKS device is opened matches the one in which it's formatted (same CPU, same RAM size, etc.). Unlocking from GRUB does count as an environment mismatch, because GRUB operates under tighter memory constraints and does not take advantage of all crypto-related CPU instructions. Concretely, this means that unlocking a LUKS device from GRUB can take much longer than unlocking it from the normal system. Since GRUB's LUKS implementation isn't capable of benchmarking, you'll have to do it # manually. It's easier for PBKDF2 because it has a single parameter to play with (iteration count) - while Argon2 has two (iteration count and memory) - and changing it has a linear effect on unlock time: for example, halving the iteration count would speed up unlocking by a factor of two. (And, of course, making low entropy passphrases twice as easy to brute-force. There is a trade-off here. Balancing convenience and security is the whole point of running PBKDF benchmarks). The preset of 2,097,152 rounds works well enough on the systems tested. Allowed values are:
"2097152" or any other postive integer you prefer

7.6.1.23. LVM_RAID_INTEGRITY

Please specify if you want to setup an LVM on mdadm on dm-crypt incl. dm-integrity cluster. Allowed values are:
"Yes" or "No"

If so, please also specify the following variables:

  • DISK_01="/dev/sdb"
  • DISK_02="/dev/sdc"
    • and so forth
  • RAID_LEVEL="6"
    • Supported values are "0", "1", "5", "6"
  • RAID_SPARE_USE="Yes"
    • If you want to add Spare disks in the first place. Allowed values are: "Yes" or "No"
  • RAID_COUNT_DISKS="5"
    • Number of devices to build the RAID. Needed if and only if RAID_SPARE_USE="Yes"
  • RAID_COUNT_SPARE="1"
    • Number of devices to use as Spare disk. Needed if and only if RAID_SPARE_USE="Yes"
  • DISK_USAGE_PERCENTAGE="99"
    • It is best practice not to use all the hard disk space for a RAID member.
  • NAME_RAID="md_data"
    • Desired name for the created RAID group.
  • NAME_VG="vg_data"
    • Desired name of the volume group to be created on top of the RAID group.
  • NAME_VOLUME="vl_data"
    • The name of the new volume to be created in the volume group.
  • NAME_MOUNTPOINT="dir_data" -The new directory to mount the volume to.

7.6.1.24. OPENSSL_SECLEVEL

SECLEVEL=2: Medium security (112-bit security).
SECLEVEL=3: High security level. Allows 128-bit security.
SECLEVEL=4: Very high security level. (192-bit security, 3840-bit RSA, SHA-384).
SECLEVEL=5: Ultra-high security level. (256-bit security, 7680-bit RSA, SHA-512).

  • SECLEVEL=2
    • RSA: Keys must be at least 2048 bits long.
    • DHE: Diffie-Hellman Ephemeral (DHE) keys must be at least 2048 bits long.
    • DH: Static Diffie-Hellman (DH) keys must be at least 2048 bits long.
    • ECC: Elliptic Curve Cryptography (ECC) keys must be at least 224 bits long.
    • Only hash algorithms providing at least 112 bits of security are allowed (SHA-224).
  • SECLEVEL=3
    • Minimum RSA, DHE, and DH key sizes: 3072 bits.
    • Minimum ECC key sizes: 256 bits.
    • Hash algorithms: Requires SHA-256 or better for signatures and MACs.
    • Symmetric encryption key sizes: Must be at least 192 bits (e.g., AES-128).
  • SECLEVEL=4
    • Suitable for highly sensitive environments requiring strong cryptographic guarantees.
    • Minimum RSA, DHE, and DH key sizes: 3840 bits.
    • Minimum ECC key sizes: 384 bits.
    • Hash algorithms: Requires SHA-384 or better for signatures and MACs.
    • Symmetric encryption key sizes: Must be at least 192 bits (e.g., AES-192).
  • SECLEVEL=5
    • Suitable for extremely sensitive and critical applications requiring the highest level of cryptographic strength.
    • Minimum RSA, DHE, and DH key sizes: 7680 bits.
    • Minimum ECC key sizes: 512 bits.
    • Hash algorithms: Requires SHA-512 or better for signatures and MACs.
    • Symmetric encryption key sizes: Must be at least 256 bits (e.g., AES-256). Allowed values are:
      "5" or "4" or "3" or "2"

7.6.1.25. OVERWRITEPROTECTION

The following will be added to .bashrc and / or .zshrc

set -o noclobber
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'

In each case (redirection, copying, moving, deleting), the goal is to add an extra hurdle when the operation may have the side effect of erasing some existing data, even though erasing existing data is not the primary goal of the operation. Allowed values are:
"Yes" or "No"

7.6.1.26. QEMUREMOVAL

This is to ensure that for a Full Disk Encryption Setup on a Netcup Root Server, the QEMU Agent Root Password Reset feature is removed. Therefore, a malicious agent must take a snapshot of the host's RAM and inspect where the Full Disk Encryption Setup key is stored. Given that Netcup also supports RAM encryption, this provides a little extra security. Allowed values are:
"Yes" or "No"

7.6.1.27. ROOTULTRA

This will lock the root user to login local and remote. In addition, the SSH root login will be disabled, as well as requiring 2FA for each user. Allowed values are:
"Yes" or "No"

7.6.1.28. SECEXTENSIONS

Please specify if you want to install and activate AppArmor or SELinux Security Extensions. SELinux defines access controls for applications, processes and files on a system with security policies. These policies determine what users may and may not access. If no policy is defined for a process, application or directory, SELinux prohibits access to it. The system is integrated into the system's kernel. AppArmor uses profiles to determine which files and rights an application requires. Each system uses certain functions differently. Allowed values are:
"selinux" or "apparmor"

7.6.1.29. SELFCHECK

Please specify if you want the script to self-verify, or not to self-verify the script and avoid a script verification failure due to an invalid signature or for easy and convenient script editing. Allowed values are:
"Yes" or "No"

7.6.1.30. SELFCHECKDL

Please specify if you want the script to self-verify all downloaded resources, or not if you want to modify the resources and avoid a script verification failure due to an invalid signature for easy and convenient script editing. Allowed values are:
"Yes" or "No"

7.6.1.31. SSHKEYROUNDS

The provided SSH hardening module generates new SSH keys with the specified number of KDF rounds to harden the keys against brute force attacks. Please note that the higher the number of rounds you select, the longer it will take to decrypt the keys. Allowed values are:
"768" or any other postive integer you prefer

7.6.1.32. SSHPORT

This hardening mechanism is a kind of security by obscurity. However, most bots that scan your SSH port do not scan all ports every time. At the very least, your log files will be grateful to be rid of tons of SSH login attempts. Allowed values are:
any port in the range "32768" to "65535"

7.6.1.33. SSHULTRA

Select if you want to use the sshd TCP wrapper in /etc/hosts.allow and /etc/hosts.deny. You MUST provide IPv4 and IPv6 SSH Jumphost, Bastion or VPN-Exitnode IPs under JUMPHOST_IPV4 and JUMPHOST_IPV6, see above. These IPs are added to the /etc/hosts.allow. You might add also JUMPHOST_DOMAIN likewise mydomain.tld which and all subdomains are added to the whitelist. You might also add INTERNAL_NETWORK as an IP range in CIDR notation.

7.6.1.34. TRUSTKEY

Please specify if you want to trust my ed25519 Gitea Signing Key. All my used keys reside in HSM like NitroKey and signing operations are done via an airgapped system. Allowed values are:
"Yes" or "No"

7.6.1.35. TRUSTLEVEL

Please specify the trust level of the signing key. PGP Trustlevel:

1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately

Allowed values are:
"5" or "4" or "3"

7.6.1.36. UFW_OUT_POLICY

Specify the default outgoing policy for the uncomplicated firewall. Default deny outgoing means that outgoing traffic is generally blocked unless otherwise allowed. Therefore, specific ports such as 53/UDP for DNS and 853/UDP for DNS over Quic are opened by default by the hardening module to ensure that the freshly hardened server is working properly. Allowed values are:
"deny" or "allow"

7.6.1.36.1. The complete list of opened ports.
-   21/tcp comment 'Outgoing FTP'
-   22/tcp comment 'Outgoing SSH'
-   25/tcp comment 'Outgoing SMTP'
-   53/tcp comment 'Outgoing DNS'
-   80/tcp comment 'Outgoing HTTP'
-  123/tcp comment 'Outgoing NTP'
-  143/tcp comment 'Outgoing IMAP'
-  443/tcp comment 'Outgoing HTTPS'
-  465/tcp comment 'Outgoing SMTPS'
-  587/tcp comment 'Outgoing SMTPS'
-  993/tcp comment 'Outgoing IMAPS'
- 4460/tcp comment 'Outgoing NTS'
-   53/udp comment 'Outgoing DNS/UDP'
-  123/udp comment 'Outgoing NTP/UDP'
-  443/udp comment 'Outgoing QUIC/UDP'
-  853/udp comment 'Outgoing DNSoverQuic/UDP'

7.6.1.37. USER_NAME

Enter the name of the sudoer user you want the script to create.

7.6.1.38. USER_SSHPUBKEY

Enter the SSH PUBLIC key of the user the script shall create.

7.6.1.39. VPSPROVIDER

Please select the VPS provider you are using. Or use "Generic" for a basic hardening of your generic server or VPS after a freshly installed Debian Bookworm environment including the CISS partition scheme. Allowed values are:
"Contabo" or "Hetzner" or "Netcup" or "Generic"

7.6.1.40. ZSH_INST

Please specify if you want to install zsh. Allowed values are:
"Yes" or "No"

7.6.1.41. SLEEPTIMER

This variable is used to set the clear screen routine after each module and is measured in seconds.

7.6.1.42. UBUNTU_CODENAME

DO NOT CHANGE. This variable is used to match the Debian Bookworm Ansible Controle Node installation.

7.6.1.43. USER_PASSWD

Generated by the appropriate secure pwgen module and displayed after the setup process in the endnotes.


7.7. Using ./restart_*.sh scripts

  • restart_crontab.sh will be called by the generated cron entry at each reboot to check if the system should be booted into hardened kernel protection mode to load the /etc/sysctl.d/99-local.conf.hold settings. If so, the settings are loaded, otherwise nothing is changed and no kernel self-protection settings are loaded.

  • restart_hardening.sh is a script that should be run via ./restart_hardening.sh in /root to reboot the system into hardened mode with hardened /etc/fstab settings and a hardened /etc/sysctl.d/99-local.hardened preset.

  • restart_install.sh is a troubleshooting script that should be run via ./restart_install.sh in /root to run when installing or starting new software fails for whatever reason. The script will change the /etc/fstab entries generated by the hardening.sh script to the default values generated by the Debian Bookworminstallation process and will also not load the /etc/sysctl.d/99-local.hardened preset, so that no /etc/fstab restrictions on the file system and no restrictions on further kernel and network stack hardening are implemented, to easily check if the hardened setup might interfere with new software components being installed.

  • restart_selinux.sh is a script that should be run via ./restart_selinux.sh in /root to set SELinux to enforce mode while it is already in permissive mode.

  • restart_ssh_hotfix.sh is called by the generated cron entry each time the system is rebooted to stop and start the SSH daemon to fix common binding errors caused by SSH being loaded at boot time before the network stack has been set up. Additionally, an /etc/systemd/system/ssh.service.d/override.conf is written by the hardening.sh script to provide multiple means of ensuring that the SSH daemon is properly started after a reboot.

8. Resources

8.1. Tutorials

8.6.1. Error handling

9. Epilog

9.1. Acknowledgements

I would like to express my sincere gratitude to Mr Who-wants-to-live-forever for his gracious support and insightful and profound criticism.

9.2. Changelog

Available at: /doc/CHANGELOG.md

9.3. Code Check Tools

Available at: /doc/CODECHECK.md

9.4. Screenshots

Available at: /doc/SCREENSHOTS.md

9.5. Security Policy

Available at: /doc/SECURITY.md

9.6. Troubleshooting

Available at: /doc/TROUBLESHOOTING.md

9.7. Audits

9.7.1. SSH Server Configuration

Available at: /doc/SSHAUDIT.md


no tracking | no logging | no advertising | no profiling | no bullshit

Description
No description provided
Readme EUPL-1.2 19 MiB
Languages
Shell 100%