CISS.2024.vps.bookworm.hardening

Overview


A) Preliminary remarks

The discussed CISS.2024.vpn.bookworm.hardening script provides state-of-the-art server-side requirements for setting up your own business and/or private IT projects on a hardened Debian Linux installation. This script follows almost all important aspects of server hardening, while at the same time offering you full flexibility to easily change the settings of the script for easy and convenient script editing. For a closer look at the settings done to harden a Debian bookworm server, see this excursion. In addition, a complete series of detailed discussions of all the settings implemented against the background of best practices and the latest recommendations of the IT security community will be started to give you a deep dive into the matter.

Let’s start with an introduction (as short as possible). This is about the goals I have in mind with this tutorial, the prerequisites needed, and the general concept behind this tutorial.

Like other tutorials from my site, this one is quite long and extensive. This is because I want to provide in-depth knowledge, so if you’re looking for a quick „copy & paste“ tutorial, you’ve probably come to the wrong place. I know this „wall of text“ can be discouraging at first. But the subject of server hardening is not necessarily trivial, and you should take the time to read this article in its entirety. This is especially important since sensitive data is often stored in your own environment. In my opinion, it is worth investing a little more time in the beginning to understand the underlying concepts and configurations. Once the server is up and running, the knowledge you have gained is worth its weight in gold: if errors occur, they can usually be fixed quite quickly, as you know exactly which concepts were used to harden a Debian Bookworm server.

For more and up-to-date information about the Debian project, visit https://www.debian.org/index.en.html.
See https://lists.debian.org/completeindex.html for the Debian mailing lists.
See https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening for the latest version of the script.

1) 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.
  • 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 trap function. Returns exit code, line number and module name both on screen and in the error log file.
  • Detailed logs available at /root/hardening/logs, including logging of user input (without logging of any credentials to be clear) and coloured log file.
  • 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 selected).
  • All files touched by the script are backed up to .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 after the setup routine.
  • Take advantage of the following bash error handling options:
set -o errexit   # Exit if a command fails.
set -o nounset   # Exit if an unset variable is used.
set -o pipefail  # Exit if a pipeline fails.
set -o noclobber # Prevent output redirection ">", ">&", "<>" from overwriting existing files.
set +o history   # Temporarily turn off history, to avoid sensitive information leakage.

2) Last test runs

Script VersionProviderDateNotes
V4.8.128Hetzner CX3211.07.2024B) E) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13)
V4.8.128Netcup Root G1110.07.2024U) E) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13)
  • 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.
  • 1) No KVM or Webconsole available.
  • 2) Grub Password Installation: checked.
  • 3) Full Disk Enryption: checked.
  • 4) /boot encryption: 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 setup: tested.

3) Main Hardening Features

Excursion Overview

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.

Ephemeral Swap Encryption

Optional ephemeral encryption of the SWAP area. In this scenario, the encrypted SWAP area will be initialised with a random new key every boot time to maximise security considerations. https://wiki.archlinux.org/title/dm-crypt/Swap_encryption

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
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"
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
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.
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
Disable Uncommon Filesystems
  • cramfs
  • fat # Not disabled in case of UEFI setup
  • freevxfs
  • jffs2
  • hfs
  • hfsplus
  • squashfs
  • udf
Disable Uncommon Network Filesystems
  • cifs
  • nfs
  • nfsv3
  • nfsv4
  • ksmbd
  • gfs2
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
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	proc	nosuid,nodev,noexec,hidepid=2		0	0
tmpfs	/dev/shm tmpfs	nodev,nosuid,noexec,relatime,size=1G   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";
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
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.
DNS Server

The following free DNS-Server are used, to not rely on standard ISP non-free server: dnsforge.de

IPv4: 176.9.93.198
IPv4: 176.9.1.117
IPv6: 2a01:4f8:151:34aa::198
IPv6: 2a01:4f8:141:316d::117

