diff --git a/README.md b/README.md index 46ec154..d0d39fe 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ----- -**Version:** v0.76 +**Version:** v0.77 -**Last Updated:** 2025-11-10 +**Last Updated:** 2025-11-17 **Compatible With:** @@ -87,12 +87,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`09b6b710aa75119bf1205e7f2609c6ec43d695f589a1b66415baa464ca9e169b` +`c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo 09b6b710aa75119bf1205e7f2609c6ec43d695f589a1b66415baa464ca9e169b du_setup.sh | sha256sum --check +echo c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh b/du_setup.sh index e7b89a7..9e0ada2 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -1,8 +1,10 @@ #!/bin/bash # Debian and Ubuntu Server Hardening Interactive Script -# Version: 0.76 | 2025-11-10 +# Version: 0.77 | 2025-11-17 # Changelog: +# - v0.77: User-configurable ignoreip functionality for configure_fail2ban function. +# Add a few more core packages in install_packages function. # - v0.76: Improve the flexibility of the built-in Docker daemon.json file to prevent any potential Docker issues. # - v0.75: Updated Docker daemon.json file to be more secure. # - v0.74: Add optional dtop (https://github.com/amir20/dtop) after docker installation. @@ -81,7 +83,7 @@ set -euo pipefail # --- Update Configuration --- -CURRENT_VERSION="0.76" +CURRENT_VERSION="0.77" SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh" CHECKSUM_URL="${SCRIPT_URL}.sha256" @@ -232,7 +234,7 @@ print_header() { printf '%s\n' "${CYAN}╔═════════════════════════════════════════════════════════════════╗${NC}" printf '%s\n' "${CYAN}║ ║${NC}" printf '%s\n' "${CYAN}║ DEBIAN/UBUNTU SERVER SETUP AND HARDENING SCRIPT ║${NC}" - printf '%s\n' "${CYAN}║ v0.76 | 2025-11-10 ║${NC}" + printf '%s\n' "${CYAN}║ v0.77 | 2025-11-17 ║${NC}" printf '%s\n' "${CYAN}║ ║${NC}" printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}" printf '\n' @@ -2553,6 +2555,50 @@ validate_ufw_port() { [[ "$port" =~ ^[0-9]+(/tcp|/udp)?$ ]] } +validate_ip_or_cidr() { + local input="$1" + # IPv4 address (simple check) + if [[ "$input" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then + local -a octets + IFS='.' read -ra octets <<< "$input" + for octet in "${octets[@]}"; do + if [[ "$octet" -gt 255 ]]; then + return 1 + fi + done + return 0 + fi + # IPv4 CIDR (e.g., 10.0.0.0/8) + if [[ "$input" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$ ]]; then + local ip="${input%/*}" + local cidr="${input##*/}" + local -a octets + IFS='.' read -ra octets <<< "$ip" + for octet in "${octets[@]}"; do + if [[ "$octet" -gt 255 ]]; then + return 1 + fi + done + if [[ "$cidr" -ge 0 && "$cidr" -le 32 ]]; then + return 0 + fi + return 1 + fi + # IPv6 address (basic check) + if [[ "$input" =~ ^[0-9a-fA-F:]+$ && "$input" == *":"* && "$input" != *"/"* ]]; then + return 0 + fi + # IPv6 CIDR (permissive check, allows compressed ::) + if [[ "$input" =~ ^[0-9a-fA-F:]+/[0-9]{1,3}$ && "$input" == *":"* ]]; then + local cidr="${input##*/}" + if [[ "$cidr" -ge 0 && "$cidr" -le 128 ]]; then + return 0 + fi + return 1 + fi + return 1 +} + convert_to_bytes() { local size_upper="${1^^}" # Convert to uppercase for case-insensitivity local unit="${size_upper: -1}" @@ -2811,6 +2857,7 @@ install_packages() { ufw fail2ban unattended-upgrades chrony \ rsync wget vim htop iotop nethogs netcat-traditional ncdu \ tree rsyslog cron jq gawk coreutils perl skopeo git \ + apt-listchanges ca-certificates gnupg logrotate \ ssh openssh-client openssh-server; then print_error "Failed to install one or more essential packages." exit 1 @@ -3603,8 +3650,51 @@ configure_firewall() { configure_fail2ban() { print_section "Fail2Ban Configuration" + # --- Collect User IPs to Ignore --- + local IGNORE_IPS="127.0.0.1/8 ::1" + local INVALID_IPS="" + + if confirm "Add custom IP addresses or ranges to Fail2Ban ignore list (e.g., your IP, Tailscale)?"; then + print_info "Enter IP addresses or CIDR ranges to whitelist (space-separated)." + print_info "Examples: 192.168.1.100 10.0.0.0/8 100.64.0.0/10" + print_info "Tailscale range: 100.64.0.0/10" + + read -rp "$(printf '%s' "${CYAN}IPs to ignore: ${NC}")" CUSTOM_IPS + + if [[ -n "$CUSTOM_IPS" ]]; then + # Validate each IP/CIDR in the input + local VALID_IPS="" + local INVALID_COUNT=0 + + for ip in $CUSTOM_IPS; do + if validate_ip_or_cidr "$ip"; then + VALID_IPS="$VALID_IPS $ip" + else + print_error "Invalid format, skipping: $ip" + INVALID_IPS="$INVALID_IPS $ip" + ((INVALID_COUNT++)) + fi + done + + if [[ -n "$VALID_IPS" ]]; then + IGNORE_IPS="$IGNORE_IPS $VALID_IPS" + print_success "Added ${VALID_IPS// /, } to ignore list." + log "Added custom Fail2Ban ignore IPs:$VALID_IPS" + fi + + if [[ $INVALID_COUNT -gt 0 ]]; then + print_warning "$INVALID_COUNT invalid IP(s) were skipped:$INVALID_IPS" + print_info "Continuing with valid IPs only. You can add more IPs later." + log "Skipped invalid IPs:$INVALID_IPS" + fi + else + print_info "No custom IPs provided. Using defaults only." + fi + else + print_info "Using default ignore IPs only (localhost)." + fi + # --- Define Desired Configurations --- - # Define content of config file. local UFW_PROBES_CONFIG UFW_PROBES_CONFIG=$(cat <<'EOF' [Definition] @@ -3617,7 +3707,7 @@ EOF local JAIL_LOCAL_CONFIG JAIL_LOCAL_CONFIG=$(cat < "$UFW_FILTER_PATH" @@ -3667,12 +3755,27 @@ EOF print_info "Enabling and restarting Fail2Ban to apply new rules..." systemctl enable fail2ban systemctl restart fail2ban - sleep 2 # Give the service a moment to initialize. + sleep 2 if systemctl is-active --quiet fail2ban; then print_success "Fail2Ban is active with the new configuration." - # Show the status of the enabled jails for confirmation. fail2ban-client status | tee -a "$LOG_FILE" + + # Show how to add IPs later + if [[ $INVALID_COUNT -gt 0 ]] || confirm "Show instructions for adding IPs later?" "n"; then + printf "\n" + print_info "To add more IP addresses to Fail2Ban ignore list later:" + printf "%s1. Edit the configuration file:%s\n" "$CYAN" "$NC" + printf " %ssudo nano /etc/fail2ban/jail.local%s\n" "$BOLD" "$NC" + printf "%s2. Update the 'ignoreip' line under [DEFAULT]:%s\n" "$CYAN" "$NC" + printf " %signoreip = 127.0.0.1/8 ::1 YOUR_IP_HERE%s\n" "$BOLD" "$NC" + printf "%s3. Restart Fail2Ban:%s\n" "$CYAN" "$NC" + printf " %ssudo systemctl restart fail2ban%s\n" "$BOLD" "$NC" + printf "%s4. Verify the configuration:%s\n" "$CYAN" "$NC" + printf " %ssudo fail2ban-client status%s\n" "$BOLD" "$NC" + printf "\n" + log "Displayed post-installation Fail2Ban instructions." + fi else print_error "Fail2Ban service failed to start. Check 'journalctl -u fail2ban' for errors." FAILED_SERVICES+=("fail2ban") diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index 5b1802f..e0af13c 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -09b6b710aa75119bf1205e7f2609c6ec43d695f589a1b66415baa464ca9e169b du_setup.sh +c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e du_setup.sh