脚本开发之Python检测和防御DOS攻击

admin 2026-02-02 00:01:59 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档介绍在CentOS下利用Python开发DOS攻击检测与防御脚本。文章详解uptime、netstat等命令,通过调用系统接口监控CPU负载、TCP连接数及队列情况来识别异常流量。防御策略上,脚本统计高频连接IP并利用防火墙指令自动封禁。该方案适合初学者掌握自动化安全运维的基础逻辑。 综合评分: 87 文章分类: 安全开发,应急响应,网络安全,安全运营


cover_image

脚本开发之Python检测和防御DOS攻击

原创

secureyang secureyang

secureyang

2026年2月1日 18:07 北京

Python检测和防御DOS攻击一、在CentOS上安装Python3二、理解各个命令的含义1、uptime2、netstat3、ss4、firewall-cmd5、sysctl三、利用python实现DOS入侵检测采集TCP连接数据采集跟DOS攻击关联度较高的数据 uptimenetstat -ant 连接数量ss -lnt  读取队列情况主调函数四、利用IP查询实现DOS防御对连接数量超标的ip地址进行封禁主调函数

只是一个比较简单的思路,功能如若想添加,可持续进行优化,当然,此文更偏向于网络安全新人学习。

Python检测和防御DOS攻击

利用Python编程实现对wrk的泛洪攻击检测,并让程序触发调用Linux命令实现防御:

1、泛洪攻击的检测,可以考虑使用的命令,这些命令可以通过Pytho调用和分析。

  • netstat -ant | wc -l
  • netstat -ant | grep SYN_RECV
  • netstat -s | grep overflowed
  • netstat -s | grep dropped
  • top -n 获取CPU使用率

以上操作过程的命令,允许使用管道和AWK提取数据,也可以直接使用Python进行数据提取

2、防御措施可以选择一下几种:

  • 修改系统配置参数,来增强系统的TCP连接数
  • 直接结束某些消耗CPU的进程,或者停止Apache的服务(不得已而为之)
  • 开启防火墙,将目标IP地址进行封锁(首选)
  • 自行查阅资料,进行其他可以执行的操作
  • 上述Python代码实现的狠心就是调用系统指令,再通过Python 进行分析,触发命令的执行等。建议在Linux上安装Pyotn3.x及以上的版本

基本步骤:

1、确保在Linux上可以正常运行Python3.x,而Centos内置的是python2.7版本

2、做基本的调研,明确对于DOS的入侵检测,需要使用那些方法或命令

3、将可以使用的命令通过Python来运行,并进行调试,确保 Python+命令 可以正常运行

4、想办法找到连接数最多的攻击源IP地址,驱动Linux的防火墙进行入侵防御

5、最后进行整合,测试,再模拟攻击,确保脚本可以正常检测

一、在CentOS上安装Python3

下载地址:Python 版本 Python 3.10.14 |Python.org

安装教程:

CentOS 7 安装 Python 3.10_yum python3.10-CSDN博客

服务器Centos7部署安装Python3的完整过程(3.10.1) – 知乎 (zhihu.com)

 cd ~

 sudo yum -y update

 sudo yum -y install openssl-devel libffi-devel bzip2-devel

 sudo yum -y groupinstall "Development Tools"

 wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz --no-check-certificate

 tar zxf openssl-1.1.1q.tar.gz

 cd openssl-1.1.1q

 ./config --prefix=/usr/local/openssl-1.1.1

 sudo make && sudo make install

 mkdir /usr/local/python3

 wget https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz

 tar zxf Python-3.10.5.tgz

 cd Python-3.10.5

 ./configure --enable-optimizations --with-openssl=/usr/local/openssl-1.1.1 --with-openssl-rpath=auto --prefix=/usr/local/python3

 sudo make altinstall

 #make

 #make install

 # 配置环境变量

 vi ~/.bash_profile

 export PYTHON_HOME=/usr/local/python3

 PATH=$PATH:$HOME/bin:$PYTHON_HOME/bin

 export PATH

 退出编辑
 source ~/.bash_profile

二、理解各个命令的含义

1、uptime

uptime 命令用户查看主机的开机时长,用户连接数量,以及在 1、5、15分钟 三个时间段内,CPU的负载情况

每周一个linux命令之—uptime详解 – vinter_he – 博客园 (cnblogs.com)

2、netstat

