du_setup/walk-through.md
2025-07-01 09:45:17 +01:00

18 KiB
Raw Permalink Blame History

Setup

  • Environment: A fresh VM running Ubuntu 22.04 LTS (a supported OS) with:
    • Root privileges (sudo or direct root access).
    • Internet connectivity (for package downloads and Tailscale).
    • At least 2GB free disk space (for swap and temporary files).
    • Minimal installation (no prior SSH hardening, UFW, or Fail2Ban configured).
  • Script Version: v0.52
  • Execution Mode: Interactive (not --quiet), to capture user prompts and verify decision points.

Walkthrough

1. Preparation

  • Download and Permissions:

    • The README instructs downloading with wget https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh and setting chmod +x du_setup.sh.
    • Assumed command: sudo ./du_setup.sh.
    • The script starts with #!/bin/bash and set -euo pipefail, ensuring strict error handling.
  • Log File Creation:

    • The script creates /var/log/du_setup_$(date +%Y%m%d_%H%M%S).log (e.g., /var/log/du_setup_20250630_222800.log) with chmod 600.
    • Backup directory /root/setup_harden_backup_20250630_222800 is created with chmod 700.\c

2. Main Function Execution

check_dependencies
  • Logic: Checks for curl, sudo, and gpg. Installs missing dependencies via apt-get.
  • Simulation:
    • On a fresh Ubuntu 22.04 VM, sudo and curl are typically present, but gpg might be missing in minimal installs.
    • The script runs apt-get install -y -qq gpg if needed, which should succeed given internet access.
  • Expected Output: ✓ All essential dependencies are installed. (or installs gpg if missing).
  • Potential Issues: None likely, as apt-get update and install are robust, and internet is assumed available.
check_system
  • Logic: Verifies root privileges, OS compatibility (Ubuntu 22.04), internet connectivity, SSH service, and /var/log writability.
  • Simulation:
    • Root check: id -u returns 0 (root), passes.
    • OS check: /etc/os-release confirms ID=ubuntu, VERSION_ID=22.04, passes.
    • Container check: No container detected (/proc/1/cgroup lacks docker/lxc/kubepod), so IS_CONTAINER=false.
    • SSH check: Assumes openssh-server is installed (common in Ubuntu server). Detects ssh.service or sshd.service.
    • Internet check: curl -s --head https://archive.ubuntu.com succeeds.
    • /var/log and /etc/shadow checks: Permissions are correct (640 for /etc/shadow, writable /var/log).
  • Expected Output:
    ✓ Running with root privileges.
    ✓ Compatible OS detected: Ubuntu 22.04 LTS
    ✓ Internet connectivity confirmed.
    
  • Potential Issues: If openssh-server is missing, the script installs it later in install_packages. No issues expected.
collect_config
  • Logic: Prompts for username, hostname, pretty hostname, and SSH port. Validates inputs.
  • Simulation Inputs:
    • Username: adminuser (valid, passes validate_username).
    • Hostname: myserver (valid, passes validate_hostname).
    • Pretty hostname: My Server (optional, accepted).
    • SSH port: 2222 (default, passes validate_port).
    • Server IP: Detected via curl -s https://ifconfig.me (e.g., 192.0.2.1).
    • Confirmation: User confirms the configuration.
  • Expected Output:
    Configuration Summary:
      Username:   adminuser
      Hostname:   myserver
      SSH Port:   2222
      Server IP:  192.0.2.1
    Continue with this configuration? [Y/n]: y
    
  • Log Entry: Configuration collected: USER=adminuser, HOST=myserver, PORT=2222
  • Potential Issues: Invalid inputs (e.g., username with spaces) prompt re-entry, which is robust. No issues expected.
install_packages
  • Logic: Updates and upgrades packages, installs essentials (ufw, fail2ban, chrony, rsync, etc.).
  • Simulation:
    • apt-get update and apt-get upgrade -y run silently.
    • Installs packages like ufw, fail2ban, chrony, rsync, openssh-server, etc.
    • Assumes sufficient disk space and internet access.
  • Expected Output: ✓ Essential packages installed.
  • Potential Issues: Rare chance of apt-get failures due to repository issues, but set -e ensures the script exits on error. No issues expected in a fresh VM.
