偶然间在自己的vps机器上查看了一下ssh登录日志,发现有很多不同的ip地址试图登录,类似于

Feb 26 08:49:15 HighBelated-VM sshd[18819]: Failed password for invalid user somkuan from 36.66.203.251 port 49642 ssh2
Feb 26 08:49:16 HighBelated-VM sshd[18819]: Received disconnect from 36.66.203.251 port 49642:11: Bye Bye [preauth]
Feb 26 08:49:16 HighBelated-VM sshd[18819]: Disconnected from 36.66.203.251 port 49642 [preauth]
Feb 26 08:49:52 HighBelated-VM sshd[19043]: Invalid user odoo8 from 206.189.222.38 port 42420
Feb 26 08:49:52 HighBelated-VM sshd[19043]: input_userauth_request: invalid user odoo8 [preauth]
Feb 26 08:49:52 HighBelated-VM sshd[19043]: pam_unix(sshd:auth): check pass; user unknown
Feb 26 08:49:52 HighBelated-VM sshd[19043]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=206.189.222.38

都是一些未知ip,不断尝试用户名和密码来登录以期获取vps所有权,这种操作也会加重vps的处理负担,因此想办法来解决这个问题。

以下有两种方式可以来缓解这种情况:

  • 更换默认ssh端口
    系统默认的ssh端口为22,我们可以修改默认的22端口为其它高位端口号,我通过两个vps,一个默认22,另外一个为随机高位端口做比较,发现22的试图访问记录要更多。

  • 通过分析ssh登录日志,封禁多次试图访问的ip地址
    显然,我们自己登录是知道用户名和密码的,就算偶尔的一两次错误也并不影响。需要注意的是多次尝试登录的ip。因此通过分析ssh日志,对高于一定数量的ssh访问且错误的ip进行封禁。
    下面给出执行脚本:

# --------------------
# 适用于Centos Debian Ubuntu
# 本脚本用于防止暴力破解ssh密码.
# 1. 查找登录IP及对应登录失败的次数
# 2. 分析,如果登录次数大于3次,认为是非法登录,封禁该IP
# Author : tkmiss
# Copyright (c) tkmiss.com
# Email: mailbox.scmy@gmail.com
# --------------------

#!/bin/bash

LIMIT_CNT=3

LOG_FILE_PATH="/var/log/secure"
TMP_BLOCK_FILE="/var/tmp/black.txt"
OS_RELEASE="/etc/os-release"

security_execution()
{
    echo "start security_execution"

    cat $LOG_FILE_PATH | awk '/Failed/{print $(NF-3)}' | sort | uniq -c | awk '{print $2"="$1;}' > $TMP_BLOCK_FILE

    for i in `cat  $TMP_BLOCK_FILE`
    do
      IP=`echo $i | awk -F '=' '{print $1}'`
      NUM=`echo $i | awk -F '=' '{print $2}'`

      if [ $NUM -gt $LIMIT_CNT ];then
          grep $IP /etc/hosts.deny > /dev/null
        if [ $? -gt 0 ];then
            echo "block ip: $IP"
            echo "sshd:$IP:deny" >> /etc/hosts.deny
        fi
      fi
    done

    echo "Completed"
}

proc_main()
{
    if [ -f "$OS_RELEASE" ]; then
        source /etc/os-release
        case $ID in
            debian|ubuntu|devuan)
                LOG_FILE_PATH="/var/log/auth.log"
                ;;
            centos|fedora|rhel)
                LOG_FILE_PATH="/var/log/secure"
                ;;
            *)
                exit 1
                ;;
        esac
        echo "System $ID $VERSION_ID"
        security_execution
    fi
}

proc_main

创建定时计划
我们不可能随时登录到vps去手动执行脚本,那么就要依靠linux自带的定时计划crontab来定时执行了。
下面是我使用的计划,每5分钟执行一次,脚本的位置自定义。

crontab -e
*/5 * * * *  /root/secure_ssh.sh
最后修改:2019 年 05 月 06 日 11 : 35 AM