Will be changed to the coresecret.eu DNS resolver soon. Please check out coresecret.eu DNS for further information.

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
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‘.
Permissions, Authentication
  • Adding a sudoer user.
  • Further hardening such as umask 077 ( 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 /etc/cron.allow file to restrict access to cron to authorised users.
  • Hardening of files via do_hardening_etc_files() function:
    • /etc/cron.allow
    • /etc/shadow
    • /etc/login.defs
    • /etc/banner replaced with generic text.
    • /etc/issue replaced with generic text.
    • /etc/issue.net replaced with generic text.
  • Hardening of directories and files via do_hardening_files_folders() function:
    • /usr/bin/gcc
    • /usr/bin/g++
    • /usr/bin/clang
    • /usr/bin/clang++
    • /etc/cron.d
    • /etc/cron.daily
    • /etc/cron.hourly
    • /etc/cron.monthly
    • /etc/cron.weekly
    • /etc/at.deny
  • Hardening via do_hardening_grub() function:
    • /boot/grub/grub.cfg
    • /etc/grub.d
  • Overwrite protection module to opt in. In each case of 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.
  • 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 /boot encryption is recommended ).
  • Changing the machine ID to the whonix ID.
  • Change the /etc/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.
  • Restrict access to compilers to root only. See above.
Software tools installation
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.

SSH, ufw, fail2ban
  • SSH hardening:
    • Choose your port.
    • Choose whether to use a bastion or jump host.
    • Public key only, no root pasword access.
    • Restrict KEX to:
      • sntrup761x25519-sha512@openssh.com
      • curve25519-sha256@libssh.org
      • diffie-hellman-group18-sha512
      • diffie-hellman-group16-sha512
    • Restrict ciphers to:
      • aes256-gcm@openssh.com
      • chacha20-poly1305@openssh.com
    • Restrict MACs to Encrypt-Then-MAC (etm@openssh.com): This method first encrypts the data and then applies the MAC. This has the advantage that the authenticity of the encrypted data can be verified without decrypting the data. It is generally considered more secure because it avoids certain attack vectors that are possible with the MAC-Then-Encrypt method:
      • hmac-sha2-512-etm@openssh.com
      • hmac-sha2-256-etm@openssh.com
    • Restrict access via allow user policy.
      Your added sudoer will automatically be added to the SSH allow user list.
    • MaxAuthTries 2:Automatic connection termination in the event of incorrect login.
    • ClientActiveIntervaL 300: defines the maximum time during which the session may be inactive before it is closed. In this case, 300 seconds is 5 minutes.
    • ClientAliveCountMax 2: defines the number of checks to be performed before a disconnection.
    • Deactivation of unused functions:
      • AllowTcpForwarding no: Disables port forwarding.
      • X11Forwarding no: Disables remote GUI view.
      • AllowAgentForwarding no: Disables the forwarding of the SSH login.
  • 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.
  • As well as file permissions hardening.
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 on their AMD machines, so this gives you a bit more security.

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.

B) Main installation

1) Prerequisites

For an apparent setup procedure, it is recommended to install a Debian Bookworm server according to this CISS.2024.bookworm.installation Tutorial.

If you wish to add a sudoer user, please prepare a dedicated SSH public key. Likewise:

ssh-keygen -o -a 768 -t ed25519 -C "your_comment_here"

Feel free to prepare /root/server-scripts/hardening.conf in advance before editing all the variables on the CLI using nano editor.

mkdir /root/server-scripts
cd /root/server-scripts
wget --https-only https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening/raw/branch/main/hardening.conf

Edit /root/server-scripts/hardening.conf to suit your needs.

###########################################################################################
# Debian Bookworm VPS Hardening Setup Script Config File              V4.8.128.2024.07.07 #
###########################################################################################
# Copyright (c) 2019 - 2024, Marc 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                                     #
###########################################################################################

ADDUSER="Yes"
ADDSHORTCUTS="Yes"
ANSIBLE="Managed"
ARCHITECTURE="AMD64"
BOOTENCRYPTION="Yes"
CURRENTTIMEZONE="Europe/Lisbon"
EPHEMERAL_SWAP="Yes"
EPHEMERAL_SWAP_PARTITION="sda4"
GRUB_PSSWD="Yes"
HOSTNAME="fully.qualified.domain.name"
IPV4="123.123.123.123"
IPV6="AAAA:BBBB:CCCC:DDDD:EEEE:FFFF::1"
JUMPHOST="Yes"
JUMPHOST_IPV4="123.123.123.123"
JUMPHOST_IPV6="AAAA:BBBB:CCCC:DDDD:EEEE:FFFF:9999:1111"
KERNELUPDATE="Yes"
LOGROTATE_CHANGE="Yes"
LOGROTATE_COUNT="90"
LUKSITERATION="2097152"
OVERWRITEPROTECTION="Yes"
QEMUREMOVAL="Yes"
SECEXTENSIONS="selinux"
SELFCHECK="Yes"
SELFCHECKDL="Yes"
SSHKEYROUNDS="768"
SSHPORT="64000"
TRUSTKEY="Yes"
TRUSTLEVEL="5"
UFW_OUT_POLICY="deny"
USERNAME="testuser"
USERSSHPUBKEY="ssh-ed25519 BBBBC3NzaC1lZDI1NTE5DDDDIFNRPjNUxyfCE5LYZArxx/u/RdMfGz4uTxiiPAziIhel 2024_255.255.255.255_user"
VPSPROVIDER="Netcup"
ZSH_INST="Yes"