netstat 命令用来打印Linux中网络系统的状态信息,可让你得知整个Linux操作系统的网络情况,需要注意的是在windows和Linux上的参数会略有不同。

 -a或--all 显示所有连线中的Socket
 -n或--numeric 直接使用IP地址,而不通过域名服务器。意思就是以数字的形式代替服务
 -l或--listening 显示监控中的服务器的Socket。
 -t或--tcp 显示TCP传输协议的连线状况
 -u或--udp 显示UDP传输协议的连线状况。
 -s或--statistics 显示网络工作信息统计表
 -r或--route 显示Routing Table。
 -p或--programs 显示正在使用Socket的程序识别码和程序名称。

 以数字方式列出所有TCP连接情况: netstat -ant
 以数字方式列出所有UDP连接情况: netstat -anu
 以数字方式列出所有TCP和UDP处理监听状态的情况: netstat -anult
 显示所有端口的统计信息: netstat-s
 显示TCP端口的统计信息: netstat-st
 显示核心路由信息: netstat -r
 显示所有连接的进程信息: netstat -ap

Linux netstat命令 |菜鸟教程 (runoob.com)

3、ss

ss 用来显示处于活动状态的套接字信息。他可以显示和netstat类似的内容,但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速高效。

 显示监听状态下的队列情况: ss -lnt
 显示非监听状态下的连接详情: ss -nt
 显示socket摘要信息: ss -s  注意其结果的IPv6的变化

LISTEN 状态: Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值,也就是说,当客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端accept() ; Send-Q 表示的则是最大的 listen backlog 数值,这就就是上面提到的 min(backlog,somaxconn)的值

非 LISTEN 状态: Recv-Q 表示 receive queue 中的 bytes 数量;Send-Q 表示 send queue 中的 bytes 数值该数值意义不大,更多关注连接的数量和状态即可

4、firewall-cmd

 关闭防火墙:systemctl stop firewalld

 添加允许端口:firewall-cmd --add-port=80/tcp

 列出防火墙规则:firewall-cmd --list-all

 禁止IP地址访问80端口:firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.112.148" port port="80" protocol="tcp" reject'

 让配置永久生效:添加允许端口:firewall-cmd --add-port=80/tcp --permanent

 允许http服务通过1分钟:firewall-cmd --zone=public --add-service=http --timeout=1m,这个 timeout 选项是一个以秒(s)、分(m)或小时(h)为单位的时间值。

5、sysctl

sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下。sysctl配置与显示在/proc/sys目录中的内核参数,可以用sysctl来设置或重新设置联网功能,如IP转发、IP碎片去除以及源路由检查等。用户只需要编辑/etc/sysctl.con文件,即可手工或自动执行由sysctl控制的功能。

 显示所有系统参数:sysctl -a

 使用cat查看指定参数:cat /proc/sys/net/ipv4/ip_forward,除/proc/sys外,后面的路径与参数名称一致换成 / 即可

 临时改变某个指定参数的值,如:sysctl -w net.ipv4.ip forward=1,也可以:echo 1 > /proc/sys/netipv4/ip forward

 如果想永久保留配置,可以修改/etc/sysctl.con文件

快速修改部分参数,优化性能:

 net/ipv4/tcp_syn_cookies   是否打开SYN COOKIES的功能,"1”为打开,“2”关闭。

 net/ipv4/tcp_max_syn_backlogSYN队列的长度,加大队列长度可以容纳更多等待连接的网络连接数。

 net/ipv4/tcp_synack_retries和net/ipv4/tcp_syn_retries定义SYN重试次数,默认为5,建议为2

 net/ipv4/sack=0

其他参数的说明:https://www.cnblogs.com/feiyun126/p/8646989.html

一些优化方案:https://blog.csdn.net/wangshuminjava/article/details/80935792

三、利用python实现DOS入侵检测

采集TCP连接数据

采集跟DOS攻击关联度较高的数据

uptime
  • > 19:51:11 up 5 days,  8:40,  3 users,  load average: 0.00, 0.02, 0.05  ->  [‘ 19:51:11 up 5 days’, ‘  8:40’, ‘  3 users’, ‘  load average: 0.00’, ‘ 0.02’, ‘ 0.05\n’]  ->    load average: 0.00  ->  [”, ”, ‘load’, ‘average:’, ‘0.00’]  ->  0.00
 importos,time

 # 可采用 split和awk进行修改得到前1分钟的CPU平均负载
 importtime,os

 defget_cpu_01():
     uptime=os.popen('uptime').read()
     #print(type(uptime))
     #print(uptime)
     cpu_load=float(uptime.split(',')[3].split(' ')[4])
     #print(cpu_load)
     returncpu_load
  • > 20:07:30 up 5 days,  8:56,  3 users,  load average: 0.00, 0.01, 0.05  –>>   20:07:30 up 5 days,  8:56,  3 users,  load average,0.00, 0.01, 0.05  –>> [‘ 20:07:48 up 5 days’, ‘  8:56’, ‘  3 users’, ‘  load average’, ‘0.00’, ‘ 0.01’, ‘ 0.05\n’]  –>>  0.00
 defget_cpu_02():
     uptime=os.popen('uptime').read()
     #print(type(uptime))
     #print(uptime)
     cpu_load=float(uptime.replace(': ',',').split(',')[4])
     #print(cpu_load)
     returncpu_load
  • > 20:16:56 up 5 days,  9:05,  3 users,  load average: 0.00, 0.01, 0.05  –>>  0.00, 0.01, 0.05  –>>  0.00
 defget_cpu_03():
     uptime=os.popen('uptime').read()
     #print(type(uptime))
     #print(uptime)
     cpu_load=float(os.popen("uptime | awk -F ': ' '{print$2}' | awk -F ',' '{print$1}'").read())
     #print(cpu_load)
     returncpu_load
