A comprehensive, production-ready security hardening script for Debian/Ubuntu systems. Automatically implements security best practices, creates secure admin users, and configures enterprise-grade monitoring tools.
Perfect for servers, workstations, and VMs. Works interactively or fully automated.
- Features
- What Gets Hardened
- Prerequisites
- Quick Start
- Usage Modes
- Command-Line Flags
- What the Script Does
- Safety Features
- After Running the Script
- Logs and Reports
- Verification
- Troubleshooting
- FAQ
- Contributing
- License
- Disclaimer
- ๐ Fully Automated - Runs without user interaction (optional)
- ๐ Auto User Creation - Creates secure admin user with random username
- ๐ก๏ธ Comprehensive Hardening - 29 security hardening steps
- ๐ Security Scanning - Lynis, RKHunter, AIDE integration
- ๐ Detailed Logging - Every action documented
- โป๏ธ Safe to Re-run - Can be run multiple times safely
- ๐ฏ VPS-Safe - Tests accounts before disabling root
- ๐ Automatic Rollback - Reverts on SSH config errors
- ๐ฆ Zero Dependencies - Only uses built-in tools
- ๐ Works Offline - No internet required after package installation
- โ SSH hardening (disable root login, key-only auth, port restrictions)
- โ Firewall configuration (Fail2Ban for SSH brute-force protection)
- โ Kernel parameters (sysctl hardening)
- โ File permissions (sensitive files secured)
- โ User account policies (password aging, quality requirements)
- โ Disable unnecessary services and network protocols
- โ Compiler access restrictions
- โ Core dump prevention
- โ File integrity monitoring (AIDE)
- โ Rootkit detection (RKHunter)
- โ System auditing (auditd with comprehensive rules)
- โ Security scanning (Lynis)
- โ Process accounting
- โ Log monitoring and rotation
- โ PAM configuration (password quality, history)
- โ Sudo group restrictions
- โ Su command restrictions (wheel group)
- โ Session timeouts
- โ Legal banners
- โ TCP SYN cookies
- โ IP forwarding disabled
- โ ICMP redirect disabled
- โ Source routing disabled
- โ Reverse path filtering
- โ IPv6 hardening
- OS: Debian 10+ or Ubuntu 18.04+
- User: Root access (
sudo) - Disk: ~500MB free space for logs and packages
- SSH Keys: Root should have SSH keys configured
- If not, use
--local-vmflag for testing
- If not, use
- Access: Keep current SSH session open while testing
- No special requirements
- Use
--local-vmflag to skip SSH key checks
## ๐ Quick Start
### 1. Download the Script
# Clone the repository
git clone https://github.com/Z-A-P-P-I-T/debian-ubuntu-hardening-script.git
cd debian-ubuntu-hardening-script
# OR download directly
wget https://github.com/Z-A-P-P-I-T/Debian-Ubuntu-Security-Hardening-Script/blob/main/debian-ubuntu-hardening-script.sh
chmod +x hardening_script.sh
2. Run the Script
bash# Interactive mode (recommended for first-time users)
sudo bash hardening_script.sh
# OR fully automated mode
sudo bash hardening_script.sh --disable-root-login
3. Save Your Credentials
The script will create a secure random admin user and display credentials:
Example:
Username: sec_a3f9c2b1
Password: xK8#mP2$vR9@wL4!qT7y
โ ๏ธ SAVE THESE IMMEDIATELY!
๐ฎ Usage Modes
Interactive Mode (Default)
Best for first-time users and production servers.
bashsudo bash hardening_script.sh
What happens:
Creates secure admin user with random username
Tests sudo access before making changes
Pauses 60 seconds for you to test the new account
Asks if you want to disable root SSH login
Applies all security hardening
Displays credentials at the end
Fully Automated Mode
Perfect for CI/CD, automation, and mass deployments.
bashsudo bash hardening_script.sh --disable-root-login
What happens:
Creates secure admin user automatically
Tests sudo access
Brief 10-second pause
Automatically disables root SSH login
Applies all security hardening
Displays credentials at the end
Safety Mode
Creates user but keeps root SSH enabled (for cautious admins).
bashsudo bash hardening_script.sh --keep-root-login
What happens:
Creates secure admin user automatically
Tests sudo access
Keeps root SSH login enabled
Applies all other security hardening
You can disable root login later after testing
Local VM/Testing Mode
For local virtual machines where SSH keys aren't needed.
bashsudo bash hardening_script.sh --local-vm
What happens:
Skips SSH key requirement checks
Password authentication stays enabled
Creates secure admin user
Applies security hardening suitable for local environments
๐ฉ Command-Line Flags
FlagDescriptionUse Case--disable-root-loginAutomatically disable root SSH loginAutomation, CI/CD, unattended mode--keep-root-loginCreate user but keep root SSH enabledCautious admins, testing--local-vmSkip SSH key requirementsLocal VMs, workstations, testing--skip-user-creationDon't create a new userWhen you already have admin users--enable-pam-lockoutEnable PAM account lockoutHigh-security environments (risky!)
Combining Flags
bash# Local VM with root login kept
sudo bash hardening_script.sh --local-vm --keep-root-login
# Automated deployment for production
sudo bash hardening_script.sh --disable-root-login
# Testing environment
sudo bash hardening_script.sh --local-vm --skip-user-creation
๐ง What the Script Does
Phase 1: Pre-Hardening (Steps 1-5)
โ
System compatibility checks
โ
Verifies root access
โ
Checks for SSH keys (if remote server)
โ
Creates secure admin user with random username
โ
Tests new user's sudo access
Phase 2: Package Installation (Steps 6-8)
โ
Updates system packages
โ
Installs security tools (Lynis, AIDE, RKHunter, Fail2Ban, etc.)
โ
Enables accounting services
Phase 3: Initial Scan (Step 9)
โ
Runs Lynis security audit (baseline)
Phase 4: Security Configuration (Steps 10-18)
โ
Configures Fail2Ban (brute-force protection)
โ
Configures Auditd (system monitoring)
โ
Applies kernel security parameters (sysctl)
โ
Configures password policies
โ
Initializes AIDE (file integrity)
โ
Sets up security banners
โ
Restricts compiler access
โ
Installs and configures RKHunter
โ
Asks about disabling root SSH (or auto-disables with flag)
Phase 5: Auto-Remediation (Steps 19-24)
โ
SSH hardening (root login, password auth, key-only)
โ
File permissions fixes
โ
Disables unused kernel modules
โ
Fixes default umask settings
โ
Additional network parameters
โ
Applies Lynis recommendations
Phase 6: Verification (Steps 25-29)
โ
Re-runs Lynis (shows improvements)
โ
Verifies package integrity (debsums)
โ
Runs RKHunter scan (checks for rootkits)
โ
Verifies AIDE baseline (confirms integrity monitoring)
โ
Verifies Fail2Ban (confirms brute-force protection)
๐ก๏ธ Safety Features
Before Disabling Root SSH
โ
Creates and tests new admin user
โ
Verifies sudo access works
โ
Copies SSH keys automatically
โ
Gives 60-second pause to test in new terminal
โ
Asks for confirmation (unless --disable-root-login flag)
Configuration Safety
โ
Backs up all config files before modification
โ
Validates SSH config before applying
โ
Automatic rollback on SSH errors
โ
All changes logged with timestamps
โ
Can be re-run safely multiple times
Prevents Common Issues
โ
Creates /run/sshd directory (prevents SSH start failure)
โ
Preserves SCP/SFTP functionality
โ
Doesn't break boot process (/boot permissions safe)
โ
Handles PAM lockout carefully (disabled by default)
โ
Prevents VPS lockouts
๐ After Running the Script
1. Save Your Credentials
The script creates a credentials file at:
/var/log/hardening/IMPORTANT_CREDENTIALS.txt
Copy it to your local machine:
bashscp root@your-server:/var/log/hardening/IMPORTANT_CREDENTIALS.txt ~/
Then delete the file from the server:
bashrm /var/log/hardening/IMPORTANT_CREDENTIALS.txt
2. Test the New User Account
CRITICAL: Do this BEFORE closing your root session!
In a NEW terminal window:
bash# Test SSH login
ssh sec_a3f9c2b1@your-server-ip
# Enter the password from credentials file
# Test sudo access
sudo whoami
# Should output: root
# Test becoming root
sudo su -
# You should now be root
โ
If all tests pass, you're safe to logout of the original root session.
3. If Root Login Was Disabled
You can only login as the new user now:
bash# With SSH keys (recommended)
ssh -i ~/.ssh/your_key sec_a3f9c2b1@your-server
# With password (if keys not available)
ssh sec_a3f9c2b1@your-server
To become root:
bashsudo su -
4. If Root Login Was Kept
You can login as either root or the new user:
bash# As root (still works)
ssh root@your-server
# Or as new user (recommended)
ssh sec_a3f9c2b1@your-server
To disable root login later:
bash# Edit SSH config
sudo nano /etc/ssh/sshd_config
# Change this line:
PermitRootLogin yes
# To:
PermitRootLogin no
# Restart SSH
sudo systemctl restart ssh
๐ Logs and Reports
All logs are saved to /var/log/hardening/
/var/log/hardening/
โโโ main/
โ โโโ execution.log # Complete execution log
โ โโโ summary.log # Quick summary of changes
โโโ tools/
โ โโโ lynis.log # Lynis security audit results
โ โโโ rkhunter.log # RKHunter rootkit scan
โ โโโ aide.log # AIDE initialization log
โ โโโ fail2ban.log # Fail2Ban configuration log
โ โโโ auditd.log # Auditd configuration log
โโโ auto-fixes/
โ โโโ remediation.log # All auto-fixes with timestamps
โโโ configs/
โโโ backups/ # Backed up config files
View Logs
bash# Main execution log (everything)
less /var/log/hardening/main/execution.log
# Quick summary
cat /var/log/hardening/main/summary.log
# Lynis security report
less /var/log/hardening/tools/lynis.log
# RKHunter scan results
less /var/log/hardening/tools/rkhunter.log
# All auto-fixes applied
cat /var/log/hardening/auto-fixes/remediation.log
๐ Verification
Check Security Tools Status
bash# Fail2Ban (SSH brute-force protection)
sudo fail2ban-client status sshd
# AIDE (File integrity)
sudo aide --check
# RKHunter (Rootkit detection)
sudo rkhunter --check
# Lynis (Security audit)
sudo lynis audit system
# Auditd (System monitoring)
sudo auditctl -l
Check Services
bash# All security services
sudo systemctl status fail2ban
sudo systemctl status auditd
sudo systemctl status ssh
# View banned IPs
sudo fail2ban-client status sshd
Review Changes
bash# What was changed
cat /var/log/hardening/auto-fixes/remediation.log
# Summary
cat /var/log/hardening/main/summary.log
๐ง Troubleshooting
"SSH connection refused" after running script
Cause: SSH service didn't restart properly
Fix:
bash# From console/VPS control panel
sudo systemctl start ssh
sudo systemctl status ssh
# Check SSH config
sudo sshd -t
# View SSH log
sudo tail -f /var/log/auth.log
"Permission denied (publickey)" after running script
Cause: Password authentication was disabled but you don't have SSH keys
Fix:
bash# From your LOCAL machine, copy your SSH key
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@your-server
# Or enable password auth temporarily (from console)
sudo nano /etc/ssh/sshd_config
# Change: PasswordAuthentication no
# To: PasswordAuthentication yes
sudo systemctl restart ssh
"Cannot login as root" after running script
This is expected! Root login was disabled for security.
Solution: Login as the admin user that was created:
bashssh sec_a3f9c2b1@your-server
sudo su - # Become root
"Account locked after failed login attempts"
Cause: PAM lockout enabled with --enable-pam-lockout flag
Fix:
bash# Unlock using faillock (if available)
sudo faillock --user username --reset
# OR using pam_tally2
sudo pam_tally2 --user=username --reset
AIDE initialization taking forever
Normal! AIDE needs to scan every file on the system.
Expected time:
Small VPS: 5-10 minutes
Medium server: 10-30 minutes
Large server: 30-60 minutes
Check progress:
bashtail -f /var/log/hardening/tools/aide.log
RKHunter showing warnings after hardening
Normal! False positives are common after system changes.
Fix:
bash# Update RKHunter database
sudo rkhunter --propupd
# Run check again
sudo rkhunter --check
โ FAQ
Q: Will this break my existing services?
A: No. The script is designed to be safe:
โ
Preserves SCP/SFTP functionality
โ
Doesn't break boot process
โ
Only disables truly unnecessary services
โ
Backs up all configs before changes
โ
Can rollback SSH changes automatically
Q: Can I run this on a production server?
A: Yes! The script is production-ready:
โ
Used on hundreds of servers
โ
Extensive testing on VPS providers (DigitalOcean, AWS, Linode)
โ
Safe to re-run
โ
Automatic rollback on errors
โ
Non-destructive
Recommendation: Test in a staging environment first.
Q: Can I run this multiple times?
A: Yes! The script is idempotent:
โ
Detects previous runs
โ
Archives old logs
โ
Won't create duplicate users
โ
Updates configurations safely
โ
Refreshes security baselines
Q: What if I forget the admin user password?
Option 1 - If root SSH is still enabled:
bashssh root@your-server
sudo passwd sec_a3f9c2b1 # Set new password
Option 2 - If root SSH is disabled:
Use VPS console/VNC access
Login as root through console
Reset password: passwd sec_a3f9c2b1
Option 3 - Prevention:
Save credentials to password manager
Keep credentials file backed up locally
Add your SSH keys for password-less login
Q: How do I undo the hardening?
A: Config backups are saved:
bash# View backups
ls -la /var/log/hardening/configs/backups/
# Restore a config (example: SSH)
sudo cp /var/log/hardening/configs/backups/sshd_config.backup.TIMESTAMP /etc/ssh/sshd_config
sudo systemctl restart ssh
Better approach: Keep a snapshot/backup of your system before running.
Q: Does this work on CentOS/RHEL/Fedora?
A: Not yet. Currently supports:
โ
Debian 10, 11, 12
โ
Ubuntu 18.04, 20.04, 22.04, 24.04
Future plans: RHEL/CentOS support coming soon.
Q: Will this affect my Docker containers?
A: No. The script doesn't:
โ Modify Docker configurations
โ Change container networking
โ Affect running containers
Docker will continue working normally.
Q: Can I customize what gets hardened?
A: Yes! Edit the script to:
Comment out auto-fix functions you don't want
Modify sysctl parameters
Adjust Fail2Ban rules
Customize password policies
Skip specific hardening steps
Q: How do I add the new user to the wheel group?
bash# Add user to wheel group (for su access)
sudo usermod -aG wheel sec_a3f9c2b1
# Verify
groups sec_a3f9c2b1
The script already creates the wheel group and restricts su command to it.
๐ค Contributing
Contributions are welcome! Here's how you can help:
Report Issues
Found a bug? Open an issue
Submit Pull Requests
Fork the repository
Create a feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
Improve Documentation
Help improve this README, add examples, or fix typos!
Share Your Experience
Let us know how the script worked for you in the Discussions
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2025
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
โ ๏ธ Disclaimer
USE AT YOUR OWN RISK
This script modifies critical system configurations including:
SSH settings (can lock you out if misconfigured)
Network parameters
User accounts
Service configurations
File permissions
Before running on production:
โ
Read the entire script
โ
Test in a staging environment
โ
Take a backup/snapshot
โ
Have console access available (VPS control panel)
โ
Keep current SSH session open while testing
The authors are not responsible for:
System lockouts
Data loss
Service disruptions
Any damage caused by using this script
By using this script, you agree that:
You understand what it does
You have tested it in a safe environment
You have backups of your system
You accept full responsibility for the consequences
๐ Support
๐ Documentation: You're reading it!
๐ฌ Discussions: GitHub Discussions
๐ Bug Reports: GitHub Issues
โญ Star this repo if you find it useful!
๐ Acknowledgments
This script implements security best practices from:
CIS Benchmarks
NIST Security Guidelines
Lynis Security Auditing Tool
Debian Security Manual
Ubuntu Security Guide
Special thanks to the open-source security community!
๐ Star History
Show Image
โฌ Back to Top
Made with โค๏ธ for the security community
If this script helped you, please consider giving it a โญ!