###########################################################################################
# !!! No changes below this line !!!                                                      #
###########################################################################################

CONFVERS="V4.8.128.2024.07.07"
DETECTED_LOCALE="$(grep LANG= /etc/default/locale | cut -d'=' -f2- | tr -d '"')"
SLEEPTIMER="1"
UBUNTU_CODENAME="jammy"
USERPASSWD="$(pwgen -n 32 -B -c -s -1)"
WEBSTACKSCRIPT="NO"
a) hardening.conf values

All variables must be entered in double quotes.

ADDUSER

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

ADDSHORTCUTS

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

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"

ARCHITECTURE

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

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"

CURRENTTIMEZONE

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

EPHEMERAL_SWAP=“Yes“ || „No“

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"

EPHEMERAL_SWAP_PARTITION=“sda4″

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

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"

HOSTNAME

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

IPV4

Please provide the IPv4 of the server in question.

IPV6

As a good practice, 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.

JUMPHOST

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

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.

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.

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"

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"

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

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

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"

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"

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"

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"

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"

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

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"

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"

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"

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"

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

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

USERSSHPUBKEY

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

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"

ZSH_INST

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

SLEEPTIMER

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

UBUNTU_CODENAME

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

USERPASSWD

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

WEBSTACKSCRIPT

DO NOT CHANGE. Not in use right now. The webstack script is a future script to automate the installation of the selected modules: acme.sh, Docker, Docker Compose, MariaDB, nginx, PHP, PHPmyAdmin and Redis including all necessary steps to harden the installed webstack. You can use the productive script already via:

apt install wget --no-install-recommends -y
mkdir /root/server-scripts
cd /root/server-scripts
wget --https-only https://cendev.eu/marc.weidner/CISS.2024.hardened.webstack/raw/branch/main/webstack.sh
chmod 700 webstack.sh
./webstack.sh

You must be root to call this script.

2) Quick start

Start the setup using the following commands:

apt install wget --no-install-recommends -y
mkdir /root/server-scripts
cd /root/server-scripts
wget --https-only https://cendev.eu/marc.weidner/CISS.2024.vps.bookworm.hardening/raw/branch/main/hardening.sh
chmod 700 hardening.sh
./hardening.sh

3) Setup routine

1) Overview

The setup script performs basic initialization, loads all the functions needed to start the script, and installs all the software required to run the next modules. The first dialogue that appears is for you to select which NIC to use. If only one NIC is found, this dialogue is arbitrary.

Select NIC (Screenshot: Marc Weidner)

The next prompt will prepare you to edit the conf file. Use this stop to manually edit the .conf file, and perhaps transfer it using your preferred editing method. Then press ENTER to continue.

Prompt to prepare .conf file (Screenshot: Marc Weidner)

A nano editor will open and you can either confirm and/or edit the variables. Press CTRL-O to quit nano.

Edit .conf file (Screenshot: Marc Weidner)

A summary of all variables read is displayed.

Summary of .conf file settings (Screenshot: Marc Weidner)

Compare PGP fingerprints (Screenshot: Marc Weidner)

In the next dialogue box, choose which kernel image you want to install. Select Cancel to skip this menu if you change your mind.

Select kernel image (Screenshot: Marc Weidner)

The next prompt allows you to check or change the fstab settings written by the script.

Prompt to confirm and edit /etc/fstab (Screenshot: Marc Weidner)
Edit or confirm /etc/fstab (Screenshot: Marc Weidner)

If you have selected ephemeral swap encryption, you will now be asked to confirm that the swap partition will be installed on the partition you specified in the .conf file. Press ENTER to continue.

