shell脚本实现自动封IP和解IP

这篇具有很好参考价值的文章主要介绍了shell脚本实现自动封IP和解IP。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

当项目正式上线后,如果有人恶意多次请求网站地址,对网站发起攻击,则会使服务器或者后端服务宕机,因此写一个shell脚本,实现一段时间内的请求访问判断,结合iptables规则对请求的源IP地址进行封操作和解封操作。


提示:以下是本篇文章正文内容,下面案例可供参考

一、背景

本案例是这样的:

1)每分钟分析一次访问日志/export/Logs/access_log,日志片段如下:

180.98.113.151 - [19/Sep/2018:09:30:07 +0800]  "/uc_server/avatar.php?uid=1145811&size=middle" 301 "GET  HTTP/1.1" "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13D15 MAGAPPX|4.1.2-4.1.0-41|iPhone OS 9.2.1 iPhone 6|wenyou|C6C25422-279C-4337-8E10-F588D577B9D7|da97ede5be797f79b96d6761bf858632|426ef86c3fc2359dc90468f7bdd0f5e9|c64f2225ec641231cd612bbe08f2b40d" 
61.227.224.229 - [19/Sep/2018:09:30:07 +0800]  "/misc.php?mod=ranklist&type=member&view=post" 200 "GET  HTTP/1.1" "http://www.wenyou.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0" 
183.207.95.145  [19/Sep/2018:09:30:07 +0800]  "/uc_server/avatar.php?uid=1323875&size=middle" 301 "GET  HTTP/1.1" "http://app.yikaidai.com/mag/circle/v1/forum/threadViewPage?tid=3446714&circle_id=&themecolor=1aadfa" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0_3 like Mac OS X) AppleWebKit/604.1.38 "
114.230.251.50 - [19/Sep/2018:09:30:07 +0800]  "/core/attachment/attachment/img?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg" 302 "GET HTTP/1.1" "https://app.yikai.com/mag/info/v1/info/infoView?id=55855&themecolor=1aadfa" "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) "
61.227.224.229 - [19/Sep/2018:09:30:07 +0800]  "/misc.php?mod=ranklist&type=member&view=onlinetime" 200 "GET HTTP/1.1" "http://www.wenyou.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0" 

2)把访问量高于100的IP给封掉
3)封过的IP都要记录到一个日志中
4)每隔30分钟检查一次被封的IP,把没有访问量或者访问量很少的IP解封
5)解封的IP记录到另外一个日志中

二、使用步骤

在编写这个脚本前先学习一下三剑客命令的使用操作

1.awk用法

1.1、在shell脚本中,awk出现概率是极高的,因为它在处理字符串上有很强的能力。先来看一个小例子:

# awk -F ':' '$3>500 {print $1,$3}' /etc/passwd
systemd-bus-proxy 999
polkitd 998
chrony 997
user1 1000

说明:awk最核心的功能是分段,可以用-F选项指定一个分隔符,然后针对某一段字符进行处理,本例中用’:'作为分隔符,去找第3段大于500的行,然后把第1段和第3段打印出来。在awk中可以使用>, <, >=, <=, ==, !=等逻辑判断的符号,这和shell是有差异的。本例中>后面的500一定不要加双引号,否则它就不以数字作为比较对象了,而是把500当成是字符串,结果自然就不一样了。如下:

# awk -F ':' '$3>"500" {print $1,$3}' /etc/passwd
shutdown 6
halt 7
mail 8
nobody 99
systemd-bus-proxy 999
dbus 81
polkitd 998
tss 59
postfix 89
sshd 74
chrony 997

awk的功能不止于此,它实际上跟shell一样属于一门脚本语言,可以写脚本。它的作者设计它的初衷是为了去格式化输出文本,它可以满足各种复杂的格式需求,不过我们平时写shell脚本时,仅仅把它作为一个命令来处理字符串,下面我列几个常见的用法(以下所有演示文件都使用1.txt)。

1)截取指定段
# awk -F ':|#' '{print $2}' 1.txt
说明:分隔符可以是一个正则表达式,本例中的分隔符可以是':'也可以是'#'
2)匹配字符后字符串
# awk -F ':' '$1 ~ "abc"' 1.txt
说明:过滤出第一段包含abc的行,其中这里的abc可以是一个正则表达式,例如:
# awk -F ':' '$1 ~ "^ro+"' 1.txt
说明:^表示开头,+表示+前面的字符至少有1个,所以"^ro+"可以匹配的字符串有:ro, roo, rooo...
3)多个语句同时使用
# awk -F ':' '$1 ~ "root" {print $1,$3}; $3>100 {print $1,$2}' 1.txt
4)多个条件
# awk '$3<100 && $7 ~ "bash" {print $0}'  1.txt
说明:如果不指定分隔符,则以空白字符作为分割符,在awk中可以用&&表示并且,用||表示或者。$0会输出整行。
5)内置变量
# awk -F ':' '{print NF,NR}' 1.txt
说明:NF为段数,NR为行数