setup_user
  • Logic: Creates adminuser if it doesnt exist, sets a password (or skips for key-only), adds to sudo group, and configures SSH keys.
  • Simulation:
    • User adminuser doesnt exist, so adduser --disabled-password --gecos "" adminuser runs.
    • Password prompt: User enters securepassword123 twice, set via chpasswd.
    • SSH key prompt: User pastes a valid key (ssh-ed25519 AAAAC3Nza... user@local).
    • Key is added to /home/adminuser/.ssh/authorized_keys with chmod 600 and chown adminuser:adminuser.
    • Adds adminuser to sudo group with usermod -aG sudo adminuser.
  • Expected Output:
    ✓ User 'adminuser' created.
    ✓ SSH public key added.
    ✓ User added to sudo group.
    ✓ Sudo group membership confirmed for 'adminuser'.
    
  • Potential Issues: Password mismatch prompts re-entry. If key is invalid, user is prompted again. Robust validation prevents issues.
configure_system
  • Logic: Sets timezone, hostname, and optionally configures locales. Backs up /etc/hosts, /etc/fstab, /etc/sysctl.conf.
  • Simulation:
    • Timezone: User enters America/New_York, validated via /usr/share/zoneinfo.
    • Locale configuration: User skips (dpkg-reconfigure locales not run).
    • Hostname: Sets myserver and pretty name My Server via hostnamectl.
    • Updates /etc/hosts with 127.0.1.1 myserver.
  • Expected Output:
    ✓ Timezone set to America/New_York.
    ✓ Hostname configured: myserver
    
  • Potential Issues: Invalid timezone prompts re-entry. No issues expected.
configure_ssh
  • Logic: Hardens SSH by setting a custom port (2222), disabling root login, enforcing key-based auth, and creating /etc/issue.net. Includes rollback on failure.
  • Simulation:
    • Detects ssh.service (Ubuntu 22.04).
    • Current port: 22 (default).
    • Backs up /etc/ssh/sshd_config to /root/setup_harden_backup_20250630_222800/sshd_config.backup_*.
    • Sets port 2222 in /etc/ssh/sshd_config (Ubuntu 22.04 uses direct config).
    • Creates /etc/ssh/sshd_config.d/99-hardening.conf with:
      PermitRootLogin no
      PasswordAuthentication no
      PubkeyAuthentication yes
      MaxAuthTries 3
      ClientAliveInterval 300
      X11Forwarding no
      PrintMotd no
      Banner /etc/issue.net
      
    • Creates /etc/issue.net with a warning banner.
    • Restarts ssh.service and verifies port 2222 with ss -tuln.
    • User tests SSH: ssh -p 2222 adminuser@192.0.2.1 (assumed successful).
    • Verifies root login is disabled with ssh -p 2222 root@localhost (fails, as expected).
  • Expected Output:
    ✓ SSH service restarted on port 2222.
    ✓ Confirmed: Root SSH login is disabled.
    ✓ SSH hardening confirmed and finalized.
    
  • Potential Issues: If the user fails to test SSH on port 2222, the script rolls back to port 22. The trap ensures rollback on errors. No issues expected with correct user input.
configure_firewall
  • Logic: Configures UFW with deny incoming, allow outgoing, and specific ports (2222/tcp, optional 80/tcp, 443/tcp, 41641/udp).
  • Simulation:
    • UFW is inactive initially.
    • Sets ufw default deny incoming, ufw default allow outgoing.
    • Allows 2222/tcp (SSH).
    • User allows HTTP (80/tcp) and HTTPS (443/tcp), skips Tailscale (41641/udp) and custom ports.
    • Enables UFW with ufw --force enable.
  • Expected Output:
    ✓ HTTP traffic allowed.
    ✓ HTTPS traffic allowed.
    ✓ Firewall is active.
    Status: active
    To                         Action      From
    --                         ------      ----
    2222/tcp (Custom SSH)     ALLOW       Anywhere
    80/tcp (HTTP)             ALLOW       Anywhere
    443/tcp (HTTPS)           ALLOW       Anywhere
    
  • Potential Issues: If the VPS providers firewall blocks port 2222, the user is warned to check. UFW enable failure is caught by set -e. No issues expected.
configure_fail2ban
  • Logic: Configures Fail2Ban to monitor SSH on port 2222 with bantime=1h, findtime=10m, maxretry=3.
  • Simulation:
    • Creates /etc/fail2ban/jail.local with:
      [DEFAULT]
      bantime = 1h
      findtime = 10m
      maxretry = 3
      backend = auto
      [sshd]
      enabled = true
      port = 2222
      logpath = %(sshd_log)s
      backend = %(sshd_backend)s
      
    • Enables and restarts fail2ban.
  • Expected Output:
    ✓ Fail2Ban is active and monitoring port(s) 2222.
    Status: sshd
    
  • Potential Issues: Fail2Ban service failure is caught and exits the script. No issues expected.
