File size: 4,494 Bytes
020c337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# coding: utf-8
import os, sys, time, re, json

os.chdir('/www/server/panel/')
sys.path.insert(0, "class/")
sys.path.insert(0, "/www/server/panel/")

import public
import requests

__isFirewalld = False
__isUfw = False

if os.path.exists('/usr/sbin/firewalld') and os.path.exists('/usr/bin/yum'):
    __isFirewalld = True
if os.path.exists('/usr/sbin/ufw') and os.path.exists('/usr/bin/apt-get'):
    __isUfw = True

def get_malicious_ip(page = 1):
    """
    从官网获取恶意IP情报库
    :param get:
    :return:
    """
    page_size = 10000

    userinfo = public.get_user_info()
    url = "https://www.bt.cn/api/bt_waf/get_system_malicious?x_bt_token=SksBSpWhJE7oVRixKCAZVEsN3QDnfQBU&page={}&size={}&uid={}&serverid={}&access_key={}".format(page,page_size,userinfo['uid'], userinfo['serverid'], userinfo['access_key'])
    res = requests.get(url).json()

    if res["success"]:
        total = res["res"]["total"] #数据总量
        ip_list = set(res["res"]["list"].keys())
        #处理是否下一页
        if total > page_size*page:
            page += 1
            return ip_list | get_malicious_ip(page)
        return ip_list
    else:
        print("每天最多只能同步五次恶意IP库~",res["res"])
        return set()

def clean_log():
    public.ExecShell("echo -n > /var/log/IP-DAILY-LOG.log")

def get_ban_time():
    """
    获取封禁时间
    """
    ban_time = 1
    firewall_config = public.readFile("/www/server/panel/config/firewall_config.json")
    if firewall_config:
        firewall_config = json.loads(firewall_config)
        ban_time = firewall_config.get("maliciousip_ban_time")
        if ban_time is None:
            ban_time = 1
    ban_time = int(ban_time)*86400
    return ban_time

def process_access_ip(malicious_ip_list):
    """
    处理iptables日志文件,获取IP访问情况 与情报库对比
    """
    ban_ip_list = set()
    logs = public.readFile("/var/log/IP-DAILY-LOG.log")
    if not logs:
        print("日志还未产生 稍等系统日志产生后再次运行")
        return ban_ip_list

    logs = logs.split("\n")
    for log in logs:
        if not log: continue
        try:
            pattern = r"SRC=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
            match = re.search(pattern, log)
            if match:
                access_ip = match.group(1).strip()
            else:
                continue
        except:
            continue
        if access_ip in malicious_ip_list:
            ban_ip_list.add(access_ip)
    return ban_ip_list

def reload_firewall():
    """
    重载防火墙
    """
    if __isUfw or not __isFirewalld:
        public.ExecShell('/usr/sbin/ufw reload')
    else:
        public.ExecShell("firewall-cmd --reload")

def clean_iptables(ban_time):
    """
    清理过期ip
    """
    nowtime = time.time()
    malicious_ip_list = public.M('firewall_malicious_ip').select()
    for ip in malicious_ip_list:
        addtime = time.mktime(time.strptime(ip['addtime'], '%Y-%m-%d %X'))
        if nowtime - addtime > ban_time:
            public.M('firewall_malicious_ip').where('id=?', (ip['id'],)).delete()
            public.ExecShell('ipset del in_bt_malicious_ipset {}'.format(ip['address']))

def process_iptables(ban_ip_list):
    """
    通过iptables封禁恶意IP
    :param ban_ip_list:
    :return:
    """
    ban_time = get_ban_time()
    print("IP封禁时间(s):",ban_time)
    if ban_time != 0:
        clean_iptables(ban_time)

    firewall_malicious_path = "/tmp/firewall_malicious_ip.txt"
    tmp_file = open(firewall_malicious_path, 'w')
    _string = ""
    for ip in ban_ip_list:
        _string = _string + "add {} {} timeout {}\n".format("in_bt_malicious_ipset", ip,ban_time)
    tmp_file.write(_string)
    tmp_file.close()

    public.ExecShell('ipset restore -f {}'.format(firewall_malicious_path))

    reload_firewall()
    add_time = time.strftime('%Y-%m-%d %X', time.localtime())
    for ip in ban_ip_list:
        public.M('firewall_malicious_ip').add('address,brief,addtime',(ip, "", add_time))

if __name__ == '__main__':
    print("===自动封禁恶意IP运行开始===")
    malicious_ip_list = get_malicious_ip()
    print("从官网同步恶意IP总量:",len(malicious_ip_list))
    malicious_access_ip = process_access_ip(malicious_ip_list)
    print("本次运行封禁恶意IP数量:",len(malicious_access_ip))
    process_iptables(malicious_access_ip)
    clean_log()
    print("===自动封禁恶意IP运行结束===")