Automates system configuration, hardening, and tooling setup for Debian servers with profile-based defaults and safe security configurations.
Designed for Debian Server, but compatible with Ubuntu Server distributions.
For Ubuntu Desktop, see: github.com/franckferman/ubuntu-post-install
- Profile-based configuration for different deployment scenarios
- VPS-safe security hardening to prevent remote lockouts
- Modular network hardening with 9 configurable components
- Multiple firewall engines: UFW, nftables, iptables
- Customizable service and package hardening
- Secure defaults that preserve functionality
- Proxmox and Docker compatibility
- APT packages with specialized tool integration
# Download script
curl -O https://raw.githubusercontent.com/franckferman/debian-server-post-install/stable/debian-server-post-install.sh
chmod +x debian-server-post-install.sh
# Or direct execution (basic profile only - review first!)
curl -fsSL https://raw.githubusercontent.com/franckferman/debian-server-post-install/stable/debian-server-post-install.sh | bash
# For root users (add --allow-root)
./debian-server-post-install.sh --allow-root
# Direct with arguments (download first)
curl -fsSL https://raw.githubusercontent.com/franckferman/debian-server-post-install/stable/debian-server-post-install.sh | bash -s -- --server-profile dev# Basic installation (VPS-safe, no Docker)
./debian-server-post-install.sh
# Production server with Docker
./debian-server-post-install.sh --server-profile prod
# Development server with full stack
./debian-server-post-install.sh --server-profile dev
# Maximum security (still VPS-safe)
./debian-server-post-install.sh --server-profile hardened
# Default + Docker installation
./debian-server-post-install.sh --install-docker # docker.io (default)
./debian-server-post-install.sh --docker-type io # docker.io (explicit)
./debian-server-post-install.sh --docker-type ce # docker-ce (official)
# Examples with different types
./debian-server-post-install.sh --server-profile default --docker-type ce
./debian-server-post-install.sh --server-profile default --install-docker| Profile | Editor | Firewall | VIM | SSH | Apps | Use Case |
|---|---|---|---|---|---|---|
| default | both | ufw + hardened | minimal | VPS-safe | server (36) | General purpose |
| prod | both | nftables + hardened | minimal | VPS-safe | server (36) | Production ready |
| dev | both | ufw + transparent | full | VPS-safe | full (57) | Development friendly |
| minimal | vim | ufw + hardened | minimal | VPS-safe | minimal (5) | Lightweight essential |
| hardened | vim | nftables + hardened | bare | VPS-safe | defense (47) | Maximum security |
+ Both editors (Vim + Neovim/LazyVim)
+ UFW firewall with hardened rules
+ Minimal Vim preset (stable)
+ Monitoring and logging enabled
- No Docker (use --docker-type to install)
+ Network hardening: ICMP/TCP/Source routing protection active
- Network hardening: IPv6/Anti-spoofing/Connection limits commented (safe)+ nftables firewall (performance)
+ SSH hardening enabled
+ Docker + Compose
+ Enhanced monitoring/logging
+ Network hardening disabled for dev (transparent firewall)
+ All other security hardening active+ UFW transparent firewall (no blocking)
+ Full Vim preset (IDE-like)
+ Nerd Fonts for terminal
+ Docker + Compose
+ Complete development stack (Node.js, Go, etc.)
- Monitoring disabled (lighter)
- Network hardening disabled (development transparent)+ Vim only (no Neovim)
+ Essential tools only (5 packages)
- No Docker/monitoring
+ Essential security only
+ Same network hardening as default+ Bare Vim preset (minimal surface)
+ nftables firewall
+ USBGuard enabled
+ Defense apps profile (security tools)
- No Docker (reduced attack surface)
+ All basic hardening features active
+ Same network hardening as default (conservative)When you choose a --server-profile, it automatically sets the --apps-profile:
| SERVER_PROFILE | → APPS_PROFILE | Total Packages | Logic |
|---|---|---|---|
| default | → server | 36 | Balanced server with management tools |
| prod | → server | 36 | Production server with same package set |
| dev | → full | 57 | Development server with full toolchain |
| minimal | → minimal | 5 | Lightweight server, essential only |
| hardened | → defense | 47 | Security-focused with audit tools |
Important: You can override this with --apps-profile <profile> to mix and match:
# Server profile "default" but with enterprise packages
./script.sh --server-profile default --apps-profile enterprise
# Production server config but minimal packages
./script.sh --server-profile prod --apps-profile minimalSERVER_PROFILE configures the server's overall behavior and defaults:
default= Balanced server configuration (UFW firewall, monitoring enabled)prod= Production server (nftables, Docker enabled)dev= Development server (transparent firewall, full vim)minimal= Lightweight server (vim only, no monitoring)hardened= Security-focused server (nftables, USBGuard)
APPS_PROFILE determines which software packages are installed:
- Uses a cumulative inheritance system where higher profiles include all lower levels
- You choose ONE apps profile, but it includes all the packages from levels below it
Level 1: minimal (5)
↓
Level 2: default (29) = minimal + comfort tools
↓
Level 3: server (36) = default + server management tools
↓
Level 4A: minimal-development (32) = server + light dev tools
Level 4B: security (39) = server + security tools
↓ ↓
Level 5A: development (43) Level 5B: defense (47) = security + blue team
↓ Level 5C: offsec (40) = security + red team
Level 6: full (57) = development + defense + offsec
↓
Level 7: enterprise (60) = full + compliance + backup-manager
| Profile | Total | Includes ALL Packages From | Adds to Previous Level |
|---|---|---|---|
| minimal | 5 | - | git, vim, curl, fail2ban, tmux |
| default | 29 | minimal | wget, zsh, htop, python3, build-essential, jq |
| server | 36 | minimal + default | logrotate, screen, cron, rsyslog, vnstat |
| minimal-development | 32 | minimal + default + server | python3-dev, make, cmake, golang-go |
| development | 43 | minimal + default + server + minimal-dev | nodejs, docker, ansible, postgresql-client |
| security | 39 | minimal + default + server | nmap, tcpdump |
| defense | 47 | minimal + default + server + security | lynis, wireshark, aide, rkhunter |
| offsec | 40 | minimal + default + server + security | netcat-openbsd |
| full | 57 | development + defense + offsec | Everything from dev + security branches |
| enterprise | 60 | full + backup-manager | auditd, backup-manager, logwatch, compliance tools |
Previously: backup-manager was in server profile (37 packages)
Now: backup-manager moved to enterprise profile (60 packages)
Rationale: Modern servers often use external backup solutions (cloud, containers, infrastructure-as-code). backup-manager fits better with enterprise compliance requirements.
# Option 1: Enterprise profile (full stack + compliance + backup)
./script.sh --apps-profile enterprise
# Option 2: Add to any profile
./script.sh --apps-profile server --extra-packages backup-manager
# Option 3: Remove from any profile that includes it
./script.sh --apps-profile enterprise --skip-apt-packages backup-managergit curl vim fail2ban tmuxEssential packages for remote server management.
# Essential tools
wget zsh htop net-tools unzip tree ncdu ss lsof
# Archive tools
lsd zip unrar p7zip-full
# Infrastructure tools
build-essential software-properties-common
apt-transport-https ca-certificates gnupg lsb-release
python3 python3-pip python3-venv jq rsynclogrotate psmisc dstat iotop nethogs
sudo screen openssl ca-certificates-utils
cron anacron at rsyslog vnstatNote: backup-manager was moved to enterprise profile for modern deployment scenarios.
python3-dev make cmake pkg-config
sqlite3 golang-go# Development stack
nodejs npm golang postgresql-client mysql-client
ansible-core fzf yq ripgrep autotools-dev
# Docker (conditional on --docker-type)
docker.io docker-compose # if --docker-type io
# HashiCorp tools (via specialized function)
terraform packer vault # via _install_hashicorp_from_profilenmap tcpdumplynis rkhunter chkrootkit
wireshark-common tshark
aide debsecan debsumsnetcat-openbsdbackup-manager # Traditional backup management system
auditd sysstat acct # System auditing and accounting
logwatch logcheck # Advanced log monitoring
rng-tools haveged # Entropy generation for cryptographyNote: enterprise includes all previous levels (57 packages) + these compliance tools.
Most packages are installed via standard APT repositories in step 5.
Some tools require external repositories and use specialized functions:
HashiCorp Tools (terraform, packer, vault):
- Adds HashiCorp repository
- Called by
_install_hashicorp_from_profile()for development/full/enterprise profiles
Docker Engine:
--docker-type io: docker.io from APT (default, stable)--docker-type ce: docker-ce from official Docker repository
The script provides 9 modular network security components with individual flags. Each component can be enabled or disabled independently.
These protections target obsolete or dangerous protocols with minimal compatibility risk:
+ ICMP Redirects Protection # Prevents redirection attacks
+ Source Routing Protection # Prevents source routing attacks
+ ICMP Security Protection # Prevents smurf attacks and bogus errors
+ TCP SYN Flood Protection # Enables SYN cookiesThese features may impact complex network configurations:
- IPv6 Configuration # Safe for Proxmox/Docker
- Martians Packet Logging # Reduces log verbosity
- Anti-spoofing (rp_filter) # Safe for VLANs/complex routing
- Connection Limits Tuning # Safe for high-performance applications
- Modern Security Features # Safe for forwarding-dependent services--disable-ipv6 # Disable IPv6 completely (default, Proxmox safe)
--no-disable-ipv6 # Enable IPv6 with security hardening--disable-icmp-redirects # Disable ICMP redirect protection
--no-disable-icmp-redirects # Enable ICMP redirect protection (default)--disable-source-routing # Disable source routing protection
--no-disable-source-routing # Enable source routing protection (default)--disable-martians-logging # Disable martians packet logging (default)
--no-disable-martians-logging # Enable martians packet logging--disable-icmp-protection # Disable ICMP security protection
--no-disable-icmp-protection # Enable ICMP security protection (default)--disable-tcp-protection # Disable TCP security protection
--no-disable-tcp-protection # Enable TCP security protection (default)--disable-antispoofing # Disable anti-spoofing protection (default)
--no-disable-antispoofing # Enable anti-spoofing protection (rp_filter=1)--disable-connection-limits # Disable connection limits tuning (default)
--no-disable-connection-limits # Enable TCP connection limits tuning--disable-modern-security # Disable modern security features (default)
--no-disable-modern-security # Enable modern security features--disable-kexec # Allow kexec system call (specialized environments)
--no-disable-kexec # Disable kexec system call (default, security hardening)# VPS-SAFE defaults everywhere
SSH_KEY_ONLY=false # Passwords allowed (no lockout)
DISABLE_ROOT_SSH=false # Root SSH enabled (remote access safe)
ALLOW_SSH=true # SSH enabled by default
SSH_PORT=22 # Standard port# Basic SSH Configuration
--allow-ssh # Open SSH port (default: enabled for servers)
--ssh-port <port> # SSH port number (default: 22)
--no-ssh-hardening # Disable SSH hardening completely
# Authentication Control
--ssh-key-only # Disable password authentication, keys only
--disable-root-ssh # Disable root SSH login
--no-disable-root-ssh # Allow root SSH login (default: enabled for remote access safety)
# IPv4/IPv6 Protocol Control
--ssh-enable-ipv6 # Explicitly enable IPv6 (default: enabled)
--ssh-disable-ipv6 # Force SSH to IPv4 only (AddressFamily inet)
--ssh-enable-ipv4 # Explicitly enable IPv4 (default: enabled)
--ssh-disable-ipv4 # Force SSH to IPv6 only (AddressFamily inet6)
--ssh-listen-address <ip> # Bind SSH to specific IP address (can be used multiple times)
# Legacy/Modern Compatibility
--ssh-modern-only # Remove legacy SSH options (Protocol 2, etc.)
--no-ssh-modern-only # Keep legacy SSH compatibility (default: enabled)
--ssh-rsa # Enable RSA host key for legacy compatibility (default: enabled)
--no-ssh-rsa # Disable RSA host key for modern clients only--firewall <engine>
ufw # Simple, recommended for most servers
nftables # Modern, high-performance
iptables # Legacy but widely supported--firewall-profile <profile>
hardened # Drop all incoming, allow outgoing + established
transparent # Allow all traffic (development/testing)--install-docker # Force Docker installation (docker.io by default)
--docker-type <type> # Docker type (auto-enables installation)
io # docker.io (Debian/Ubuntu repos, stable)
ce # docker-ce (Docker official repos, latest features)
--no-docker # Skip Docker installationInstallation Logic:
- default/minimal/hardened: No Docker by default
- prod/dev: Docker installed automatically
- Any profile: Use
--install-docker,--extras docker, or--docker-typeto force installation - --docker-type: Automatically enables Docker installation with specified type
- --extras docker: Works with
--docker-typeto specify engine type
Examples:
# Default profile + Docker CE
./script.sh --server-profile default --docker-type ce
./script.sh --server-profile default --extras docker --docker-type ce
# Default profile + Docker IO
./script.sh --server-profile default --install-docker
./script.sh --server-profile default --extras docker- Both types get identical security configuration
--editor <mode>
both # Vim + Neovim/LazyVim (default most profiles)
vim # Vim only (minimal/hardened)
neovim # LazyVim only
none # Skip editor installation--vim-preset <preset>
full # vim-plug + plugins (dev profile)
minimal # gruvbox + basic config (default/prod/minimal)
bare # basic settings only (hardened)The kernel hardening parameters are based on industry-standard security frameworks:
Primary Sources:
- CIS Benchmarks - Center for Internet Security Linux hardening guidelines
- ANSSI - French National Agency for Information Systems Security
- NIST SP 800-53 - National Institute of Standards and Technology controls
- KSPP - Linux Kernel Self-Protection Project recommendations
Applied Protections:
# Information Disclosure Prevention (CIS 1.6.1 + ANSSI R12)
kernel.dmesg_restrict = 1 # Prevent unprivileged kernel log access
kernel.kptr_restrict = 2 # Hide kernel pointers (anti-KASLR bypass)
kernel.yama.ptrace_scope = 1 # Restrict process debugging
# Kernel Exploit Mitigation (KSPP + CIS)
kernel.kexec_load_disabled = 1 # Disable kexec (anti-rootkit)
kernel.unprivileged_bpf_disabled = 1 # Disable unprivileged eBPF
net.core.bpf_jit_harden = 2 # Harden BPF JIT compiler
# File System Security (CIS 1.6.4 + NIST)
fs.suid_dumpable = 0 # Disable SUID core dumps
fs.protected_hardlinks = 1 # Prevent hardlink attacks
fs.protected_symlinks = 1 # Prevent symlink attacks
fs.protected_fifos = 2 # Prevent FIFO attacks
fs.protected_regular = 2 # Prevent file attacks
# ASLR Enhancement (CIS 1.6.2 + KSPP)
kernel.randomize_va_space = 2 # Full address space randomization
vm.mmap_rnd_bits = 32 # Maximum mmap entropy (64-bit)
vm.mmap_rnd_compat_bits = 16 # Maximum mmap entropy (32-bit)| Profile | Root Lock | USB Guard | Services Removed | Packages Removed |
|---|---|---|---|---|
| server | - No | - No | 9 services | 9 packages |
| workstation | - No | + Yes | 7 services | 9 packages |
| enterprise | - No | + Yes | 5 services | 9 packages |
# server (default for all server profiles)
Removes: avahi-daemon, cups, bluetooth, whoopsie, apport,
speech-dispatcher, telnet, rsh-server, tftp
# workstation
Removes: avahi-daemon, cups, whoopsie, apport,
telnet, rsh-server, tftp
# enterprise (preserves corporate services)
Removes: whoopsie, apport, telnet, rsh-server, tftp
Keeps: avahi-daemon, cups, bluetooth (corporate compatibility)# server/workstation/enterprise (aggressive cleanup)
Removes: xinetd, nis, rsh-client, talk, telnet, tftp,
rsh-server, telnet-server, tftp-server--harden-services # Enable service hardening (default)
--no-harden-services # Skip service hardening
--harden-services-list "a,b,c" # Custom service list (overrides profile)
--skip-services "x,y" # Remove services from profile list--harden-packages # Enable package hardening (default)
--no-harden-packages # Skip package removal
--harden-packages-list "a,b,c" # Custom package list (overrides profile)
--skip-packages "x,y" # Remove packages from profile list./debian-server-post-install.sh --server-profile prod --ssh-port 2222
# → Safe network hardening enabled, IPv6/anti-spoofing disabled for compatibility./debian-server-post-install.sh \
--server-profile hardened \
--no-disable-ipv6 \
--no-disable-antispoofing \
--no-disable-martians-logging \
--ssh-key-only --disable-root-ssh
# → Maximum network and SSH hardening./debian-server-post-install.sh \
--server-profile dev \
--docker-type ce \
--install-nerd-fonts \
--no-disable-ipv6
# → Full development stack with Docker CE./debian-server-post-install.sh \
--server-profile default \
--apps-profile enterprise \
--hardening-profile enterprise \
--install-usbguard \
--no-disable-antispoofing
# → Enterprise compliance tooling with USB security- IPv6: Disabled by default (safe for clustering/VMs)
- Anti-spoofing: Disabled by default (safe for VLANs/bridges)
- Modern Security: Disabled by default (forwarding=0 breaks VMs)
- All other hardening: Enabled and safe
- Modern Security: NEVER enable (forwarding=0 breaks containers)
- Anti-spoofing: May break complex networking
- docker.io vs docker-ce: Both supported via --docker-type
- All other hardening: Safe and recommended
- Anti-spoofing: Disabled by default (rp_filter=1 breaks inter-VLAN routing)
- Connection Limits: Disabled by default (may limit high-performance routing)
| Setting | default | prod | dev | minimal | hardened |
|---|---|---|---|---|---|
| EDITOR_MODE | both | both | both | vim | vim |
| VIM_PRESET | minimal | minimal | full | minimal | bare |
| FIREWALL | ufw | nftables | ufw | ufw | nftables |
| FIREWALL_PROFILE | hardened | hardened | transparent | hardened | hardened |
| APPS_PROFILE | server | server | full | minimal | defense |
| DOCKER_TYPE | io | io | io | io | io |
| HARDENING_PROFILE | server | server | server | server | server |
| HARDEN_NETWORK | true | true | false | true | true |
| SSH_KEY_ONLY | false | false | false | false | false |
| DISABLE_ROOT_SSH | false | false | false | false | false |
| LOCK_ROOT | false | false | false | false | false |
| INSTALL_USBGUARD | false | false | false | false | true |
--extras <list> # Comma-separated extras to install
docker # Enable Docker installation (use with --docker-type)
gh # GitHub CLI with official repository
hashicorp # Redirects to apps-profile development+
monitoring # Handled by existing monitoring steps
mullvad # Use --install-mullvad flag instead
--extra-packages <list> # Comma-separated APT packages to add
htop,bat,exa,fd-find # Example: modern CLI tools
--install-mullvad # Mullvad VPN client
--mullvad-source <method> # Installation method (apt|direct|github)Examples:
# Docker via extras (docker.io by default)
./script.sh --server-profile default --extras docker
# Docker CE via extras + type specification
./script.sh --server-profile default --extras docker --docker-type ce
# GitHub CLI + custom packages
./script.sh --server-profile default --extras gh --extra-packages kubectl,helm
# Development with Docker CE + GitHub CLI
./script.sh --server-profile dev --docker-type ce --extras gh--install-nerd-fonts # Install Nerd Fonts for terminal
--nerd-fonts-profile <p> # Font selection profile
minimal # FiraCode only
default # FiraCode + JetBrains
full # FiraCode + JetBrains + Hack + SourceCode--steps <selection> # Run specific steps only
--steps 1-5 # Run steps 1 through 5
--steps 1,3,5 # Run steps 1, 3, and 5
--steps 2-8 # Run steps 2 through 8- GitHub Issues: Report bugs and feature requests
- Security: All defaults are VPS-safe and tested
- Primary: Debian 11/12 Server
- Compatible: Ubuntu Server 20.04/22.04/24.04
- Ubuntu Desktop: Use ubuntu-post-install instead
Author: Franck FERMAN
Version: 2.1.0
License: MIT