#!/bin/bash # Production Docker Host Setup Script # This script sets up a secure, production-ready Docker host on Ubuntu Server 22.04 LTS # It includes security hardening, performance optimizations, and best practices # CAUTION: This script makes significant system changes. Use at your own risk. set -euo pipefail # --- AESTHETICS --- # Define color codes for echo messages GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' # Define the escape sequence for the alien emoji (U+1F47D) ALIEN='\xF0\x9F\x91\xBD' # Define the variable for resetting the color back to the default NC='\033[0m' # Function to print colorized output with alien emoji print_message() { local color=$1 local message=$2 echo -e "${color}${ALIEN} ${message}${NC}" } # Function to handle errors handle_error() { print_message "${RED}" "An error occurred. Exiting..." exit 1 } # Set up error handling trap 'handle_error' ERR # Check if script is run as root if [[ $EUID -ne 0 ]]; then print_message "${RED}" "This script must be run as root" exit 1 fi # Update and upgrade system print_message "${YELLOW}" "Updating and upgrading system..." apt-get update -y && apt-get upgrade -y # Install essential packages print_message "${YELLOW}" "Installing essential packages..." apt-get install -y ufw fail2ban curl wget gnupg lsb-release ca-certificates apt-transport-https software-properties-common # Set up firewall print_message "${YELLOW}" "Configuring firewall..." ufw --force reset ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw allow http ufw allow https ufw allow 2376/tcp # Docker TLS port echo "y" | ufw enable # Configure fail2ban print_message "${YELLOW}" "Configuring fail2ban..." cat < /etc/fail2ban/jail.local [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 3600 EOF systemctl enable fail2ban systemctl restart fail2ban # Harden SSH configuration print_message "${YELLOW}" "Hardening SSH configuration..." if [ -f /etc/ssh/sshd_config ]; then sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config if systemctl is-active --quiet ssh; then systemctl restart ssh elif systemctl is-active --quiet sshd; then systemctl restart sshd else print_message "${RED}" "SSH service not found. Please check your SSH configuration." fi else print_message "${RED}" "SSH configuration file not found. Please check your SSH installation." fi # Install and configure Docker print_message "${YELLOW}" "Installing Docker..." curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh # Configure Docker daemon print_message "${YELLOW}" "Configuring Docker daemon..." mkdir -p /etc/docker cat < /etc/docker/daemon.json { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "icc": false, "live-restore": true, "userland-proxy": false, "no-new-privileges": true } EOF systemctl enable docker systemctl restart docker # Install Docker Compose print_message "${YELLOW}" "Installing Docker Compose..." DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4) curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose # Create docker user and group print_message "${YELLOW}" "Creating docker user and group..." adduser --system --group --shell /bin/bash docker usermod -aG docker docker # Set up Docker network print_message "${YELLOW}" "Setting up Docker network..." docker network create --driver bridge private # Install and configure Nginx print_message "${YELLOW}" "Installing and configuring Nginx..." apt-get install -y nginx certbot python3-certbot-nginx # Set up SSL certificate renewal print_message "${YELLOW}" "Setting up SSL certificate renewal..." echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null # Install additional useful tools # print_message "${YELLOW}" "Installing additional tools..." # apt-get install -y bat btop lsd # Basic monitoring print_message "${YELLOW}" "Setting up basic system monitoring..." apt-get install -y sysstat systemctl enable sysstat systemctl start sysstat # Enable and configure auditd print_message "${YELLOW}" "Configuring auditd..." apt-get install -y auditd audispd-plugins auditctl -e 1 systemctl enable auditd systemctl start auditd # Set up log rotation print_message "${YELLOW}" "Configuring log rotation..." cat < /etc/logrotate.d/docker-logs /var/lib/docker/containers/*/*.log { rotate 7 daily compress missingok delaycompress copytruncate } EOF # Harden kernel parameters print_message "${YELLOW}" "Hardening kernel parameters..." cat <> /etc/sysctl.conf net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.icmp_ignore_bogus_error_responses = 1 EOF sysctl -p # Set up automatic security updates print_message "${YELLOW}" "Setting up automatic security updates..." apt-get install -y unattended-upgrades echo 'Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security"; };' > /etc/apt/apt.conf.d/50unattended-upgrades # Set up aliases # print_message "${YELLOW}" "Setting up aliases..." # cat <> /etc/bash.bashrc # Aliases # alias ls='lsd -lah' # alias cat='batcat' # alias top='btop' # EOF # Fix for PS1 unbound variable # echo 'if [ -z "${PS1-}" ]; then return; fi' | cat - /etc/bash.bashrc > temp && mv temp /etc/bash.hashrc # Apply aliases to current session source /etc/bash.bashrc # Clean up print_message "${YELLOW}" "Cleaning up..." apt-get autoremove -y apt-get clean # Final message print_message "${GREEN}" "Setup complete! Please reboot the system to apply all changes." print_message "${YELLOW}" "Note: Some changes may require a logout/login to take effect."