我用 LinuxLinux学习|Gentoo/Arch/FreeBSDLinux

第11篇:Linux防火墙 黑名单管理

2020-04-03  本文已影响0人  铁甲万能狗

正常情况下,暴露于互联网的服务器是不会收到来自目标端口是137,138,139的数据包,若你对Samba协议熟悉的话,这三个端口是Windows系统用于请求NetBIOS主机名称,若短短在10分钟之内,你的服务器收到来自这些莫名奇妙的数据包,基本可以断定是收到来自互联网其他来历不明源IP对你主机的端口扫描。

这些端口扫描,来源与Windows 2000/XP时代NetBIOS服务漏洞,包含netbios-ssn(139/tcp)以及netbios-ns(137/tcp),NetBios 會洩漏远程主机的ID以及的主机名称,入侵者更可以使用密碼破解工具,对主机進行字典攻击的,如下图是笔者的Linux服务器在最近运行以来,收到来自这些恶意IP地址的端口扫描

如果你有阅读我之前的Linux防火墙系列文章,应该了解到如下firewalld的规则的重要性,我们来自可疑的数据包都做了日志记录,但仅有日志记录是远远不够的,还要采取一些主动防御措施

这也是会有本篇随笔的原因,所谓的主动防御就是Linux防火墙从目前的防火墙日志中提取那些恶意的IP地址,并制作一个黑名单写入规则中,永久Ban掉这些恶意IP。

本篇会以防止端口扫描为例,这个案例中会用到这些direct规则

ipv4 mangle PORT_SCANNING 0 -m recent --name portscan --rcheck --seconds 25200 -j DROP
ipv4 mangle PORT_SCANNING 1 -m recent --name portscan --remove
ipv4 mangle PORT_SCANNING 2 -p tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix port_scan:
ipv4 mangle PORT_SCANNING 3 -p tcp --dport 139 -m recent --name portscan --set -j DROP
ipv4 mangle PORT_SCANNING 4 -p tcp --dport 138 -m recent --name portscan --set -j LOG --log-prefix port_scan:
ipv4 mangle PORT_SCANNING 5 -p tcp --dport 138 -m recent --name portscan --set -j DROP
ipv4 mangle PORT_SCANNING 6 -p tcp --dport 137 -m recent --name portscan --set -j LOG --log-prefix port_scan:
ipv4 mangle PORT_SCANNING 7 -p tcp --dport 137 -m recent --name portscan --set -j DROP

根据前面一篇的日志管理,我们将防火墙日志保存在/var/log/iptables.log这个文件中,也就是上文第一个插图的日志记录。我们需要从日志中提取有用的源IP地址。你应该要想到“Python大法好,信Python得脱身!!

为什么要用set,而不用list呢?因为set数据接口可以除去重复的IP地址。这个Python程序没什么好说的,一目了然。

#!/usr/bin/python3 
import os,re

logFile='/var/log/iptables.log'
blkIpFile='~/iplist.txt'

ip_pat=re.compile(r'SRC=(\d+\.\d+\.\d+\.\d+)')

if not os.path.exists(logFile):
    raise FileNotFoundError("{}文件不存在!!".format(logFile))

keyWords=["port_scan","syn_attack"]

res=None
blackIPs=set()

with open(logFile,'r') as f:
    data=f.readlines()
    
    for line in data:
        for word in keyWords:
            if word in line:
                res=ip_pat.findall(line)
                if len(res):
                    print("找到源ip:{}".format(res[1]))
                    blackIPs.add(res[1])
                break
            #if
        #end-for
    #end-for
#end-with


if not os.path.exists(blkIpFile):
    raise FileNotFoundError("{}文件不存在".format(blkIpFile))

with open(blkIpFile,'w') as f:
    
    if len(blackIPs)==0:
        raise ValueError("参数blackIPs为空!!\n")
    for item in blackIPs:
        f.write("{}\n".format(item))
    #end-for
#end-with

运行上面的脚本后,我们可以查看iplist.txt这个文本,笔者都惊呆了,运行短短十多天的服务器居然遭到650多个恶意IP地址


接下来,需要用到firewalld的ipset选项,将上面的iplist.txt文件导入到firewalld的规则中,

ipset指定的IP地址集可以在防火墙区域中用作源地址过滤,也可以用作rich规则中的源地址。 在Red Hat Enterprise Linux 7中,首选方法是在direct规则中使用用firewalld创建的ipset。

以本文为例,创建一个名为“blk_src_ips”的ipset

firewall-cmd --permanent --new-ipset=blk_src_ips --type=hash:net

type选项中的hash:net对应的是ipv4的网络环境。 要创建用于IPv6的IP集,请添加--option = family = inet6选项。

接下来,就是使用--add-entries-from-file选项将iplist.txt的内容导入到blk_src_ips的ipset空间中

irewall-cmd --permanent --ipset=blk_src_ips --add-entries-from-file=~/iplist.txt

跟着,我们在drop区域中定义一条源规则,将blk_src_ips的地址集作为源规则的源IP,我们之所以要使用drop区域是因为drop区域默认就是任何绑定到该区域的IP地址或端口的数据包都一律丢弃。

firewall-cmd --permanent --zone=drop --add-source=ipset:blk_src_ips

最后一步,非常关键,一定要确保drop区域是防火墙最后要被执行的默认区域,因此一定要补上这条命令

firewall-cmd --permanent --set-default-zone=drop
firewall-cmd --reload

运行一段时间,或许你会发现的默认区域的策略已经生效了,PRE_drop这条链中正是匹配ipset:blk_src_ips这个地址集的,刚好有一个数据包被拦截并且丢弃,这样已经说明刚才的配置已经生效了。


ss8.png

小结:

本案例,需要你对TCP/IP协议有一定程度的了解,以及了解firewalld内部区域和iptables规则的内部运行原理。

上一篇下一篇

猜你喜欢

热点阅读