netstat -ant 连接数量

正常 netstat -ant 展示情况,一般是不会迅猛增加

 defget_TCP_conn():
     netstat=int(os.popen('netstat -ant | wc -l').read())
     returnnetstat
ss -lnt  读取队列情况

 defget_queue_size():
     queue=os.popen('ss -lnt | grep :80').read()
     recv_q=int(queue.split()[1])
     send_q=int(queue.split()[2])
     returnrecv_q,send_q
主调函数
 if__name__=='__main__':
     whileTrue:
         #cpu_load = get_cpu_load_01()
         #cpu_load = get_cpu_load_02()
         cpu_load=get_cpu_load_03()

         TCP_conn=get_TCP_conn()

         recv_q,send_q=get_queue_size()

         print(f"cpu_load:{cpu_load} TCP_conn:{TCP_conn} TCP_Queue:{recv_q,send_q}")
         time.sleep(2)
         #print(type())
         ifcpu_load>33.3orTCP_conn>2000orrecv_q>send_q-10:
             print("CPU 负载过高或TCP连接数太多,可能遭遇DOS攻击,请注意!!!")

四、利用IP查询实现DOS防御

要实现DOS防御,除了能够检测到DOS攻击,必须还要对检测到的情况进行防御

对连接数量超标的ip地址进行封禁

  • 找到连接数量超标的IP地址

  • 通过执行 netstat -ant 我们可以查看tcp连接情况,然后再通过grep和其他处理方式找到所有连接我们的IP地址

  • 对所有连接本地服务器的IP地址进行处理,利用字典的特性可以统计每一个IP地址连接本地服务器的数量,找到超标的IP地址,执行防火墙将其封禁

 defget_most_ip_basic():
     netstat=os.popen('netstat -ant | findstr :80').read()
     netstat_list=netstat.split('\n')
     ip_list=[]
     forlineinnetstat_list:
         try:
             ip=line.split()[2].split(':')[0]
             ip_list.append(ip)
             #print(ip)
         except:
             pass

     ip_dict= {}
     foripinip_list:
         ifipinip_dict.keys():
             ip_dict[ip] +=1
         else:
             ip_dict[ip] =1
     # print(ip_dict)
     # 默认对可迭代变量进行升序排序,所以改为降序排列
     sort=sorted(ip_dict.values(),reverse=True)
     # print(sort)
     forkey,valueinip_dict.items():
         ifvalue==sort[0]:
             returnkey,value

上面代码适合windows运行,下面适合linux运行

 defget_most_ip():
     netstat=os.popen('netstat -ant | grep :80').read()
     netstat_list=netstat.split('\n')
     ip_list=[]
     forlineinnetstat_list:
         try:
             ip=line.split()[4].split(':')[0]
             ip_list.append(ip)
             #print(ip)
         except:
             pass
     # 直接使用Python内置的计数器来实现排序
     ip_dict=Counter(ip_list)
     most_ip=ip_dict.most_common(1)
     # print(most_ip)
&nbsp;&nbsp; &nbsp;&nbsp;# print(type(most_ip)) &nbsp;# <class 'list'>
&nbsp;&nbsp; &nbsp;&nbsp;returnmost_ip

主调函数

&nbsp;if__name__=='__main__':
&nbsp;&nbsp; &nbsp;&nbsp;whileTrue:
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;#cpu_load = get_cpu_load_01()
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;#cpu_load = get_cpu_load_02()
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;cpu_load=get_cpu_load_03()

&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;TCP_conn=get_TCP_conn()

&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;recv_q,send_q=get_queue_size()

&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"cpu_load:{cpu_load}&nbsp;TCP_conn:{TCP_conn}&nbsp;TCP_Queue:{recv_q,send_q}")
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;time.sleep(2)
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;#print(type())
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;ifcpu_load>33.3orTCP_conn>2000orrecv_q>send_q-10:
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("CPU 负载过高或TCP连接数太多,可能遭遇DOS攻击,请注意!!!")
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;most_ip=get_most_ip()
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(f"出现可疑IP:{most_ip[0][0]}&nbsp;具有连接数:{most_ip[0][1]}&nbsp;")
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;firewall_mostip(most_ip[0][0])

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:secureyang secureyang secureyang《脚本开发之Python检测和防御DOS攻击》

评论:0   参与:  0