VPS hit by brute-force attack

Today I checked the status of my VPS with AI, and the following result came up:

Confirmed: This VPS is undergoing a massive SSH brute-force attack, and the attack intensity is very high.

Check results
SSH log statistics for the past 7 days:
Password failures: 33,880 times
Invalid username events: 7,014 times
The largest attack source, 66.154.112.102, generated about 25,678 related failed events

So I quickly installed Fail2ban to prevent brute-force attacks and block IPs.

Below is a one-click command, which includes an IP whitelist that you’ll need to edit yourself.

My rule is: if an IP fails to log in via SSH more than 10 times within 24 hours, it gets permanently banned.

You can adjust this according to your needs.

Lazy people like me will appreciate this, but I still recommend using key-based authentication and disabling username/password login for higher security.

sudo bash <<'SCRIPT'
set -Eeuo pipefail

# Trusted IP whitelist; separate multiple IPs with spaces
TRUSTED_IPS="Fill in your own IP addresses here; this is the whitelist"

# Fail2ban jail name
JAIL_NAME="sshd-password-permanent"

if [ "$(id -u)" -ne 0 ]; then
    echo "Error: Please run as root or with sudo." >&2
    exit 1
fi

if ! command -v apt-get >/dev/null 2>&1; then
    echo "Error: This script is only for Debian/Ubuntu systems using apt." >&2
    exit 1
fi

if ! command -v systemctl >/dev/null 2>&1 ||
   ! command -v journalctl >/dev/null 2>&1; then
    echo "Error: The system must use systemd and journald." >&2
    exit 1
fi

export DEBIAN_FRONTEND=noninteractive

echo "===== Installing Fail2ban and iptables ====="

apt-get update
apt-get install -y fail2ban iptables

install -d -m 0755 \
    /etc/fail2ban/filter.d \
    /etc/fail2ban/jail.d

echo "===== Disabling the system’s default SSH jail ====="

# Some Debian/Ubuntu systems enable the sshd jail by default,
# but pure journald systems might not have /var/log/auth.log,
# causing Fail2ban to fail to start.
cat > /etc/fail2ban/jail.d/00-disable-default-sshd.local <<'EOF'
[sshd]
enabled = false
EOF

echo "===== Creating a filter for all usernames’ SSH password failures ====="

cat > /etc/fail2ban/filter.d/sshd-password-all-users.conf <<'EOF'
[Definition]
failregex = ^.*sshd(?:\[\d+\])?: Failed password for (?:invalid user )?\S+ from <HOST> port \d+ ssh\d*$
ignoreregex =
EOF

echo "===== Creating the permanent ban jail ====="

cat > /etc/fail2ban/jail.d/sshd-password-permanent.local <<EOF
[${JAIL_NAME}]
enabled = true

filter = sshd-password-all-users
backend = systemd

journalmatch = _SYSTEMD_UNIT=ssh.service + _SYSTEMD_UNIT=sshd.service

port = ssh
protocol = tcp

# 10 failures from the same IP
maxretry = 10

# Check period: 24 hours
findtime = 86400

# Permanent ban
bantime = -1

# Trusted IPs never get banned
ignoreip = 127.0.0.1/8 ::1 ${TRUSTED_IPS}

banaction = iptables-multiport
EOF

echo "===== Checking Fail2ban configuration ====="

fail2ban-client -t

echo "===== Enabling and restarting Fail2ban ====="

systemctl enable fail2ban
systemctl restart fail2ban

sleep 2

echo "===== Verifying Fail2ban service ====="

if ! systemctl is-active --quiet fail2ban; then
    echo "Error: Fail2ban failed to start. Recent logs:" >&2
    journalctl -u fail2ban -n 80 --no-pager >&2
    exit 1
fi

if ! fail2ban-client status "${JAIL_NAME}" >/dev/null 2>&1; then
    echo "Error: Jail ${JAIL_NAME} was not enabled successfully." >&2
    fail2ban-client status >&2 || true
    exit 1
fi

echo
echo "===== Deployment Successful ====="

fail2ban-client status "${JAIL_NAME}"

echo
echo "===== Current Active Parameters ====="

printf 'Max retry count: maxretry = '
fail2ban-client get "${JAIL_NAME}" maxretry

printf 'Check period: findtime = '
fail2ban-client get "${JAIL_NAME}" findtime

printf 'Ban time: bantime = '
fail2ban-client get "${JAIL_NAME}" bantime

echo
echo "Whitelist:"
fail2ban-client get "${JAIL_NAME}" ignoreip

echo
echo "================================================"
echo "Fail2ban deployed successfully"
echo "Monitoring: All usernames’ SSH password failures"
echo "Ban condition: Same IP fails 10 times within 24 hours"
echo "Ban duration: Permanent"
echo "Trusted whitelist: 127.0.0.1/8 ::1 ${TRUSTED_IPS}"
echo "================================================"
SCRIPT
7 Likes

Thank you for sharing your hands-on experience.

1 Like

“Storing things carelessly invites theft, flaunting beauty invites lust.” So, which feature of your VPS attracted them to attack you?

1 Like

This is something beginners can learn from. :ac01:

1 Like

This is standard practice, it doesn’t count as an attack.
Besides, it’s only 30,000 in 7 days. Some days you can get 30,000 in just one day.

I’m already helping you attack the other side.

:xhj45:

:ac32:

Fight violence with violence :xhj003:

It’s only just over 30,000 times—doesn’t that count as normal internet noise?
My home computer’s SSH logs show 100,000 failed login attempts in a single day and that’s perfectly normal. If you have port 22 open, you can’t avoid getting scanned.

If you’re already having AI look things up for you, why bother writing scripts by hand? Just let the AI set everything up for you—it’s much easier. In most cases, a single fail2ban is enough.

Take a moment to learn

1 Like

Not quite sure how to play? :joy:

1 Like

Change to a different port first, don’t use 22.

Why not just set up a whitelist for port 22 so only you can access it?

A single machine only has 65,535 ports, and I’ll just scan all of them for you.

They mainly target major VPS providers—even Cloudflare isn’t spared.

:ac01:

The server was unreachable for two days, so I just reinstalled the operating system.