File size: 3,600 Bytes
17e971c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import subprocess
import sys
import os
import time
import threading

def run_cmd(cmd):
    try:
        subprocess.run(cmd, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return True
    except:
        return False

def load_iptables():
    """
    恢复 iptables 规则
    """
    if run_cmd("iptables -C INPUT -j IN_BT"):
        print("iptables 已存在")
    else:
        if run_cmd("iptables-restore --noflush < /www/server/panel/data/iptablesdata"):
            print("iptables 已恢复")

def load_ipset():
    """
    恢复 ipset 规则
    """
    if run_cmd("ipset restore < /www/server/panel/data/ipsetdata"):
        print("ipset 已恢复")
    else:
        print("ipset 已存在")

def save_iptables():
    """
    保存 iptables 规则
    """
    if run_cmd("iptables -C INPUT -j IN_BT"):
        save_cmd = """
            iptables-save   \
            |grep -E '_BT|^\*|^COMMIT' | sed 's/^-A INPUT/-I INPUT/; s/^-A OUTPUT/-I OUTPUT/; s/^-A PREROUTING/-I PREROUTING/'  \
            |awk '
                /^(\*|COMMIT)/ {print; next}
                !seen[$0]++'    \
            > /www/server/panel/data/iptablesdata
        """
        if run_cmd(save_cmd):
            print("iptables 已保存")

def save_ipset():
    """
    保存 ipset 规则
    """
    if run_cmd("ipset save | grep -E '_bt_' > /www/server/panel/data/ipsetdata"):
        print("ipset 已保存")

def dbus_listener():
    if not os.path.exists("/sbin/firewalld"):
        print("非Firewalld")
        return

    cmd = [
        "dbus-monitor",
        "--system",
        "type='signal',path='/org/fedoraproject/FirewallD1',interface='org.fedoraproject.FirewallD1',member='Reloaded'",
        "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.fedoraproject.FirewallD1',arg1=''"
    ]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

    while True:
        line = process.stdout.readline().strip()

        if not line:
            break
        if "signal" in line:
            if "member=Reloaded" in line:
                print("firewalld reload...")
                load_iptables()
            elif "member=NameOwnerChanged" in line:
                print("firewalld restart...")
                threading.Timer(3, load_iptables).start()

def main():
    if len(sys.argv) < 2:
        print("command:start|reload|stop|save")
        sys.exit(1)

    command = sys.argv[1]
    if command == "start":
        load_ipset()
        load_iptables()
        listener_thread = threading.Thread(target=dbus_listener)
        listener_thread.daemon = True
        listener_thread.start()
        while True:
            time.sleep(1)
    elif command == "reload":
        save_ipset()
        save_iptables()
        load_ipset()
        load_iptables()
    elif command == "stop":
        save_ipset()
        save_iptables()
        run_cmd("iptables -D INPUT -j IN_BT; iptables -D OUTPUT -j OUT_BT; iptables -t nat -D PREROUTING -j FORWARD_BT;")
    elif command == "save":
        save_ipset()
        save_iptables()
    elif command == "saveiptables":
        save_iptables()
    elif command == "saveipset":
        save_ipset()
    elif command == "loadiptables":
        load_iptables()
    elif command == "loadipset":
        load_ipset()
    elif command == "reloadiptables":
        save_iptables()
        load_iptables()
    elif command == "reloadipset":
        save_ipset()
        load_ipset()
    else:
        sys.exit(1)

if __name__ == "__main__":
    main()