| 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() |