编写shell脚本禁止非法访问的ip

需要提前知道的一些内容

  1. Linux下的/var/log/secure文件记录了登录Linux服务器的日志信息,如果有人尝试破解你的服务器,那么可以在这个文件中看到很多密码错误的信息,如下图

  2. Linux下的/etc/hosts.deny文件可以配置需要禁止访问的ip,外部请求进入时,会先在/etc/hosts.allow中检查ip是否存在,若存在,直接放行请求,如果没有,判断在是否在/etc/hosts.deny中,如果在,禁止请求连接

  3. Linux支持cron定时任务,搭配shell脚本可以让我们定时运行自己编写的脚本,不需要人工进行干预

本机Linux版本为CentOS7

先梳理整个流程

  1. 读取/var/log/secure文件,筛选出试图登录服务器但密码错误的信息
  2. 从每一行信息中分离出对应的外部ip
  3. 对这些ip进行排序和去重,统计每个ip尝试登录的次数
  4. 遍历所有的外部ip,判断当前ip尝试登录次数是否超过忍耐值(可能自己有时候也会输错密码或者其他原因导致登录失败),将该ip添加到/etc/hosts.deny
  5. 使用Linux自带的cron服务创建定时任务,每隔一定的时间就执行该脚本

开始动手

  1. 创建deny_illegal_ip.sh脚本文件

    1
    2
    cd /usr/shell_study
    touch deny_illegal_ip.sh
  2. 创建一个文件来保存非法访问的ip

    1
    touch illegal_ip_list.txt
  3. 创建一个文件来保存cron定时任务执行日志

    1
    touch cron_task.log
  4. 编写脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    IP_LIST_PATH="/usr/shell_study/illegal_ip_list.txt"
    # hosts.deny path
    HOSTS_DENY_PATH="/etc/hosts.deny"
    # hosts.deny backup path
    HOSTS_DENY_BAK_PATH="/etc/hosts.deny.bak"
    # cron task log path
    CRON_TASK_LOG_PATH="/usr/shell_study/cron_task.log"
    # the number of illegal ip
    IP_COUNT=0

    # clean old ip file
    if [ -e $IP_LIST_PATH ]
    then
    cat /dev/null > $IP_LIST_PATH
    fi

    # extract illegal ip
    cat $SECURE_LOG_PATH | grep "Failed password" | awk -F "from" '{print $2}' | awk -F "port" '{print $1}' | sort | uniq -c > $IP_LIST_PATH

    # reset hosts.deny, as we check the ip whether existed in hosts.deny, so this step can be removed
    #if [ -e $HOSTS_DENY_BAK_PATH ]
    #then
    # cat $HOSTS_DENY_BAK_PATH > $HOSTS_DENY_PATH
    #fi

    # add illegal ip to hosts.deny which appears more than once
    while read IP_LINE
    do
    COUNT=`echo $IP_LINE | awk -F " " '{print $1}'`
    IP=`echo $IP_LINE | awk -F " " '{print $2}'`
    if [ $COUNT -ge 2 -a `grep -c $IP $HOSTS_DENY_PATH` -eq 0 ]
    then
    let IP_COUNT++
    echo "sshd:$IP" >> $HOSTS_DENY_PATH
    fi
    done < $IP_LIST_PATH

    # add cron task log
    echo "$(date "+%Y-%m-%d %H:%M:%S"): added $IP_COUNT illegal ip" >> $CRON_TASK_LOG_PATH
  5. 设置定时任务,每天执行一次

    1
    2
    crontab -e
    0 0 * * * /usr/shell_study/deny_illegal_ip.sh
  6. 查看定时任务日志

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    tail -f /usr/shell_study/cron_task.log
    2022-10-24 22:00:01: added 0 illegal ips
    2022-10-24 22:30:01: added 0 illegal ips
    2022-10-24 23:00:01: added 0 illegal ips
    2022-10-24 23:30:01: added 0 illegal ips
    2022-10-25 00:00:01: added 0 illegal ips
    2022-10-25 00:30:01: added 1 illegal ips
    2022-10-25 01:00:02: added 0 illegal ips
    2022-10-25 01:30:01: added 0 illegal ips
    2022-10-25 02:00:01: added 0 illegal ips
    2022-10-25 02:30:01: added 0 illegal ips
    2022-10-25 03:00:01: added 0 illegal ips
  7. 查看ip是否被禁止访问

    1
    vim /etc/hosts.deny