2.sort排序

语法: sort [-t 分隔符] [-kn1,n2] [-nru] 这里的n1 < n2
-t 分隔符 :作用跟cut的-d一个意思
-n :使用纯数字排序
-r :反向排序
-u :去重复
-kn1,n2 :由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序

如果sort不加任何选项,则从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出,如下:

# head -n5 /etc/passwd |sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
root:x:0:0:root:/root:/bin/bash

-t 后面跟分隔符,-k后面跟数字,表示对第几个区域的字符串排序,-n 则表示使用纯数字排序,示例如下:

# head -n5 /etc/passwd |sort -t: -k3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

-k3,5 表示从第3到第5区域间的字符串排序,-r表示反向排序,示例如下:

# head -n5 /etc/passwd |sort -t: -k3,5 -r
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
root:x:0:0:root:/root:/bin/bash

3.uniq去重复

这个命令我经常用的选项只有一个,-c :统计重复的行数,并把行数写在前面
请把下面的内容写入testb.txt, 保存。
111
222
111
333

使用uniq 的前提是需要先给文件排序,否则不管用,如下所示:

# uniq testb.txt
111
222
111
333
# sort testb.txt |uniq
111
222
333

以下是-c选项的作用:

# sort testb.txt |uniq -c
      2 111
      1 222
      1 333

4.用iptables工具封/解封IP

在CentOS系统中有一个叫做netfilter的防火墙,它可以对进入或者即将离开网卡的数据包进行处理。最常见的用法就封IP,即限制某些IP或者某些IP的某个port的数据包进入Linux系统。很多人把iptables叫做防火墙,其实不然,iptables是CentOS6系统里的一个服务,当然它也是一个命令,而在CentOS7系统里也有iptables命令,服务名不再是iptables,而是firewalld。

1)查看filter表的iptables规则

# iptables -nvL -t filter
说明:在CentOS7上netfilter有5个表,分别是:filter、nat、mangle、raw、secuirty。而我们用的比较多的是前两个,本案例中的封ip用的就是filter表。该命令中的-t filter可以省略,默认就是filter表。

2)增加规则

# iptables -A INPUT -p tcp --dport 80 -s 1.1.1.1 -j DROP
说明: -A表示增加规则,INPUT为filter表里的一个链,除此之外,filter表还有OUTPUT链和FORWARD链。这里我引用网上的一张图片帮助大家理解netfilter的表和链。

shell脚本实现自动封IP和解IP,shell,运维,安全

数据包的流向是这样的:
	a. 当一个数据进入网卡时,他首先进入PREOUTING链(数据包进入路由之前),然后判断目标IP是否本机。
	b. 如果数据包是进入本机的,他会到达INPUT链(通过路由表后目的地为本机),数据包到达INPUT链后进入本机内核,然后内核进行处理,处理完到OUTPUT链(由本机产生,向外转变),最后到POSTROUTING(发送到网卡接口之前)。
	c. 如果不是进入本机的,他会到FORWARDING链(通过路由表后,目的地不为本机)最后POSTROUTING链(发送到网卡接口之前)。

-A选项是增加一条规则,更准确地说是追加一条规则,因为iptables的规则是分前后的,用iptables -nvL查看规则时,越靠上的规则就越先生效,也就是说优先级越高。所以,使用-A追加的规则只能排在最后面,但如果想增加一条优先级最高的规则怎么办?用-I选项(插入规则的意思)即可,示例命令如下

	# iptables -I INPUT -p tcp --dport 80 -s 2.2.2.2 -j DROP

也可以不针对端口,只写IP,同时也可以指定目标IP地址,如下

# iptables -I INPUT -s 3.3.3.3 -d 4.4.4.4 -j DROP

删除规则有两个方法,一是全部清空,另外一个就是删除一条

# iptables -t filter -F

删除一条规则,比较麻烦,因为你需要记得当时创建这条规则的命令,把-I或者-A换成-D即可,如下

# iptables -D INPUT -s 3.3.3.3 -d 4.4.4.4 -j DROP

