Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

-----

**Version:** v0.81.3
**Version:** v0.81.4

**Last Updated:** 2026-08-09
**Last Updated:** 2026-08-12

**Compatible With:**

Expand Down Expand Up @@ -88,12 +88,12 @@

Compare the output hash to the one below. They must match exactly.

`4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2`
`87b55982d3eb81ac94fe3bb41749b55af08680a0920d2053bd7bbd08ce232313`

Or echo the hash to check, it should output: `du_setup.sh: OK`

```bash
echo 4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2 du_setup.sh | sha256sum --check
echo 87b55982d3eb81ac94fe3bb41749b55af08680a0920d2053bd7bbd08ce232313 du_setup.sh | sha256sum --check
Comment thread
buildplan marked this conversation as resolved.
Dismissed
```

### 3. Run the Script
Expand Down
33 changes: 22 additions & 11 deletions du_setup.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/bin/bash

# Debian and Ubuntu Server Hardening Interactive Script
# Version: 0.81.3 | 2026-08-09
# Version: 0.81.4 | 2026-08-12
# Changelog:
# - v0.81.4: Fix silent script abort on IPv6-only servers, improve local IP detection and IPv6 route fallbacks.
# Safely handle immutable/locked /etc/resolv.conf files (common on VPS providers) to prevent aborts during Secure DNS setup.
# - 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.
Expand Down Expand Up @@ -120,7 +122,7 @@
set -euo pipefail

# --- Update Configuration ---
CURRENT_VERSION="0.81.1"
CURRENT_VERSION="0.81.4"
SCRIPT_URL="https://raw.githubusercontent.com/buildplan/du_setup/refs/heads/main/du_setup.sh"
CHECKSUM_URL="${SCRIPT_URL}.sha256"

Expand Down Expand Up @@ -284,7 +286,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.3 | 2026-08-09 ║${NC}"
printf '%s\n' "${CYAN}║ v0.81.4 | 2026-08-12 ║${NC}"
printf '%s\n' "${CYAN}║ ║${NC}"
printf '%s\n' "${CYAN}╚═════════════════════════════════════════════════════════════════╝${NC}"
printf '\n'
Expand Down Expand Up @@ -1485,13 +1487,13 @@ sysinfo() {
public_ipv4=$(curl -4 -sf -m 2 --connect-timeout 1 https://ip.wiredalter.com 2>/dev/null || \
curl -4 -sf -m 2 --connect-timeout 1 https://checkip.amazonaws.com 2>/dev/null || \
curl -4 -sf -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
curl -4 -sf -m 2 --connect-timeout 1 https://api.ipify.org 2>/dev/null)
curl -4 -sf -m 2 --connect-timeout 1 https://api.ipify.org 2>/dev/null || true)
# If no IPv4, try IPv6
if [ -z "$public_ipv4" ]; then
public_ipv6=$(curl -6 -sf -m 2 --connect-timeout 1 https://ip.wiredalter.com 2>/dev/null || \
curl -6 -sf -m 2 --connect-timeout 1 https://ipconfig.io 2>/dev/null || \
curl -6 -sf -m 2 --connect-timeout 1 https://icanhazip.co 2>/dev/null || \
curl -6 -sf -m 2 --connect-timeout 1 https://api64.ipify.org 2>/dev/null)
curl -6 -sf -m 2 --connect-timeout 1 https://api64.ipify.org 2>/dev/null || true)
fi
# Get local/internal IP as fallback
for iface in eth0 ens3 enp0s3 enp0s6 wlan0 ens33 eno1; do
Expand Down Expand Up @@ -2912,7 +2914,7 @@ collect_config() {
# 1. Get the Local LAN IP (Explicit Check)
# This prevents crashing on IPv6-only servers
if ip -4 route get 8.8.8.8 >/dev/null 2>&1; then
LOCAL_IP_V4=$(ip -4 route get 8.8.8.8 | head -1 | awk '{print $7}')
LOCAL_IP_V4=$(ip -4 route get 8.8.8.8 | head -1 | awk -F'src ' '{print $2}' | awk '{print $1}')
else
LOCAL_IP_V4=""
fi
Expand Down Expand Up @@ -3365,12 +3367,12 @@ show_connection_options() {

local TS_IP=""
if command -v tailscale >/dev/null 2>&1 && tailscale ip >/dev/null 2>&1; then
TS_IP=$(tailscale ip -4 2>/dev/null)
TS_IP=$(tailscale ip -4 2>/dev/null || true)
fi

local NB_IP=""
if command -v netbird >/dev/null 2>&1 && netbird status 2>/dev/null | grep -q "Connected"; then
NB_IP=$(ip -4 addr show wt0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -1)
NB_IP=$(ip -4 addr show wt0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -1 || true)
fi

printf "\n"
Expand All @@ -3393,7 +3395,10 @@ show_connection_options() {
# show the detected local IP from route (Home VM scenario)
if [[ "$found_internal" == false && "$public_ip" == "Unknown" ]]; then
local fallback_ip
fallback_ip=$(ip -4 route get 8.8.8.8 2>/dev/null | head -1 | awk '{print $7}')
fallback_ip=$(ip -4 route get 8.8.8.8 2>/dev/null | head -1 | awk -F'src ' '{print $2}' | awk '{print $1}' || true)
if [[ -z "$fallback_ip" ]]; then
fallback_ip=$(ip -6 route get 2001:4860:4860::8888 2>/dev/null | head -1 | awk -F'src ' '{print $2}' | awk '{print $1}' || true)
fi
if [[ -n "$fallback_ip" ]]; then
printf " %-20s ${CYAN}ssh -p %s %s@%s${NC}\n" "Local (LAN):" "$port" "$USERNAME" "$fallback_ip"
fi
Expand Down Expand Up @@ -4494,8 +4499,14 @@ SECURE_DNS_CONFIG
# Ensure the OS is actually pointing to systemd-resolved for DNS queries
if [[ ! -L /etc/resolv.conf ]] || [[ "$(readlink /etc/resolv.conf)" != "../run/systemd/resolve/stub-resolv.conf" && "$(readlink /etc/resolv.conf)" != "/run/systemd/resolve/stub-resolv.conf" ]]; then
print_info "Symlinking /etc/resolv.conf to the secure stub resolver..."
rm -f /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# Attempt to unlock the file if it's protected (common on VPS providers)
chattr -i /etc/resolv.conf 2>/dev/null || true

if rm -f /etc/resolv.conf 2>/dev/null; then
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf || true
else
print_warning "Could not modify /etc/resolv.conf (locked by provider). Secure DNS may not apply locally."
fi
fi

print_success "Secure DNS configured and activated."
Expand Down
2 changes: 1 addition & 1 deletion du_setup.sh.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4ff3b33b35e69e47512362c8c45d69c5c17ba96f3d3c28250d47f9965f4436b2 du_setup.sh
87b55982d3eb81ac94fe3bb41749b55af08680a0920d2053bd7bbd08ce232313 du_setup.sh
Loading