How to respond to a SSH brute force attack on a single VPS?

2 min read Original article ↗

I logged onto my VPS this morning to find millions of failed login attempts for the root user and other users that don't even exist. I took the below measures to try and obfuscate the attackers efforts which (have been going on for months).

Question(s)

  1. Is this an appropriate response?
  2. What more can be done?
  3. Is there anything valuable I can do with a list of these IPs?

System info for a Centos7 vps

uname -a
inux vm01 3.10.0-327.22.2.el7.x86_64 #1 SMP Thu Jun 23 17:05:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

step 1

Created a script to grab all the IP addresses that failed to login from the secure log. (/var/log/secure)

# get_ips.sh
grep "Failed password for" /var/log/secure \
| grep -Po "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" \
| sort \
| uniq -c

step 2

Write a script to create firewall rules to block the ip address that are found from the script in step 1. This script is ip_list_to_rules.sh

#!/bin/bash
# ip_list_to_rules.sh
# script to parse output of get_ips.sh and create firewall rules
# to block ssh requests

if [ -z $1 ]; then
  echo "arg1 must be path to a list of the form <COUNT> <IP>\n"
  exit
fi

LIST=$(readlink -f $1)
SSH_IP=$(echo $SSH_CLIENT | head -n1 | awk '{print $1;}')

echo "Reading IPs from ${LIST}"
echo "SSH Client IP will be ignored (${SSH_IP})"

while read COUNT IP; do

  echo "Creating rule for ${IP}"
  firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -m tcp --source $IP -p tcp --dport 22 -j REJECT
  firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -m tcp --source $IP/24 -p tcp --dport 22 -j REJECT

done<<<"$(cat ${LIST} | grep -v ${SSH_IP})"

step 3

Run it all and save rules.

./get_ips.sh > attack_ips.list
./ip_list_to_rules.sh attack_ips.list
firewall-cmd --reload

Update

Below are the measures I took from the answers.

  1. Disabled root logins
  2. Changed SSH port
  3. Install & configured fail2ban
  4. Disable password authentication & enable public key auth

I didn't actual do 4 because I usually connect through chrome secure shell client and AFAIK there isn't public key support.