zoukankan      html  css  js  c++  java
  • linux , nginx: 封禁IP的办法【转】

    今天,我们的一台服务器出了问题: 被若干IP地址访问某个接口,该接口会发送短信。

    所以,我们可以做两件事: 1. nginx的层面封IP 。  2  linux server的层面封IP

    先看nginx : 非常简单,  加上  deny xxx.x.x.x; 就可以了。

    linux的层面:  iptables -I INPUT -s 110.7.48.47 -j DROP

    就可以把某个IP封掉。

    目测,后者更方便一些。

    在nginx 层面的封禁, req还是会打进来, 让nginx 返回 403,  占用资源。

    还可以把以上步骤做成自动化的脚本,

    参考: http://www.cnblogs.com/huligong1234/p/7189426.html

    下面是如何做成自动化的封禁IP

    直接一步到位:

    1. 修改crontab :    $ crontab -e

    */2 * * * * sh /opt/check_black_ip.sh

    2. 增加这个文件:

    tail -n10000 /usr/local/nginx/logs/access.log | awk '{print $1,$7}' | grep send_login_token | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>30)print "deny "$2";"}' > /usr/local/nginx/conf/blacklist.append.conf
    /usr/local/nginx/sbin/nginx -s reload

    3. 确保你的nginx配置如下:

    http{
        # ....
        include blacklist.conf;
    }

    下面是具体的原理和过程:

    1. 确定好nginx的日志文件的位置,  例如:   /usr/local/nginx/logs/access.log  ( 如果你用了logrotate, 那么这个文件可能是每天更新一次 )

    2. 使用命令:

    $ tail -n50000 /usr/local/nginx/logs/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | | awk '{if($1>100)print "deny "$2";"}'

    第一部分:  awk '{print $1}'  只打印出 所有log的ip (第一个被空格截断的内容)

    sort 是排序(按照字母顺序)

    uniq -c 是对所有内容进行去重,并且计数

    sort -rn 是反向排序。 根据计数的结果。

    所以,上面的命令,会给出如下结果:

     182.84.132.13
     117.82.174.128
     182.150.146.215
     182.148.58.231
     116.7.219.28
     182.150.28.110
     36.7.122.26

    最后一部分的:  awk '{if($1>100) .... }'是一个bash脚本,会找到所有出现过100次的ip, 然后输出一段deny这样的文本:

    deny 182.84.132.13;
    deny 117.82.174.128;
    deny 182.150.146.215;
    deny 182.148.58.231;
    deny 116.7.219.28;
    deny 182.150.28.110;
    deny 36.7.122.26;
    deny 110.7.48.47;
    deny 124.127.182.6;
    deny 110.188.153.219;

    最后的最后,把上数的结果, 使用 ">" (覆盖文件)  或者 ">>" (追加文件) 操作符到blacklist.conf文件中。 完整命令为:

    $ tail -n50000 /usr/local/nginx/logs/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>100)print "deny "$2";"}' >> /usr/local/nginx/conf/blacklist.conf

    nginx中的配置如下:

    http{
        # ....
        include blacklist.conf;
    }

    进一步的,我们可以只针对某个url的访问进行统计, 代码如下:

    $ tail -n10000 /usr/local/nginx/logs/access.log | awk '{print $1,$7}' | grep send_login_token | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if($1>30)print "deny "$2";"}' >> /usr/local/nginx/conf/blacklist.conf

    上面代码,会查看过去10000行nginx记录,找到对于访问 "/interface/..../send_login_token " 的request, 进行ip的计数,对于超过30次访问的,直接封ip

    根据当前时刻的ip访问, 自动封禁ip 的脚本.

    列出当前时刻, 所有的请求数大于10的ip地址: netstat -an | grep ^tcp.*:80 | egrep -v 'LISTEN|127.0.0.1' | awk -F"[ ]+|[:]" '{print $6}' | sort | uniq -c |sort -rn | awk '{ if ($1>10){print $2}}'

    解释:

    1. netstat -an -a 表示列出所有, -n 表示列出来的都是 数字(例如 3.3.3.4 , 而不是名称) 例如:

    # netstat -an
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3020            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3021            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3022            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3023            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:35888           0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3001            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3002            0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:3003            0.0.0.0:*               LISTEN     
    tcp        0      0 172.18.230.209:80       118.112.56.229:6785     TIME_WAIT  
    tcp        0      0 172.18.230.209:37220    218.5.173.146:1521      ESTABLISHED
    tcp        0      0 172.18.230.209:80       182.84.139.53:1817      ESTABLISHED
    tcp        0      0 172.18.230.209:37212    218.5.173.146:1521      ESTABLISHED
    tcp      401      0 172.18.230.209:38086    140.205.140.205:80      CLOSE_WAIT 

    2. $ netstat -an |grep ^tcp.*:80 是对当前的链接中,找到所有的要访问80端口的请求. 例如:

    # netstat -an | grep ^tcp.*:80
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
    tcp        0      0 172.18.230.209:80       118.112.56.229:7873     TIME_WAIT  
    tcp        0      0 172.18.230.209:80       118.112.56.229:7426     ESTABLISHED
    tcp      401      0 172.18.230.209:38086    140.205.140.205:80      CLOSE_WAIT 
    tcp        0      0 172.18.230.209:80       182.84.139.53:49165     TIME_WAIT  
    tcp        0      0 172.18.230.209:80       180.108.11.25:15104     TIME_WAIT 

    3. $ netstat -an |grep ^tcp.*:80 | egrep -v 'LISTEN|127.0.0.1' , 这句话是对 "127.0.0.1' 或者 LISTEN 做个排除. 去掉本地的请求, 去掉 正在 LISTEN的接口

    4. awk -F"[ ]+|[:]" '{print $6}' 这里是对结果做个处理, 把某一行的结果, 按照 空格或者 ':' 冒号来分割,取得第六个.(起始的是第一个), 例如:

    tcp        0      0 172.18.230.209:80       118.112.56.229:7873     TIME_WAIT

    按照空格或者: 来分割的话,第六个就是 118.112.56.229, 这个就是正在请求的IP

    5. sort: 按照字母顺序排序. uniq -c 表示 去重,并且加上 出现的次数. sort -r 表示 翻转排序. -n 表示按照数字的大小排序.

    6. awk '{if ($1>$num){print $2}} 处理结果, 找到满足条件的, 然后打印出来.

    完整版, 根据每秒ip的访问上线,来自动封禁的脚本 :

    #!/bin/bash
    num=100 #  每秒某个ip的访问上限
    list=`netstat -an |grep ^tcp.*:80|egrep -v 'LISTEN|127.0.0.1'|awk -F"[ ]+|[:]" '{print $6}'|sort|uniq -c|sort -rn|awk '{if ($1>$num){print $2}}'`
    for i in $list
    do
          iptables -I INPUT -s $i --dport 80 -j DROP
    done

    解封IP的方法

    先用这个命令看到所有被封禁的IP $ iptables -L -n -v --line-numbers

    iptables -L -n -v --line-numbers
    Chain INPUT (policy ACCEPT 289 packets, 71013 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
            0     0 DROP       all  --  *      *       45.77.183.135        0.0.0.0/0           
            0     0 DROP       all  --  *      *       120.239.199.152      0.0.0.0/0           
            0     0 DROP       all  --  *      *       47.52.132.105        0.0.0.0/0

    然后用这个命令恢复:  iptables -D INPUT ( 例如:iptables -D INPUT 1 就是删掉上面的第一条 45.77.183.135 )

    转自

    linux , nginx: 封禁IP的办法 (自动化脚本封ip, 根据瞬时的请求总量,或者根据日志 - 为程序员服务 http://ju.outofmemory.cn/entry/343736

  • 相关阅读:
    DVWA 黑客攻防演练(十)反射型 XSS 攻击 Reflected Cross Site Scripting
    DVWA 黑客攻防演练(九) SQL 盲注 SQL Injection (Blind)
    DVWA 黑客攻防演练(八)SQL 注入 SQL Injection
    DVWA 黑客攻防演练(七)Weak Session IDs
    DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA
    DVWA 黑客攻防演练(五)文件上传漏洞 File Upload
    工作流表结构设计
    Visual Studio 2019尝鲜----新建空项目体验
    《使用CSLA 2019:CSLA .NET概述》原版和机译文档下载
    .NET快速开发平台的在线预览
  • 原文地址:https://www.cnblogs.com/paul8339/p/11675561.html
Copyright © 2011-2022 走看看