Ephemeral SWAP partition confirmation (Screenshot: Marc Weidner)

Encyrpted /boot partition confirmation (Screenshot: Marc Weidner)

The encryption command will then prompt you to enter your passphrase and verify your input. Press ENTER to continue.

If everything is OK, type „Yes“ and press ENTER to continue.

LUKS1 preparation of /boot confirmation (Screenshot: Marc Weidner)

After encryption, you will be asked to confirm that the updated GRUB2 boot loader is to be written to the hard drive found by the setup script.

Press ENTER to confirm.

GRUB2 bootloader confirmation (Screenshot: Marc Weidner)

In the final steps of /boot encryption, you will be prompted three times for a password to change the LUKS1 iterations you specified in the .conf file.

First time: enter your previously chosen password.
Second time: either choose a new one or use the one from before.
Third time: either confirm the new one or repeat your old one a third time.

If everything went well, confirm with Yes and press ENTER.

LUKS1 iterationen update confirmation (Screenshot: Marc Weidner)

The next step will be the SSH hardening module. The module will pause before continuing. From a second terminal, log in to your machine using the newly provided IPv4:PORT credentials and confirm that you have access. Keep this terminal open at all times for security reasons.

Type Yes to continue with the setup and press ENTER.

Prompt to open new SSH session (Screenshot: Marc Weidner)

If you have GRUB password protection enabled, the command will now prompt you to enter and confirm your password.

If everything is OK, type „Yes“ and press ENTER to continue.

GRUB2 password confirmation (Screenshot: Marc Weidner)

If you have GRUB password protection enabled, the command will now prompt you to enter and confirm your password.

You will now be presented with the string that update-grub will write. Note that the output shows exactly two lines of text, with only two spaces in the second line.

Press CTRL-X to close nano.

GRUB2 final string confirmation (Screenshot: Marc Weidner)

Then press ENTER again to proceed with setup.


If you specified to install zsh: please note that this setup will run another script to install zsh. Therefore, you will need to type exit at the zsh prompt to return to the main hardening setup script.

Please follow the hardening setup script exactly as shown below:

zsh installation hint (Screenshot: Marc Weidner)
zsh installation: enter exit to switch back to hardening script (Screenshot: Marc Weidner)

If you have not chosen a secure root password, you can now change the root password. Please choose a strong one with at least 24 alphanumeric random characters or an equivalent strong dice-generated lexicon passphrase of at least eight words.

Password update for root (Screenshot: Marc Weidner)

The final summary screen gives you information about the login credentials of your possibly added sudoer, where and how to view the log file from the CLI, the password file which should be deleted asap, and a summary of your new SSH settings to log into your freshly hardened Debian bookworm server.

If you have opted in to SELinux, there are a few more steps to do. Please read the next chapter.

Otherwise, you can skip to the final considerations.

Final summary (Screenshot: Marc Weidner)
SELinux

To prepare SELinux to run in premissive mode, you must first reboot to let SELinux label the entire filesystem. The SELinux subsystem scans the entire file system and assigns each object the appropriate security context based on the SELinux policy. This process is called relabelling. It ensures that each object has a correct SELinux context that the policy can enforce:

reboot now

Then log in to the web console and enter the password for your encrypted /boot partition, if you have chosen to encrypt /boot.

Netcup websonsole encrypted /boot password prompt (Screenshot: Marc Weidner)

Next, enter the username, in this case „superadmin“, and your chosen GRUB2 password for the password protected GRUB2 boot loader, if you have chosen to password protect GRUB2.

Netcup websonsole GRUB2 password prompt (Screenshot: Marc Weidner)

Enter the password for the LVM-on-dm-crypt encrypted partition, and a second time the password for the encrypted /boot partition, if you have chosen to encrypt /boot.

Netcup websonsole 2nd time encrypted /boot password prompt (Screenshot: Marc Weidner)

As you can see, SELinux will prompt you that it is in the process of re-labelling. After SELinux has finished the process, it will reboot the system. Please log in to the webconsole one last time.

Netcup websonsole SELinux relabelling hint (Screenshot: Marc Weidner)

Execute after logging in via SSH:

root@test:/root/~#> sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             default
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

To check that SELinux is enabled and running in permissive mode. You can then force SELinux into enforced mode when you are ready.