5.shell脚本中的函数

在shell脚本中如果某一段代码出现1次以上,应该把这段代码封装到一个函数里,这样后续调用它会很方便,而且代码看起来也非常美观。下面我用一个实际的例子来说明函数的好处。

需求是,检查系统中是否安装vim-enhanced、expect、wget包,如果没有安装则安装一下,传统的shell代码是这样写的:

if ! rpm -q vim-enhanced &>/dev/null
then 
    yum install -y vim-enhanced
fi

if ! rpm -q expect &>/dev/null
then
    yum install -y expect
fi

if ! rpm -q wget &>/dev/null
then
    yum install -y wget
fi

试问,如果让你去检查100个包,难道你要写100遍这段代码吗?用函数就简洁多了,如下

## 定义if_install函数
if_install() {
  if ! rpm -q $1 &>/dev/null
    then
        yum install -y $1
    fi
}

## 用for循环把所有rpm包逐一检查一遍
for pkg in vim-enhanced expect wget
do
    if_install $pkg
done

6.sed用法

sed和grep、awk一样频繁地出现在shell脚本中,它们三个经常被叫做“正则三剑客”,可见这三个工具和正则表达式之间的关系非同一般。对于sed工具的用法,我列几个常见的

1)打印指定行

sed -n '10p' 1.txt

说明:10指的是行号,p表示print(打印),加上-n后只显示第10行,否则会把1.txt所有行都显示出来,这里的单引号是我的习惯,你可以不加也可以加双引号。另外,可以指定多行,示例命令如下:

sed -n '1,5p' 1.txt

说明:打印1到5行,如果是不连续的行,可以这样

sed -n '1p;5p' 1.txt

sed也有和grep类似的过滤指定行的功能,如下

sed -n '/abc/p' 1.txt

说明://为一个固定写法,里面就是要匹配的字符串,可以是正则,例如

sed -n '/[a-z0-9]/p' 1.txt

在正则表达式中,有几个特殊符号属于扩展正则范畴,它们是+, ?, |, (), {}。在grep中要使用它们需要加上-E选项,而在sed中要使用它们,需要加上-r选项,比如

sed -nr '/abc|123/p' 1.txt

2)删除指定行

sed '10d' 1.txt

说明:会删除第10行,但并不会真正操作1.txt内容,而是屏幕上显示的内容少了第10行,要想直接在文件内生效,可以加上-i选项,如下

sed -i '10d' 1.txt

删除包含’abc’或者’linux’字符串的行

sed -ir '/abc|linux/d' 1.txt

3)查找替换

把1.txt中的出现的全部’aming’替换为’linux’

sed 's/aming/linux/g' 1.txt

说明:这里的s表示替换,g表示全局替换,如果不加g则只替换每行中出现的第一个’aming’。文章来源地址https://www.toymoban.com/news/detail-771346.html


7.参考脚本

#! /bin/bash
## 把访问量比较大的IP封掉,如果20分钟内被封的IP没有请求或者请求很少,需要解封

#定义1分钟以前的时间,用于过滤1分钟以前的日志
t1=`date -d "-1 min" +%Y:%H:%M`
log=/data/logs/access_log

block_ip()
{
    egrep "$t1:[0-5]+" $log > /tmp/tmp_last_min.log

    #把1分钟内访问量高于100的ip记录到一个临时文件中
    awk '{print $1}' /tmp/tmp_last_min.log |sort -n |uniq -c|sort -n |awk '$1>100 {print $2}' > /tmp/bad_ip.list

    #计算ip的数量
    n=`wc -l /tmp/bad_ip.list|awk '{print $1}'`

    #当ip数大于0时,才会用iptables封掉它
    if [ $n -ne 0 ]
    then
        for ip in `cat /tmp/bad_ip.list`
        do
            iptables -I INPUT -s $ip -j REJECT
        done
        #将这些被封的IP记录到日志里
        echo "`date` 封掉的IP有:" >> /tmp/block_ip.log
        cat /tmp/bad_ip.list >> /tmp/block_ip.log
    fi
}

unblock_ip()
{
    #首先将包个数小于5的ip记录到一个临时文件里,把它们标记为白名单IP
    iptables -nvL INPUT|sed '1d' |awk '$1<5 {print $8}' > /tmp/good_ip.list
    n=`wc -l /tmp/good_ip.list|awk '{print $1}'`
    if [ $n -ne 0 ]
    then
        for ip in `cat /tmp/good_ip.list`
        do
            iptables -D INPUT -s $ip -j REJECT
        done
        echo "`date` 解封的IP有:" >> /tmp/unblock_ip.log
        cat /tmp/good_ip.list >> /tmp/unblock_ip.log
    fi
    #当解封完白名单IP后,将计数器清零,进入下一个计数周期
    iptables -Z
}

