开发者社区> 问答> 正文

Shell脚本:nginx暴力防护DOS及DDOS

先说下我目前的系统情况:
nginx+php+php-fpm+mysql

由于项目还没有上线,所以ECS用的是最低的配置。但我不知道是我自己的问题还是阿里本身的问题,阿里的云盾CC防护最低阀值为100个/s HTTP请求。
在这种情况下,我不得不做了nginx的限制同IP并发数为10。

这么做的效果是,虽然在超过10的并发连接会被nginx返回503。但nginx还是会影响这个请求,这不是我想要的结果,如果有无聊的恶意攻击,日志会被一直这样的快速写入,但一时间也没有特别好的方案。
所以我写了一个shell脚本来做这么一件事:
1.获取当前与10秒后的nginx日志文件
2.对获取到的文件进行处理,统计IP及请求次数
3.获取每个IP在10秒内增加的数量
4.使用iptables关闭10秒后访问次数超过30的IP

脚本如下: #!/bin/bash
## Date: 2015/7/25
## Author: Mislost
## Denfense DDOS with iptables rule.
##定义nginx log文件路径
log_file="/var/log/nginx/access"
## 后台每10秒做一次防护
while true
do
## 获得当前nginx访问信息
    awk -F" " '{print $1}' $log_file | sort | uniq -c | sort -n -r -k1 > /tmp/ip.old
# 获得10秒后nginx访问信息
    sleep 10
    awk -F" " '{print $1}' $log_file | sort | uniq -c | sort -n -r -k1 > /tmp/ip.new
## 格式化信息(也可用IFS=$”\n“实现读行的问题)
    awk -F" " '{print $1":"$2}' /tmp/ip.old > /tmp/old
    awk -F" " '{print $1":"$2}' /tmp/ip.new > /tmp/new
## 获取10秒内请求次数超过30次的IP地址,并通过iptables拒绝访问。
    for line in $(cat /tmp/new)
    do
## 获取所有IP地址,并计算10内在日志中请求数
        IP=`echo $line | awk -F":" '{print $2}'`
        count_new=`echo $line |awk -F":" '{print $1}'`
        count_old=$(awk -F":" "/$IP/{print \$1}" old)
        if [[ $count_old != "" ]];then
            let result=count_new-count_old
        else
            result=$count_new
        fi
        if [[ $result -ge 30  ]];then
# 如果10秒内请求数大于30,拒绝这个IP的所有入站访问
            iptables -I INPUT -s $IP -j DROP
            now=`date "+%Y-%m-%d %H:%M:%S"`
##写入日志来记录被决绝的IP地址
            echo \[$now\]Drop the ip ==== $IP >> /var/log/ddos.log
      fi
done
done




注意:由于iptables写的比较死,如果需要用自己的IP进行测试,请将iptables 规则写成
iptables -I INPUT -s $IP -p tcp --dport 80 -j DROP

用root用户将脚本丢到后台运行。
比如:./ddos.sh &

这可能不是一个好方法,并且次方案只能防护DOS和轻量的DDOS。
我会研究其他的可行方案,并跟踪此贴。
真心希望有更好的方案提供给我。
QQ:124236270

展开
收起
mislost 2015-07-27 17:37:39 11297 0
3 条回答
写回答
取消 提交回答
  • 问题有点多,先说个最主要的吧,绝大多数CC攻击,都是C动态页面,如果你不区分动态和静态来计算请求次数,正常的访客差不多都会被你给封光了,比如访问这个帖子,一共有89个请求。

    -------------------------

    Re:回4楼云代维的帖子
    引用第5楼mislost于2015-07-27 20:31发表的 回4楼云代维的帖子 :
    你说的这个动静的问题 我其实是考虑过的  
    不过我们的静态页面是做了缓存 且日志是另外写在一个文件里的 本来是要求不记录的 后来我加上去的
    所以不存在在access.log中出现静态页面的请求的
    也就是说 access日志中出现的全部都是动态的页面请求
    [url=http://bbs.aliyun.com/job.php?action=topost&tid=252127&pid=679833][/url]

    看不明白你在说什么,能不能帖一下配置代码长长见识。
    2015-07-27 18:37:01
    赞同 展开评论 打赏
  • ReShell脚本:nginx暴力防护DOS及DDOS
    不知道为何 插入代码里 不可设置代码类型 只能如此了

    -------------------------

    回4楼云代维的帖子
    你说的这个动静的问题 我其实是考虑过的  
    不过我们的静态页面是做了缓存 且日志是另外写在一个文件里的 本来是要求不记录的 后来我加上去的
    所以不存在在access.log中出现静态页面的请求的
    也就是说 access日志中出现的全部都是动态的页面请求
    2015-07-27 17:44:21
    赞同 展开评论 打赏
  • 解决方案工程师,负责为企业规划上云迁移方案和云上架构设计,在网站建设开发和云计算领域有多年经验,专注于Linux平台的系统维护以及应用部署。致力于以场景化的方式让云计算,用更加通俗易懂的方式让更多人体验云计算,让云端的计算更质朴的落地。
    文本可以再编辑一下,优化阅读体验。

    CC通过 nginx log + iptable 貌似可以防御
    DDOS 效果不大

    -------------------------

    回 2楼(mislost) 的帖子
    请将iptables 规则写成 i
    ptables -I INPUT -s $IP -p tcp --dport 80 -j DROP

    iptable 你都没有弄好
    2015-07-27 17:41:15
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Shell 脚本速查手册 立即下载
CentOS Nginx PHP JAVA 多语言镜像使用手 立即下载
CentOS Nginx PHP JAVA多语言镜像使用手册 立即下载