Final considerations
Basic checks

After restarting, perform some basic checks to ensure that the system is running smoothly.

root@test:/root/~#> ls -la /root/hardening/log
total 164
drwxr-xr-x. 2 root root  4096 Jul  8 10:35 .
drwxr-xr-x. 6 root root  4096 Jul  8 10:35 ..
-rw-r--r--. 1 root root   143 Jul  8 10:27 apthardening.log
-r--------. 1 root root   298 Jul  8 10:34 ATTENTION-Passwords.log
-rw-r--r--. 1 root root     0 Jul  8 10:18 autoremove.log
-rw-r--r--. 1 root root 25955 Jul  8 10:35 cpu.log
-rw-r--r--. 1 root root   108 Jul  8 10:35 deinstall.log
-rw-r--r--. 1 root root  6977 Jul  8 10:35 device.log
-rw-r-----. 1 root root  1349 Jul  8 10:22 downloaded_modules.log
-r--------. 1 root root 32929 Jul  8 10:35 error_log_1720430338.log
-rw-r--r--. 1 root root   850 Jul  8 10:35 fail2ban.log
-rw-r--r--. 1 root root   283 Jul  8 10:32 grub.log
-r--------. 1 root root 21214 Jul  8 10:35 install_log_1720430338.log
-rw-r--r--. 1 root root  2838 Jul  8 10:35 ntps.log
-rw-------. 1 root root    41 Jul  8 10:26 selinux.log
-rw-r--r--. 1 root root   338 Jul  8 10:31 ssh.log
-rw-r--r--. 1 root root    91 Jul  8 10:35 systemctl.log
-rw-r--r--. 1 root root  1986 Jul  8 10:35 systemd-analyze.log
-rw-r--r--. 1 root root   590 Jul  8 10:35 systemsummary.log
-rw-r--r--. 1 root root  3826 Jul  8 10:35 ufw.log

cat /root/hardening/log/cpu.log: to check for CPU vulnerabilities and mitigations.

root@test:/root/~#> cat /root/hardening/log/cpu.log
...
> SUMMARY: CVE-2017-5753:OK CVE-2017-5715:OK CVE-2017-5754:OK CVE-2018-3640:OK CVE-2018-3639:OK CVE-2018-3615:OK CVE-2018-3620:OK CVE-2018-3646:OK CVE-2018-12126:OK CVE-2018-12130:OK CVE-2018-12127:OK CVE-2019-11091:OK CVE-2019-11135:OK CVE-2018-12207:OK CVE-2020-0543:OK

jboot: to check the last boot log.