configure_auto_updates
  • Logic: Configures unattended-upgrades for automatic security updates.
  • Simulation:
    • User confirms enabling auto-updates.
    • Sets unattended-upgrades/enable_auto_updates to true and runs dpkg-reconfigure.
  • Expected Output: ✓ Automatic security updates enabled.
  • Potential Issues: Package is already installed via install_packages. No issues expected.
configure_time_sync
  • Logic: Enables and verifies chrony for time synchronization.
  • Simulation:
    • systemctl enable --now chrony runs.
    • chronyc tracking confirms synchronization.
  • Expected Output:
    ✓ Chrony is active for time synchronization.
    Reference ID    : 192.168.1.1 (time.example.com)
    Stratum         : 2
    ...
    
  • Potential Issues: Chrony failure is caught and exits. No issues expected.
install_docker
  • Logic: Installs Docker if user confirms, adds adminuser to docker group, and runs a hello-world test.
  • Simulation:
    • User confirms Docker installation.
    • Removes old runtimes, adds Docker GPG key and repository, installs docker-ce, docker-ce-cli, etc.
    • Configures /etc/docker/daemon.json with log settings.
    • Adds adminuser to docker group.
    • Runs docker run --rm hello-world as adminuser.
  • Expected Output:
    ✓ Docker sanity check passed.
    NOTE: 'adminuser' must log out and back in to use Docker without sudo.
    
  • Potential Issues: Docker repository issues are caught by set -e. No issues expected with internet access.
install_tailscale
  • Logic: Installs Tailscale if confirmed, connects using a pre-auth key, and applies optional flags.
  • Simulation:
    • User confirms Tailscale installation.
    • Chooses standard Tailscale (option 1).
    • Enters key: tskey-auth-xyz123.
    • Skips additional flags ( --ssh, --advertise-exit-node, etc.).
    • Runs tailscale up --auth-key=tskey-auth-xyz123 --operator=adminuser.
    • Verifies connection with tailscale ip (e.g., 100.64.0.1).
  • Expected Output:
    ✓ Tailscale connected successfully. Node IPv4 in tailnet: 100.64.0.1
    
  • Potential Issues: Invalid key or network issues are logged to /tmp/tailscale_status.txt. Retries (3x) mitigate transient failures.
setup_backup
  • Logic: Configures rsync backups over SSH with optional notifications and a test backup.
  • Simulation:
    • User confirms backup setup.
    • Backup destination: u12345@u12345.your-storagebox.de.
    • Port: 23 (Hetzner).
    • Remote path: /home/backups/.
    • Hetzner mode: Enabled (uses -s for ssh-copy-id).
    • Key copy: Manual (user runs ssh-copy-id -p 23 -i /root/.ssh/id_ed25519.pub -s u12345@u12345.your-storagebox.de).
    • Creates /root/.ssh/id_ed25519 if missing.
    • Creates /root/rsync_exclude.txt with defaults.
    • Cron schedule: 5 3 * * * (daily at 3:05 AM).
    • Notifications: Skipped.
    • Test backup: User confirms, creates /root/test_backup_*, runs rsync to u12345@u12345.your-storagebox.de:/home/backups/test_backup/.
  • Expected Output:
    ✓ Root SSH key generated at /root/.ssh/id_ed25519
    ACTION REQUIRED: Copy the root SSH key to the backup destination.
    The root user's public key is: ssh-ed25519 AAAAC3Nza... root@myserver
    Run the following command: ssh-copy-id -p "23" -i "/root/.ssh/id_ed25519.pub" -s "u12345@u12345.your-storagebox.de"
    ✓ Rsync exclude file created.
    ✓ Test backup successful! Check /var/log/backup_rsync.log for details.
    ✓ Backup cron job scheduled: 5 3 * * *
    
  • Potential Issues: If the SSH key isnt copied, the test backup fails, logged to /var/log/backup_rsync.log. Manual copy instructions are clear. No issues expected with correct setup.
configure_swap
  • Logic: Configures a swap file if confirmed, with default size 2G.
  • Simulation:
    • User confirms swap creation.
    • Size: 2G.
    • Disk space check: Assumes >2GB available.
    • Creates /swapfile with fallocate, chmod 600, mkswap, swapon.
    • Adds /swapfile none swap sw 0 0 to /etc/fstab.
    • Sets vm.swappiness=10, vm.vfs_cache_pressure=50 in /etc/sysctl.d/99-swap.conf.
  • Expected Output:
    ✓ Swap file created: 2G
    ✓ Swap entry added to /etc/fstab.
    ✓ Swap settings applied to /etc/sysctl.d/99-swap.conf.
    NAME      TYPE  SIZE  USED PRIO
    /swapfile file   2G    0B   -2
    
  • Potential Issues: Insufficient disk space exits the script. No issues expected.
