A comprehensive bash script to automate the initial configuration of fresh Linux server installations with security hardening and essential tools.
- OS Support: Debian 11/12, Ubuntu 22.04/24.04
- System Configuration:
- Timezone setup
- Swapfile creation (with dphys-swapfile support)
- Hostname configuration
- Essential Packages: Installs curl, gnupg, bash-completion, btop, sudo, and more
- Docker: Installation with automatic log rotation configuration
- User Management:
- Create passwordless sudo user
- Import SSH keys from GitHub/GitLab
- Security Hardening:
- SSH hardening (disable root login, password auth, etc.)
- fail2ban configuration
- Root account locking
- Fresh installation of supported OS
- Root access
- Internet connectivity
wget https://raw.githubusercontent.com/ditdot/server-bootstrap-script/main/bootstrap.sh
chmod +x bootstrap.shsudo ./bootstrap.sh [OPTIONS]| Option | Description |
|---|---|
-h, --help |
Show help message |
-t, --timezone ZONE |
Set timezone (e.g., America/New_York) |
-s, --swap SIZE |
Create swapfile of SIZE (e.g., 1G, 2G) |
-n, --hostname NAME |
Set server hostname |
-d, --docker |
Install Docker and configure log rotation |
-u, --user USERNAME |
Create sudo user with passwordless sudo |
-k, --ssh-key SOURCE |
SSH key source: github:USERNAME, gitlab:USERNAME, or direct URL |
--harden-ssh |
Harden SSH configuration |
--fail2ban |
Install and configure fail2ban |
--lock-root |
Lock root account (requires sudo user) |
--skip-upgrade |
Skip system upgrade |
Basic setup with timezone and swap:
sudo ./bootstrap.sh -t America/New_York -s 2GFull setup with new user from GitHub:
sudo ./bootstrap.sh -t UTC -s 1G -n myserver -d -u john -k github:john --harden-ssh --fail2ban --lock-rootSetup with GitLab SSH keys:
sudo ./bootstrap.sh -u alice -k gitlab:alice --harden-sshDocker installation only:
sudo ./bootstrap.sh -d --skip-upgrade- SSH Hardening: When using
--harden-ssh, ensure you can login with the new user before closing your current session - Root Locking: The
--lock-rootoption requires creating a sudo user first - Backups: All configuration files are backed up before modification with
.bak.{timestamp}suffix
When SSH hardening is enabled, the following settings are applied:
- Protocol 2 only
- Root login disabled
- Password authentication disabled
- Maximum authentication attempts: 3
- Client idle timeout: 300 seconds
- Maximum sessions: 2
- X11 forwarding disabled
Docker installation includes:
- Latest Docker CE from official repository
- Docker Compose plugin
- Automatic log rotation (10MB max size, 3 files)
- User added to docker group (if creating new user)
Default fail2ban settings:
- Ban time: 1 hour
- Find time: 10 minutes
- Max retries: 5 (3 for SSH)
- Email notifications to root@localhost
For development and testing:
shellcheck- Shell script static analysis toolshfmt- Shell script formatter (optional)make- Build automationdocker- For testing across different OS versions
# Install shellcheck on Debian/Ubuntu
sudo apt-get install shellcheck
# Install shfmt (optional, requires Go)
go install mvdan.cc/sh/v3/cmd/shfmt@latestmake help # Show all available targets
make check # Run all checks (lint, format, validate)
make lint # Run shellcheck
make format # Check formatting with shfmt
make test # Run basic tests
make install # Install script to /usr/local/binThis project uses:
- ShellCheck for static analysis and best practices enforcement
- shfmt for consistent code formatting
- GitHub Actions for continuous integration
- Makefile for development workflow automation
# Run basic functionality tests
make test
# Run tests in Docker containers (all supported OS)
make test-docker
# Run specific checks
make lint # ShellCheck only
make validate # Syntax validation onlyScript fails with "This script must be run as root"
- Run the script with
sudoor as root user
SSH connection lost after hardening
- Boot into recovery mode or use console access
- Check
/etc/ssh/sshd_config.d/99-hardening.conf - Restore from backup:
/etc/ssh/sshd_config.bak.{timestamp}
Swap creation fails
- Check available disk space
- If using Raspberry Pi, the script automatically uses dphys-swapfile
Docker installation fails
- Ensure the system is fully updated
- Check internet connectivity
- Verify the OS is supported
Feel free to submit issues and enhancement requests!
MIT License - feel free to use and modify as needed.