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

正常情况下,暴露于互联网的服务器是不会收到来自目标端口是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得脱身!!

  • 下面的python程序就是从/var/log/iptables.log日志文件中提取每行记录的跟源IP地址的关键字,
  • 并将这些源IP地址追加到一个集合中。
  • 最后将set集合中的ip地址逐行写入一个叫ipList.txt的文本当中

为什么要用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地址


ss8.gif

接下来,需要用到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这个地址集的,刚好有一个数据包被拦截并且丢弃,这样已经说明刚才的配置已经生效了。


由于我们的日志文件可能每天会捕获到来自不同恶意源ip地址的新记录。我们不可能都将上面的python脚本每天都人工执行一遍,此时可以使用crontab的任务计划让python脚本每天设定的时间点执行一次,自动让ipset规则刷新一次
通过sudo crontab -e 命令,配置如下任务计划,让其在每天凌晨0点开始执行

 0 0 * * * ~/set_ip.py

小结:

本案例,需要你对TCP/IP协议有一定程度的了解,以及了解firewalld内部区域和iptables规则的内部运行原理。你不是说主动防御吗?是,我还没有给出完整的示例,因为我认为这是读者自己需要去具体思考,你自己切实的安全方案,但我至少开了一个很好的场景示范,以及实现更复杂的安全需求需要用到的知识点,没错,Python,Python,Python重要事情说三遍,即便是从事IT服务架构设计和运维的人员,或多或少都要涉及Linux+Python组合的复杂应用场景,例如:。

  • 基于域名的rich规则
  • 基于域名的数据包转发
  • 基于域名的策略路由(这条与firewalld无关)

没错,以上是firewalld原生的规则设定无法实现的,但通过python写一个封装firewall-cmd的应用逻辑,下面这些基于应用层的防火墙应用都能够实现,因为通过python的第三方工具:域名解析IP的工具,多如牛毛,例如dnspython是灰常不错的工具。上面说的这些都能够用python写扩展模块来实现。如果你面对高并发的防火墙应用,或需要频繁修改firewalld动态规则/Linux内核的动态路由表,python可能会带来某种程度的服务器资源的性能消耗,那么别忘了还有cython来做python坚强的后盾,cython能令python的某些运算量或高I/O的逻辑能高效地执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容