From 3091a5f6630d2e212eb2c9aacc641f2502505385 Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 09:35:04 +0100 Subject: [PATCH 1/8] feat: switch Fail2Ban banaction to nftables-allports --- du_setup.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index b21bf98..78feeca 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -1,11 +1,13 @@ #!/bin/bash # Debian and Ubuntu Server Hardening Interactive Script -# Version: 0.81.2 | 2026-08-08 +# Version: 0.81.3 | 2026-08-09 # Changelog: +# - v0.81.3: Switch Fail2Ban UFW banaction to native nftables (nftables-allports) for maximum performance and modern standard compliance. +# Ensure 'nftables' package is installed for minimal server compatibility. # - v0.81.2: Switch Fail2Ban UFW banaction to ipset for improved performance when handling large ban lists. # Update UFW SSH rule from allow to limit to provide native brute-force protection. -# - v0.81.1: Fix IPv6 connectivity issues with Secure DNS. +# - v0.81.1: Fix IPv6 connectivity issues with Secure DNS. # Implement Docker-compatible IPv6 SLAAC sysctl configuration and enable native IPv6 networking in Docker daemon. # - v0.81.0: Added optional encrypted DNS (DoT) setup using Quad9 and Cloudflare. # Includes automatic installation of systemd-resolved if needed and configuration to block tracking protocols. @@ -282,7 +284,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.81.2 | 2026-08-08 ║${NC}" + printf '%s\n' "${CYAN}║ v0.81.3 | 2026-08-09 ║${NC}" printf '%s\n' "${CYAN}║ ║${NC}" printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}" printf '\n' @@ -4065,11 +4067,10 @@ configure_firewall() { configure_fail2ban() { print_section "Fail2Ban Configuration" - # Install Fail2Ban if not present - if ! dpkg -l fail2ban | grep -q ^ii || ! dpkg -l ipset | grep -q ^ii; then - print_info "Installing Fail2Ban and ipset..." - if ! apt-get install -y -qq fail2ban ipset; then - print_error "Failed to install Fail2Ban or ipset." + if ! dpkg -l fail2ban | grep -q ^ii || ! dpkg -l nftables | grep -q ^ii; then + print_info "Installing Fail2Ban and nftables..." + if ! apt-get install -y -qq fail2ban nftables; then + print_error "Failed to install Fail2Ban or nftables." return 1 fi fi @@ -4185,7 +4186,7 @@ ignoreip = ${IGNORE_IPS[*]} bantime = 1d findtime = 10m maxretry = 5 -banaction = iptables-ipset-proto6-allports +banaction = nftables-allports [sshd] enabled = true @@ -6173,7 +6174,7 @@ generate_summary() { # Adjust verification commands based on selection if [[ "$IDS_INSTALLED" == "fail2ban" ]]; then printf " %-28s ${CYAN}%s${NC}\n" "- Fail2Ban sshd jail:" "sudo fail2ban-client status sshd" - printf " %-28s ${CYAN}%s${NC}\n" "- IPSet banned IPs:" "sudo ipset list" + printf " %-28s ${CYAN}%s${NC}\n" "- nftables drop counters:" "sudo nft list table inet f2b-table" elif [[ "$IDS_INSTALLED" == "crowdsec" ]]; then printf " %-28s ${CYAN}%s${NC}\n" "- CrowdSec status:" "sudo cscli metrics" printf " %-28s ${CYAN}%s${NC}\n" "- CrowdSec bans:" "sudo cscli decisions list" From 17208be2dbad9820fdcf53ab4e637dc6a42ec84d Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 09:37:34 +0100 Subject: [PATCH 2/8] chore: bump v0.81.3 and update checksum --- README.md | 8 ++++---- du_setup.sh.sha256 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d831075..7260976 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ----- -**Version:** v0.81.2 +**Version:** v0.81.3 -**Last Updated:** 2026-08-08 +**Last Updated:** 2026-08-09 **Compatible With:** @@ -88,12 +88,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`61e57d5dda80143be646ac1777095b4e658a980ab88dfde6756a965eb8af65e9` +`81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo 61e57d5dda80143be646ac1777095b4e658a980ab88dfde6756a965eb8af65e9 du_setup.sh | sha256sum --check +echo 81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2 du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index c78b9a4..c12ecf1 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -61e57d5dda80143be646ac1777095b4e658a980ab88dfde6756a965eb8af65e9 du_setup.sh +81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2 du_setup.sh From 3e8143a8194ea29c1f447e7f2e4222c78b0f927e Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 10:15:52 +0100 Subject: [PATCH 3/8] feat: add nftables-common.local config --- du_setup.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index 78feeca..50f8161 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -4177,6 +4177,16 @@ configure_fail2ban() { failregex = \[UFW BLOCK\] IN=.* OUT=.* SRC= ignoreregex = EOF +) + + local NFTABLES_COMMON_LOCAL + NFTABLES_COMMON_LOCAL=$(cat <<'EOF' +[Init] +# Ensure Fail2Ban silently drops packets +blocktype = drop +# Drop all protocols for a banned IP to mimic UFW's blanket deny +nftables_match = +EOF ) local JAIL_LOCAL_CONFIG @@ -4204,11 +4214,13 @@ EOF local UFW_FILTER_PATH="/etc/fail2ban/filter.d/ufw-probes.conf" local JAIL_LOCAL_PATH="/etc/fail2ban/jail.local" + local NFTABLES_COMMON_PATH="/etc/fail2ban/action.d/nftables-common.local" # --- Idempotency Check --- - if [[ -f "$UFW_FILTER_PATH" && -f "$JAIL_LOCAL_PATH" ]] && \ + if [[ -f "$UFW_FILTER_PATH" && -f "$JAIL_LOCAL_PATH" && -f "$NFTABLES_COMMON_PATH" ]] && \ cmp -s "$UFW_FILTER_PATH" <<<"$UFW_PROBES_CONFIG" && \ - cmp -s "$JAIL_LOCAL_PATH" <<<"$JAIL_LOCAL_CONFIG"; then + cmp -s "$JAIL_LOCAL_PATH" <<<"$JAIL_LOCAL_CONFIG" && \ + cmp -s "$NFTABLES_COMMON_PATH" <<<"$NFTABLES_COMMON_LOCAL"; then print_info "Fail2Ban is already configured correctly. Skipping." log "Fail2Ban configuration is already correct." return 0 @@ -4216,9 +4228,10 @@ EOF # --- Apply Configuration --- print_info "Applying new Fail2Ban configuration..." - mkdir -p /etc/fail2ban/filter.d + mkdir -p /etc/fail2ban/filter.d /etc/fail2ban/action.d echo "$UFW_PROBES_CONFIG" > "$UFW_FILTER_PATH" echo "$JAIL_LOCAL_CONFIG" > "$JAIL_LOCAL_PATH" + echo "$NFTABLES_COMMON_LOCAL" > "$NFTABLES_COMMON_PATH" # --- Ensure the log file exists BEFORE restarting the service --- if [[ ! -f /var/log/ufw.log ]]; then From 269b245f9153cfb3bde6183c0bf31a311349055a Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 10:17:20 +0100 Subject: [PATCH 4/8] chore: update checksum v0.81.3 --- README.md | 4 ++-- du_setup.sh.sha256 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7260976..cb855ee 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2` +`c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo 81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2 du_setup.sh | sha256sum --check +echo c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05 du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index c12ecf1..6b48839 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -81de2f9e435c52bd0c852541456590ea75487273a0fcb4619fac5218e8b738f2 du_setup.sh +c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05 du_setup.sh From 3d71d76d449fb1a3acef57fffaed3d6949cb0136 Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 10:55:26 +0100 Subject: [PATCH 5/8] refactor: update nftables config to use nftables-allports.local --- du_setup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index 50f8161..a5e7466 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -4214,13 +4214,13 @@ EOF local UFW_FILTER_PATH="/etc/fail2ban/filter.d/ufw-probes.conf" local JAIL_LOCAL_PATH="/etc/fail2ban/jail.local" - local NFTABLES_COMMON_PATH="/etc/fail2ban/action.d/nftables-common.local" + local NFTABLES_LOCAL_PATH="/etc/fail2ban/action.d/nftables-allports.local" # --- Idempotency Check --- - if [[ -f "$UFW_FILTER_PATH" && -f "$JAIL_LOCAL_PATH" && -f "$NFTABLES_COMMON_PATH" ]] && \ + if [[ -f "$UFW_FILTER_PATH" && -f "$JAIL_LOCAL_PATH" && -f "$NFTABLES_LOCAL_PATH" ]] && \ cmp -s "$UFW_FILTER_PATH" <<<"$UFW_PROBES_CONFIG" && \ cmp -s "$JAIL_LOCAL_PATH" <<<"$JAIL_LOCAL_CONFIG" && \ - cmp -s "$NFTABLES_COMMON_PATH" <<<"$NFTABLES_COMMON_LOCAL"; then + cmp -s "$NFTABLES_LOCAL_PATH" <<<"$NFTABLES_ALLPORTS_LOCAL"; then print_info "Fail2Ban is already configured correctly. Skipping." log "Fail2Ban configuration is already correct." return 0 @@ -4229,9 +4229,10 @@ EOF # --- Apply Configuration --- print_info "Applying new Fail2Ban configuration..." mkdir -p /etc/fail2ban/filter.d /etc/fail2ban/action.d + rm -f /etc/fail2ban/action.d/nftables-common.local 2>/dev/null || true echo "$UFW_PROBES_CONFIG" > "$UFW_FILTER_PATH" echo "$JAIL_LOCAL_CONFIG" > "$JAIL_LOCAL_PATH" - echo "$NFTABLES_COMMON_LOCAL" > "$NFTABLES_COMMON_PATH" + echo "$NFTABLES_ALLPORTS_LOCAL" > "$NFTABLES_LOCAL_PATH" # --- Ensure the log file exists BEFORE restarting the service --- if [[ ! -f /var/log/ufw.log ]]; then From 5182525d95dede44bcdb1a1abfcac3970685fe3a Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 10:56:13 +0100 Subject: [PATCH 6/8] checksum v0.81.3 --- README.md | 4 ++-- du_setup.sh.sha256 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb855ee..cac07b3 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05` +`20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05 du_setup.sh | sha256sum --check +echo 20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7 du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index 6b48839..4b6f009 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -c93407c2271ea4486e471d3a91bf1faac4238d7e88cd8d329586154ea401dd05 du_setup.sh +20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7 du_setup.sh From 40912fd9070aa3ed41a0d8181e80879ef5c59179 Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 11:21:40 +0100 Subject: [PATCH 7/8] refactor: update nftables jail config --- du_setup.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/du_setup.sh b/du_setup.sh index a5e7466..73f081d 100644 --- a/du_setup.sh +++ b/du_setup.sh @@ -4179,13 +4179,17 @@ ignoreregex = EOF ) - local NFTABLES_COMMON_LOCAL - NFTABLES_COMMON_LOCAL=$(cat <<'EOF' + local NFTABLES_ALLPORTS_LOCAL + NFTABLES_ALLPORTS_LOCAL=$(cat <<'EOF' [Init] # Ensure Fail2Ban silently drops packets blocktype = drop -# Drop all protocols for a banned IP to mimic UFW's blanket deny +# Drop all protocols for a banned IP (older Fail2Ban versions) nftables_match = + +[Definition] +# Drop all protocols for a banned IP (newer Fail2Ban versions) +rule_match-allports = EOF ) From c5b15befe9cc8cdc87907afa3fd4d17e6b7f247f Mon Sep 17 00:00:00 2001 From: buildplan Date: Sun, 9 Aug 2026 11:32:27 +0100 Subject: [PATCH 8/8] checksum v0.81.3 --- README.md | 4 ++-- du_setup.sh.sha256 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cac07b3..4ed9db5 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,12 @@ sha256sum du_setup.sh Compare the output hash to the one below. They must match exactly. -`20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7` +`4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2` Or echo the hash to check, it should output: `du_setup.sh: OK` ```bash -echo 20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7 du_setup.sh | sha256sum --check +echo 4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2 du_setup.sh | sha256sum --check ``` ### 3. Run the Script diff --git a/du_setup.sh.sha256 b/du_setup.sh.sha256 index 4b6f009..351db84 100644 --- a/du_setup.sh.sha256 +++ b/du_setup.sh.sha256 @@ -1 +1 @@ -20531d7a6c784ce2a2dc7f604dedb32839d4027a4b4568793e285cd2a73bc6a7 du_setup.sh +4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2 du_setup.sh