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

  • 相关阅读:
    Java入门第37课——猜字母游戏之设计数据结构
    Sublime Text 3 常用快捷键
    WEB前端响应式布局之BootStarp使用
    js让页面逐渐变透明,直到消失
    Vue实战之插件 sweetalert 的使用
    搭建jQuery开发环境
    Layui数据表单的编辑
    SpringBoot基于websocket的网页聊天
    layui修改数据的时候下拉框和选择框默认选中
    Linux 软件编译、安装、删除
  • 原文地址:https://www.cnblogs.com/paul8339/p/11675561.html
Copyright © 2011-2022 走看看