configure_security_audit
  • Logic: Runs Lynis and (on Debian) debsecan if confirmed.
  • Simulation:
    • User confirms audit.
    • Installs lynis, runs lynis audit system --quick.
    • Skips debsecan (Ubuntu 22.04, not supported).
    • Logs to /var/log/setup_harden_security_audit_20250630_222800.log.
    • Extracts hardening index (e.g., 75).
  • Expected Output:
    ✓ Lynis audit completed. Check /var/log/setup_harden_security_audit_20250630_222800.log for details.
     debsecan is not supported on Ubuntu. Skipping debsecan audit.
    
  • Potential Issues: Lynis failure is logged and doesnt exit the script. No issues expected.
final_cleanup
  • Logic: Runs apt-get update, upgrade, autoremove, autoclean, and reloads daemons.
  • Simulation: All commands succeed.
  • Expected Output: ✓ Final system update and cleanup complete.
  • Potential Issues: Repository issues are logged as warnings, not fatal. No issues expected.
generate_summary
  • Logic: Summarizes configuration, checks service status, and provides verification steps.
  • Simulation:
    • Services (ssh.service, fail2ban, chrony, ufw, docker, tailscaled) are active.
    • Backup is configured, test successful.
    • Tailscale is connected (IP: 100.64.0.1).
    • Audit ran, hardening index: 75, debsecan: Not supported on Ubuntu.
  • Expected Output:
    Setup Complete!
    ✓ Service ssh.service is active.
    ✓ Service fail2ban is active.
    ✓ Service chrony is active.
    ✓ Service ufw is active.
    ✓ Service docker is active.
    ✓ Service tailscaled is active and connected.
    ✓ Security audit performed.
    Configuration Summary:
      Admin User:      adminuser
      Hostname:        myserver
      SSH Port:        2222
      Server IP:       192.0.2.1
      Remote Backup:   Enabled
        - Backup Script: /root/run_backup.sh
        - Destination:   u12345@u12345.your-storagebox.de
        - SSH Port:      23
        - Remote Path:   /home/backups/
        - Cron Schedule: 5 3 * * *
        - Notifications: None
        - Test Status:   Successful
      Tailscale:       Enabled
        - Server:        https://controlplane.tailscale.com
        - Tailscale IPs: 100.64.0.1
        - Flags:         None
      Security Audit:  Performed
        - Audit Log:     /var/log/setup_harden_security_audit_20250630_222800.log
        - Hardening Index: 75
        - Vulnerabilities: Not supported on Ubuntu
      Log File:        /var/log/du_setup_20250630_222800.log
      Backups:         /root/setup_harden_backup_20250630_222800
    Post-Reboot Verification Steps:
      - SSH access:       ssh -p 2222 adminuser@192.0.2.1
      - Firewall rules:   sudo ufw status verbose
      - Time sync:        chronyc tracking
      - Fail2Ban status:  sudo fail2ban-client status sshd
      - Swap status:      sudo swapon --show && free -h
      - Hostname:         hostnamectl
      - Docker status:    docker ps
      - Tailscale status: tailscale status
      - Remote Backup:
          - Verify SSH key: sudo cat /root/.ssh/id_ed25519.pub
          - Copy key if needed: ssh-copy-id -p 23 -s u12345@u12345.your-storagebox.de
          - Test backup:     sudo /root/run_backup.sh
          - Check logs:      sudo less /var/log/backup_rsync.log
      - Security Audit:
          - Check results:   sudo less /var/log/setup_harden_security_audit_20250630_222800.log
    ⚠ ACTION REQUIRED: Ensure the root SSH key (/root/.ssh/id_ed25519.pub) is copied to u12345@u12345.your-storagebox.de.
    ⚠ A reboot is required to apply all changes cleanly.
    Reboot now? [Y/n]: n
    ⚠ Please reboot manually with 'sudo reboot'.
    
  • Potential Issues: If services fail, theyre listed in FAILED_SERVICES. Backup key copy warning for manual mode. No issues expected.

Potential Runtime Issues

  • SSH Lockout: If the user fails to test SSH on port 2222, the script rolls back to port 22, preventing lockout. The warning to test in a separate terminal is clear.
  • Backup Failure: If the root SSH key isnt copied to the backup server, the test backup fails, and logs provide clear troubleshooting steps (e.g., ssh-copy-id, nc -zv).
  • Tailscale: Invalid keys or network issues (e.g., UDP 41641 blocked) are caught with retries and logged to /tmp/tailscale_status.txt.
  • Disk Space: Swap creation checks available space, exiting if insufficient. Assumed 2GB available in the VM.
  • Package Installation: Repository failures are caught by set -e, and the script exits cleanly.