root@test:/root/~#> jboot
Jul 08 13:04:35 meet.e2ee.li kernel: Linux version 6.7.12+bpo-cloud-amd64 (debian-kernel@lists.debian.org) (x86_64-linux-gnu-gcc-12 (D>
Jul 08 13:04:35 meet.e2ee.li kernel: Command line: BOOT_IMAGE=/vmlinuz-6.7.12+bpo-cloud-amd64 root=/dev/mapper/vg00-root ro security

ssf: to see if any services have failed to load.

root@test:/root/~#> ssf
root@test:/root/~#>

cysd: to check which NTPS sources are selected.

root@test:/root/~#> cysd
  . State: N - noselect, s - unsynchronised, M - missing samples,
 /         d/D - large distance, ~ - jittery, w/W - waits for others,
|          S - stale, O - orphan, T - not trusted, P - not preferred,
|          U - waits for update,, x - falseticker, + - combined, * - best.
|   Effective options   ---------.  (N - noselect, P - prefer
|   Configured options  ----.     \  T - trust, R - require)
|   Auth. enabled (Y/N) -.   \     \     Offset interval --.
|                        |    |     |                       |
S Name/IP Address        Auth COpts EOpts Last Score     Interval  Leap
=======================================================================
* ptbtime1.ptb.de           Y ----- -----   14   1.0   -56ms   +58ms  N
+ ptbtime2.ptb.de           Y ----- -----    6   3.2   -55ms   +54ms  N
+ ptbtime3.ptb.de           Y ----- -----    0   1.8   -55ms   +54ms  N
N ptbtime4.PTB.DE           Y N---- N----    0   1.0    +0ns    +0ns  N
s mmo1-ts.nts.netnod.se     Y ----- -----    0   1.0    +0ns    +0ns  ?

cytr: to check if NTP is running properly.

root@test:/root/~#> cytr
Reference ID    : C035676C (ptbtime1.ptb.de)
Stratum         : 2
Ref time (UTC)  : Mon Jul 08 18:24:30 2024
System time     : 0.000229411 seconds slow of NTP time
Last offset     : -0.000064207 seconds
RMS offset      : 0.000184657 seconds
Frequency       : 0.907 ppm slow
Residual freq   : -0.001 ppm
Skew            : 0.069 ppm
Root delay      : 0.112030201 seconds
Root dispersion : 0.001787123 seconds
Update interval : 512.3 seconds
Leap status     : Normal

f2bufw: to check for blocked IPs due to unwanted port scans on closed ports.

root@test:/root/~#> f2bufw
Status for the jail: ufw
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     814
|  `- File list:        /var/log/ufw.log
`- Actions
   |- Currently banned: 1182
   |- Total banned:     1182
   `- Banned IP list:   1.13.101.70

lsblk: to check that all partitions are mounted properly.

root@test:/root/~#> lsblk
NAME                     MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda                        8:0    0   512G  0 disk
├─sda1                     8:1    0   3.7G  0 part
├─sda2                     8:2    0   3.7G  0 part  /boot/efi
├─sda3                     8:3    0   3.7G  0 part
 └─boot_crypt           254:10   0   3.7G  0 crypt /boot
├─sda4                     8:4    0  14.9G  0 part
 └─swap                 254:9    0  14.9G  0 crypt [SWAP]
└─sda5                     8:5    0 485.9G  0 part
  └─sda5_crypt           254:0    0 485.9G  0 crypt
    ├─vg00-home          254:1    0  59.6G  0 lvm   /home
    ├─vg00-root          254:2    0  59.6G  0 lvm   /
    ├─vg00-tmp           254:3    0  14.9G  0 lvm   /tmp
    ├─vg00-var_log       254:4    0  14.9G  0 lvm   /var/log
    ├─vg00-var_tmp       254:5    0  14.9G  0 lvm   /var/tmp
    ├─vg00-var_log_audit 254:6    0  14.9G  0 lvm   /var/log/audit
    ├─vg00-usr           254:7    0 119.2G  0 lvm   /usr
    └─vg00-var           254:8    0 187.9G  0 lvm   /var
sr0                       11:0    1  1024M  0 rom

lvs: to check lvm volumes

root@test:/root/~#> lvs
  LV            VG   Attr       LSize    Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  home          vg00 -wi-ao----   59.60g
  root          vg00 -wi-ao----   59.60g
  tmp           vg00 -wi-ao----  <14.90g
  usr           vg00 -wi-ao---- <119.21g
  var           vg00 -wi-ao---- <187.90g
  var_log       vg00 -wi-ao----  <14.90g
  var_log_audit vg00 -wi-ao----  <14.90g
  var_tmp       vg00 -wi-ao----  <14.90g
Further Hardening

sysp: to load all hardened kernel settings – note that any software that needs to load kernel modules, such as docker, will fail to start. Either apply your personal settings to /etc/sysctl.d/99-local.hardened or run sysp after all your components are installed and up.

lsadt: To perform a Lynis audit. Please refer to the logs provided there for further instructions on any findings that may raise your concerns.

LAMP stack setup?

If you want to set up a LAMP stack: please continue with CISS.2024.hardened.webstack script and the accompanying Tutorial. This is a digitally signed, self-verifying shell script for setting up an all-inclusive LAMP environment that relies on the most secure ciphers and follows the latest best practices in webserver hardening to achieve a quadruple A+ rating at Qualys SSL Labs, Mozilla Observatory, immuniweb, Probely; incl. HSTS Preload preparation and HTTP/3 and QUIC support. Letsencrypt CA has been replaced by the Norwegian CA buypass.no, which supports 180-day free TLS certificates.

2) Generated scripts

The hardening script will also add the following scripts to /root

restart_crontab.sh
restart_hardening.sh
restart_install.sh
restart_selinux.sh
restart_ssh_hotfix.sh
selinux_policy.sh

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 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 bookworm installation 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.

selinux_policy.sh is a simple SELinux policy file generator.

C) Ressources

D) Changelog

DateInfo
2024.07.08Initial Version

Please consider a donation in support of my free services.