Table of Contents
- 1. System Overview and Architecture
- 2. Compatibility and Operational Modes
- 3. Core Security and System Hardening
- 4. Network Configuration and Defense
- 5. Infrastructure, Services, and Backups
- 6. Administrative Environment and Shell Customization
- 7. Auditing, Reporting, and Recovery
Technical reference for the Debian/Ubuntu Server Hardening Script (du_setup.sh).
It is a Bash-based automation tool designed for the initial provisioning and security baseline configuration of fresh server instances. This script tries to be idempotent, but it is primarily designed to be run on a brand-new system.
1. System Overview and Architecture
Script utilizes a modular architecture, uses set -euo pipefail to ensure immediate termination on error, preventing cascading failures during the hardening process. It is designed to transform a standard operating system installation into a production-ready, security-hardened environment through a series of sequential phases managed by the main() function.
Execution Flow
- Initialization: Establishes comprehensive logging to
/var/log/du_setup_*.logand creates a timestamped backup directory at/root/setup_harden_backup_*to store original configuration files (e.g.,sshd_config,fstab,hosts) before modification. - Environment Detection: Utilizes
systemd-detect-virt,dmidecode, and/sys/class/dmi/id/files to identify the server type (bare-metal, commercial Cloud VPS, or local/private VM). This detection logic informs the necessity of the "Provider Cleanup" phase. - Interactive Configuration: Collects critical parameters including the administrator username, system hostname, and custom SSH port.
- Provisioning and Hardening: Executes package installation, user management, firewall setup, SSH hardening, and kernel optimization functions.
- Reporting: Conducts security audits (Lynis/Debsecan) and generates a final status report at
/var/log/du_setup_report_*.txt.
2. Compatibility and Operational Modes
System Requirements
- Supported OS: Debian 12, 13 and Ubuntu 20.04, 22.04, 24.04 (LTS releases recommended).
- Privileges: Root execution is mandatory; the script includes an
EUIDcheck to prevent unauthorized execution. - Container Awareness: Detects Docker/LXC environments via
/proc/1/cgroupto automatically skip incompatible tasks such as swap file management and kernel parameter tuning.
Operational Modes
The script supports several arguments to control behavior, allowing for both interactive and automated use cases.
| Argument | Description |
|---|---|
(No Argument) |
Standard interactive setup with user prompts. |
--quiet |
Suppresses non-critical output for automated provisioning sequences. |
--cleanup-preview |
Runs a dry-run of the provider cleanup module; lists items to be removed without taking action. |
--cleanup-only |
Executes only the provider package and user removal routines on existing servers, skipping hardening. |
--skip-cleanup |
Executes the full hardening suite but bypasses provider package removal. |
3. Core Security and System Hardening
User Management
The script creates a new administrative account with sudo privileges to replace direct root access.
- Account Security: Users are created with
--disabled-password. A password can be set forsudoauthentication, or the user can opt for key-only access. - SSH Credentials: Supports manual entry of public keys or automatic generation of an Ed25519 key pair. If generated, the private key is displayed temporarily in the terminal and then immediately deleted from the server.
- Group Membership: The user is added to
sudoand, if Docker is installed, thedockergroup.
Kernel and Filesystem Hardening
The script applies specific sysctl parameters to address low-level network and filesystem vulnerabilities. Recommended security parameters are applied via /etc/sysctl.d/99-du-hardening.conf to mitigate common network and memory-based attacks.
Network Protection:
- IP Spoofing: Enabled via
net.ipv4.conf.all.rp_filter=1. - SYN-Flood Attacks: Mitigated by setting
net.ipv4.tcp_syncookies=1. - ICMP Redirects: Ignored to prevent route mangling (
accept_redirects=0).
Kernel Integrity:
- ASLR: Full randomization enabled via
kernel.randomize_va_space=2. - Pointer Access: Restricted via
kernel.kptr_restrict=2to prevent address leaks. - Dmesg Access: Restricted to root only via
kernel.dmesg_restrict=1.
Filesystem Security:
- Link Protection: Prevents TOCTOU race conditions by setting
fs.protected_hardlinks=1andfs.protected_symlinks=1.
Provider Package Cleanup
To reduce the attack surface on commercial VPS instances, the script scans for and removes cloud-provider-specific components:
- Agents: Targets monitoring and management tools like
qemu-guest-agent,do-agent(DigitalOcean),amazon-ssm-agent(AWS), andgoogle-osconfig-agent(GCP). - Default Users: Identifies and removes common provisioning accounts such as
ubuntu,debian,cloud-user, andec2-user. - Cloud-Init Management: Offers to disable
cloud-initservices to prevent post-provisioning configuration overwrites while maintaining package dependencies, rather than purging the package which can cause system instability.
4. Network Configuration and Defense
SSH Hardening and Rollback Safety
The configure_ssh function implements a secure protocol baseline while ensuring availability.
- Hardening: Enforces
PermitRootLogin no,PasswordAuthentication no,PubkeyAuthentication yes,X11Forwarding no, andMaxAuthTries 3via a custom configuration file at/etc/ssh/sshd_config.d/99-hardening.conf. - Custom Port: Moves SSH to a user-defined port (defaulting to 2222 if not specified).
- Rollback Mechanism: The script utilizes a
trapto handle errors during SSH configuration. If the user cannot confirm a successful connection on the new port in a separate terminal, the script automatically reverts the firewall rules and SSH service configuration to the original port (e.g., 22) to prevent administrative lockout.
Firewall (UFW)
Configures the Uncomplicated Firewall (UFW) with a "Deny Incoming / Allow Outgoing" default policy.
- IPv6 Support: Automatically enabled in
/etc/default/ufwif system support is detected. - Rule Management: Automatically allows the custom SSH port. Provides interactive prompts to allow HTTP (80), HTTPS (443), and Tailscale (UDP 41641).
- Transition Logic: Creates a temporary rule allowing the previous SSH port during the setup phase to ensure connectivity is maintained until the new configuration is verified.
Intrusion Detection Systems (IDS)
Users can select between two primary defense layers:
- Fail2Ban: Sets up a
sshdjail and a customufw-probesfilter. It parses/var/log/ufw.logfor rejected packets, blocking IPs attempting port scans or brute-force attacks. It automatically whitelists the current connecting IP. - CrowdSec: Installs the agent and firewall bouncer, enabling a collaborative reputation-based defense. It configures log acquisition for
/var/log/ufw.logand supports enrollment in the CrowdSec console.
5. Infrastructure, Services, and Backups
Automated Backups
Configures an rsync-based backup system for remote storage (e.g., Hetzner Storage Box) via the setup_backup function.
- Transport: Generates a dedicated root Ed25519 key (
/root/.ssh/id_ed25519) for passwordless authentication. Supportsssh-copy-idwith specific flags (e.g.,-sfor SFTP-only hosts). - Execution: Generates a script at
/root/run_backup.shwhich handles locking, rsync execution, log rotation, and error handling. - Scheduling: Installs a root
crontabentry for consistent execution (default: 03:05 daily). - Notifications: Integrates with ntfy.sh or Discord webhooks to report backup success or failure.
- Testing: Includes a verification function to test a single-file transfer to the destination before finalizing the schedule.
Docker and Tailscale Integration
- Docker: Installs Docker Engine, CLI, and Compose from official repositories. Configures
/etc/docker/daemon.jsonwith secure log rotation limits andlive-restoreenabled. Optionally installsdtopfor terminal-based container monitoring. - Tailscale: Automates installation and allows configuration of specific flags, including Tailscale SSH, exit node advertising, and route acceptance.
System Maintenance
- Swap Management: Detects existing swap. If absent, it creates a
/swapfile(default 2G) usingfallocate(withddfallback). It tunesvm.swappiness(default 10) andvm.vfs_cache_pressure(default 50) for performance. - Update Policy: Enables
unattended-upgradesto automatically apply security patches. - Time Synchronization: Ensures
chronyis enabled and synchronized to maintain accurate system logs.
6. Administrative Environment and Shell Customization
The script installs a customized .bashrc for the new admin user to improve operational efficiency (configure_custom_bashrc).
Features
- Prompt: Displays user, host, current directory, Git branch, background jobs, and a visual status indicator for the previous command's exit code.
- History: ISO 8601 timestamps, 10,000-line history size, and deduplication.
- Aliasing: Extensive shortcuts for system navigation (e.g.,
..,up), file management (e.g.,ll,extract,backup), and Docker operations (e.g.,dps,dlog,dcsh). - Utility Functions: Includes
sysinfofor a login dashboard containing CPU/RAM usage andbashhelpfor a categorized command reference.
7. Auditing, Reporting, and Recovery
Security Audits
- Lynis: Performs a system-wide security audit, logging detailed results to
/var/log/setup_harden_security_audit_*.logand extracting a numerical Hardening Index. - Debsecan: On Debian systems, identifies package-level CVE vulnerabilities.
Technical Hardening Comparison
The following table provides a technical comparison between standard default configurations on fresh Debian or Ubuntu installations and the hardened state applied by the du_setup.sh script (v0.79.1).
System Hardening Comparison Table
| Feature / Setting | Default State | Hardened State (Script Applied) |
|---|---|---|
| SSH Port | Port 22 | User-defined custom port (e.g., 2222) |
| SSH Root Login | Often allowed or "prohibit-password" | Explicitly disabled (PermitRootLogin no) |
| SSH Authentication | Password-based allowed | Key-based only (PasswordAuthentication no) |
| SSH Security Policy | Generic defaults | MaxAuthTries 3, ClientAliveInterval 300 |
| SSH Banner | Standard OS identification | Custom warning banner (/etc/issue.net) |
| User Privileges | Direct root or standard user | Dedicated admin user with mandatory sudo |
| Firewall (UFW) | Typically inactive | Active with "Deny Incoming" default policy |
| Firewall IPv6 | Config-dependent | Auto-detected and enabled if kernel-supported |
| Intrusion Detection | None installed | Fail2Ban (with UFW probe filters) or CrowdSec |
| Kernel Hardening | Standard vendor presets | rp_filter, tcp_syncookies, kptr_restrict |
| Process Tracing | Standard scope | Restricted via kernel.yama.ptrace_scope=1 |
| System Updates | Manual check required | Automated security updates (unattended-upgrades) |
| Time Sync | Varies by provider | Chrony active for precision network time sync |
| Swap Configuration | Provider default (often none) | Optimized /swapfile with tuned swappiness |
| Shell Experience | Generic .bashrc |
Enhanced .bashrc with smart prompt and aliases |
| Backups | Manual or provider-snapshot | Automated rsync over SSH with notifications |
Critical File Locations
| Path | Description |
|---|---|
/var/log/du_setup_*.log |
Primary execution log. |
/var/log/du_setup_report_*.txt |
Final configuration summary. |
/etc/ssh/sshd_config.d/99-hardening.conf |
Hardened SSH parameters. |
/etc/sysctl.d/99-du-hardening.conf |
Kernel hardening parameters. |
/root/run_backup.sh |
Generated automated backup script. |
/root/rsync_exclude.txt |
Exclusion list for the backup script. |
/root/setup_harden_backup_* |
Directory containing backups of original config files. |