#取当前时间的分钟数
t=`date +%M`

#当分钟数为00或者30时(即每隔30分钟),执行解封IP的函数,其他时间只执行封IP的函数
if [ $t == "00" ] || [ $t == "30" ]
then
   unblock_ip
   block_ip
else
   block_ip
fi

到了这里,关于shell脚本实现自动封IP和解IP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • shell脚本练习--安全封堵脚本,使用firewalld实现

      安全封堵(security hardening)是指采取一系列措施来增强系统的安全性,防止潜在的攻击和漏洞利用。以下是一些常见的安全封堵措施: 更新和修补系统:定期更新操作系统和软件包以获取最新的安全补丁和修复程序。 配置防火墙:使用防火墙软件(如iptables或firewalld)来限

    2024年02月14日
    浏览(31)
  • 云计算的自动化与脚本:实现高效运维

    云计算是一种基于互联网和服务器集群的计算模式,它允许用户在需要时从任何地方访问计算资源。自动化和脚本在云计算中发挥着至关重要的作用,因为它们可以帮助管理员更高效地运行和维护云计算环境。在本文中,我们将探讨云计算自动化和脚本的核心概念、算法原理

    2024年04月12日
    浏览(36)
  • Liunx shell编程及自动化运维实现--第五章三剑客

    正则表达式(RE)是一种字符模式,用于再查找过程中匹配指定的字符,在大多数程序中,正则表达式都被置于两个正斜杠之间:例如//就是由正斜杠界定的正则表达式,他将匹配被查找的行中任何位置出现的相同模式。在正则表达式中,元字符时最重要的概念。 定义:元字

    2024年02月21日
    浏览(24)
  • 运维Shell脚本小试牛刀(二)

    运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0); pwd)命令详解 [root@www shelldic]# cat checkpass.sh  #!/bin/bash - #================================================================================================================== # # #                          

    2024年02月10日
    浏览(25)
  • 运维Shell脚本小试牛刀(一)

    运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0); pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 Cenos7安装小火车程序动画 运维Shell脚本小试牛刀(五):until循环 运维Shell脚本小试牛刀

    2024年02月11日
    浏览(31)
  • Shell 脚本实现自动启动程序、日志管理和定时任务监控

    本篇将通过Shell 脚本实现自动启动Java程序、日志管理和定时任务监控。脚本启动程序具灵活定制、可移植性和扩展性强的优点,可以根据需要添加额外的功能、配置选项和自定义行为,从而满足更具体的要求。 确保将脚本中的/path/to/log和your_program_port等替换为实际的日志路径

    2024年01月21日
    浏览(34)
  • 运维高级--shell脚本完成分库分表

         随着系统的运行,存储的数据量会越来越大,系统的访问的压力也会随之增大,如果一个库中的表数据超过了一定的数量,比如说MySQL中的表数据达到千万级别,就需要考虑进行分库分表;      其次随着表数据的不断增大,会发现查询也随着变得缓慢,如果添加索

    2024年02月15日
    浏览(35)
  • 运维:18工作中常用 Shell 脚本, 强烈推荐

      1、检测两台服务器指定目录下的文件一致性

    2024年02月14日
    浏览(28)
  • 简单的Shell脚本实现自动化构建部署-适合前后端分离的小网站

    大家在生活中经常会自己写一点小代码。然后部署在公有云的服务器上。但是一般像阿里,腾讯等服务商,提供的机器内存并不是很大。如果想装入一个jenkins之类的服务,会比较占用CPU和内存的资源。但是人手的部署又是比较麻烦的。所以我这里提供了一个思路,使用shell脚

    2023年04月16日
    浏览(57)
  • 【运维工程师学习三】Linux中Shell脚本编写

    Shell程序有很多, 如 Korn shell(ksh)、Bourne Again shell(bash)、C shell(包括csh与tcsh) 等等, 各主要操作系统下缺省的shell: AIX下是 Korn Shell Solaris缺省的是 Bourne shell FreeBSD缺省的是 C shell HP-UX缺省的是 POSIX shell Linux缺省的是 Bourne Again shell 但这种在命令行中的命令是即时输出结果的,不

    2024年02月11日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包