From 33c4d58bb7d9ea91acd2f97de6e005484d3582f7 Mon Sep 17 00:00:00 2001 From: Leora Date: Wed, 19 Nov 2025 05:24:45 -0600 Subject: [PATCH 1/6] Auto SSH connection whitelist feat & whitelist deduplication. --- du_setup.sh | 103 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 37 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index 9e0ada2..d9d61bd 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -3651,48 +3651,77 @@ configure_fail2ban() { print_section "Fail2Ban Configuration" # --- Collect User IPs to Ignore --- - local IGNORE_IPS="127.0.0.1/8 ::1" - local INVALID_IPS="" + local -a IGNORE_IPS=("127.0.0.1/8" "::1") # Array for easier dedup. + local prompt_change="" - 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" + # NEW: Auto-detect and offer to whitelist current SSH connection + if [[ -n "$SSH_CONNECTION" ]]; then + local CURRENT_IP="${SSH_CONNECTION%% *}" + print_info "Detected SSH connection from: $CURRENT_IP" - read -rp "$(printf '%s' "${CYAN}IPs to ignore: ${NC}")" CUSTOM_IPS + if confirm "Whitelist your current IP ($CURRENT_IP) in Fail2Ban?"; then + if validate_ip_or_cidr "$CURRENT_IP"; then + IGNORE_IPS+=("$CURRENT_IP") + print_success "Added your current IP to whitelist." + log "Auto-whitelisted SSH connection IP: $CURRENT_IP" + else + print_warning "Could not validate current IP. Please add it manually." + fi + fi + prompt_change=" additional" # Modifies following prompt based on presence of SSH connection. + fi - 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++)) + if confirm "Add$prompt_change IP addresses or CIDR ranges to Fail2Ban ignore list (e.g., Tailscale)?"; then + while true; do + local -a WHITELIST_IPS=() + log "Prompting user for IP addresses or CIDR ranges to whitelist via Fail2Ban ignore list..." + printf '%s\n' "${CYAN}Enter IP addresses or CIDR ranges to whitelist, separated by spaces.${NC}" + printf '%s\n' "Examples:" + printf ' %-24s %s\n' "Single IP:" "192.168.1.100" + printf ' %-24s %s\n' "CIDR Range:" "10.0.0.0/8" + printf ' %-24s %s\n' "IPv6 Address:" "2606:4700::1111" + read -ra WHITELIST_IPS -p " > " + if (( ${#WHITELIST_IPS[@]} == 0 )); then + print_info "No IP addresses entered. Skipping." + break + fi + local valid=true + local -a INVALID_IPS=() + for ip in "${WHITELIST_IPS[@]}"; do + if ! validate_ip_or_cidr "$ip"; then + valid=false + INVALID_IPS+=("$ip") 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" + if [[ "$valid" == true ]]; then + IGNORE_IPS+=( "${WHITELIST_IPS[@]}" ) + break + else + local s + (( ${#INVALID_IPS[@]} > 1 )) && s="s" # Plural if > 1 + print_error "Invalid IP$s: ${INVALID_IPS[*]}" + printf '%s\n' "Please try again. Leave blank to skip." 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)." + done fi + # Deduplicate final IGNORE_IPS + if (( ${#IGNORE_IPS[@]} > 0 )); then + local -A seen=() + local -a unique=() + for ip in "${IGNORE_IPS[@]}"; do + [[ -z ${seen[$ip]} ]] && { + seen[$ip]=1 + unique+=( "$ip" ) + } + done + IGNORE_IPS=( "${unique[@]}" ) + fi + local WHITELIST_STR + printf -v WHITELIST_STR "Whitelisting:\n" + for ip in "${IGNORE_IPS[@]:2}"; do # Skip first two entries in console output ("127.0.0.1/8" "::1"). + printf -v WHITELIST_STR "%s %s\n" "$WHITELIST_STR" "$ip" + done + print_info "$WHITELIST_STR" # --- Define Desired Configurations --- local UFW_PROBES_CONFIG @@ -3707,7 +3736,7 @@ EOF local JAIL_LOCAL_CONFIG JAIL_LOCAL_CONFIG=$(cat < 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" From f89ba12361dd54b8f2bb89e25f11a0a30ec3f76c Mon Sep 17 00:00:00 2001 From: Leora Date: Wed, 19 Nov 2025 11:54:54 -0600 Subject: [PATCH 2/6] Declared unset variables. Fixed console output based on VERBOSE state. --- du_setup.sh | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index d9d61bd..5d37926 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -3652,6 +3652,7 @@ configure_fail2ban() { # --- Collect User IPs to Ignore --- local -a IGNORE_IPS=("127.0.0.1/8" "::1") # Array for easier dedup. + local -a INVALID_IPS=() local prompt_change="" # NEW: Auto-detect and offer to whitelist current SSH connection @@ -3671,7 +3672,8 @@ configure_fail2ban() { prompt_change=" additional" # Modifies following prompt based on presence of SSH connection. fi - if confirm "Add$prompt_change IP addresses or CIDR ranges to Fail2Ban ignore list (e.g., Tailscale)?"; then + if [[ $VERBOSE != false ]] && \ + confirm "Add$prompt_change IP addresses or CIDR ranges to Fail2Ban ignore list (e.g., Tailscale)?"; then while true; do local -a WHITELIST_IPS=() log "Prompting user for IP addresses or CIDR ranges to whitelist via Fail2Ban ignore list..." @@ -3686,7 +3688,7 @@ configure_fail2ban() { break fi local valid=true - local -a INVALID_IPS=() + INVALID_IPS=() for ip in "${WHITELIST_IPS[@]}"; do if ! validate_ip_or_cidr "$ip"; then valid=false @@ -3697,10 +3699,10 @@ configure_fail2ban() { IGNORE_IPS+=( "${WHITELIST_IPS[@]}" ) break else - local s + local s="" (( ${#INVALID_IPS[@]} > 1 )) && s="s" # Plural if > 1 print_error "Invalid IP$s: ${INVALID_IPS[*]}" - printf '%s\n' "Please try again. Leave blank to skip." + printf '%s\n\n' "Please try again. Leave blank to skip." fi done fi @@ -3709,19 +3711,21 @@ configure_fail2ban() { local -A seen=() local -a unique=() for ip in "${IGNORE_IPS[@]}"; do - [[ -z ${seen[$ip]} ]] && { + if [[ ! -v seen[$ip] ]]; then seen[$ip]=1 unique+=( "$ip" ) - } + fi done IGNORE_IPS=( "${unique[@]}" ) fi - local WHITELIST_STR - printf -v WHITELIST_STR "Whitelisting:\n" - for ip in "${IGNORE_IPS[@]:2}"; do # Skip first two entries in console output ("127.0.0.1/8" "::1"). - printf -v WHITELIST_STR "%s %s\n" "$WHITELIST_STR" "$ip" - done - print_info "$WHITELIST_STR" + if (( ${#IGNORE_IPS[@]} > 2 )); then + local WHITELIST_STR + printf -v WHITELIST_STR "Whitelisting:\n" + for ip in "${IGNORE_IPS[@]:2}"; do # Skip first two entries in console output ("127.0.0.1/8" "::1"). + printf -v WHITELIST_STR "%s %s\n" "$WHITELIST_STR" "$ip" + done + print_info "$WHITELIST_STR" + fi # --- Define Desired Configurations --- local UFW_PROBES_CONFIG @@ -3793,6 +3797,9 @@ EOF # Show how to add IPs later if (( ${#INVALID_IPS[@]} > 0 )) || confirm "Show instructions for adding IPs later?" "n"; then printf "\n" + if [[ $VERBOSE == false ]]; then + printf '%s\n' "${PURPLE}ℹ Fail2Ban ignore list modification:${NC}" + fi 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" From de930c0705c4af03b8473bfd48b48398997b1088 Mon Sep 17 00:00:00 2001 From: Leora Date: Wed, 19 Nov 2025 12:00:43 -0600 Subject: [PATCH 3/6] Version bump (v0.77.1) & sha256 update --- README.md | 8 ++++---- du_setup.sh | 7 ++++--- du_setup.sh.sha256 | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d0d39fe..2d4cb72 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ----- -**Version:** v0.77 +**Version:** v0.77.1 -**Last Updated:** 2025-11-17 +**Last Updated:** 2025-11-19 **Compatible With:** @@ -87,12 +87,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e` +`2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e du_setup.sh | sha256sum --check +echo 2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh b/du_setup.sh index 5d37926..5b86690 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -1,8 +1,9 @@ #!/bin/bash # Debian and Ubuntu Server Hardening Interactive Script -# Version: 0.77 | 2025-11-17 +# Version: 0.77.1 | 2025-11-19 # Changelog: +# - v0.77.1: Auto SSH connection whitelist feat & whitelist deduplication. # - 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. @@ -83,7 +84,7 @@ set -euo pipefail # --- Update Configuration --- -CURRENT_VERSION="0.77" +CURRENT_VERSION="0.77.1" SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh" CHECKSUM_URL="${SCRIPT_URL}.sha256" @@ -234,7 +235,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.77 | 2025-11-17 ║${NC}" + printf '%s\n' "${CYAN}║ v0.77.1 | 2025-11-19 ║${NC}" printf '%s\n' "${CYAN}║ ║${NC}" printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}" printf '\n' diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index e0af13c..b6a9d11 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -c0ba3b6fcb9022895c79f809b6e432fd4446f7464fc090d15d361508e234289e du_setup.sh +2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD du_setup.sh From 260406cb2bcaacabc6c60863bb30516396059a9d Mon Sep 17 00:00:00 2001 From: Leora Date: Wed, 19 Nov 2025 12:11:40 -0600 Subject: [PATCH 4/6] Add Tailscale range example. --- README.md | 4 ++-- du_setup.sh | 1 + du_setup.sh.sha256 | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d4cb72..c10be24 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD` +`AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo 2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD du_setup.sh | sha256sum --check +echo AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh b/du_setup.sh index 5b86690..90be215 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -3683,6 +3683,7 @@ configure_fail2ban() { printf ' %-24s %s\n' "Single IP:" "192.168.1.100" printf ' %-24s %s\n' "CIDR Range:" "10.0.0.0/8" printf ' %-24s %s\n' "IPv6 Address:" "2606:4700::1111" + printf ' %-24s %s\n' "Tailscale Range:" "100.64.0.0/10" read -ra WHITELIST_IPS -p " > " if (( ${#WHITELIST_IPS[@]} == 0 )); then print_info "No IP addresses entered. Skipping." diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index b6a9d11..a421067 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -2ADF74FB455EE3BC49463BA7BE4C1A1417D6C546066E5CF2A2A06DC7FABD17FD du_setup.sh +AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD du_setup.sh From 05b385e9031537d650ddd06b707eb9a87aea515f Mon Sep 17 00:00:00 2001 From: buildplan Date: Wed, 19 Nov 2025 20:05:48 +0000 Subject: [PATCH 5/6] checksum v0.77.1 --- du_setup.sh.sha256 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index a421067..853bfd7 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD du_setup.sh +3ea3416cf0916ea92c382e1c899de0ef2f29535c9c93d1fa7466b4a78e1bb26d du_setup.sh From 64854aff71a79479e193c6938c1545636e48d40c Mon Sep 17 00:00:00 2001 From: buildplan Date: Wed, 19 Nov 2025 20:07:13 +0000 Subject: [PATCH 6/6] update checksum --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c10be24..b72eb3f 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD` +`3ea3416cf0916ea92c382e1c899de0ef2f29535c9c93d1fa7466b4a78e1bb26d` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo AE1100E1AF42E7EA2F7CBEC959930C8AB8FE2B87F488CBCD83713FBCADFF06DD du_setup.sh | sha256sum --check +echo 3ea3416cf0916ea92c382e1c899de0ef2f29535c9c93d1fa7466b4a78e1bb26d du_setup.sh | sha256sum --check ``` ### 3. Run the Script