基于wxpytho的firewall-cmd 简单指令生成工具

firewall_rule_generator.py

import wx

class IPValidator(wx.Validator):
    def __init__(self):
        super().__init__()

    def Clone(self):
        return IPValidator()

    def Validate(self, win):
        text_ctrl = self.GetWindow()
        ip = text_ctrl.GetValue().strip()
        if not ip:
            wx.MessageBox("IP地址不能为空!", "错误", wx.OK|wx.ICON_ERROR)
            return False
        # 简单验证IPv4/IPv6格式(可根据需要扩展正则)
        if ":" in ip:
            # IPv6简单验证(至少有7个冒号分隔的段)
            if len(ip.split(":")) < 3:
                wx.MessageBox("IPv6地址格式不正确!", "错误", wx.OK|wx.ICON_ERROR)
                return False
        else:
            # IPv4简单验证(四组数字,0-255)
            parts = ip.split(".")
            if len(parts) != 4 or not all(p.isdigit() and 0 <= int(p) <= 255 for p in parts):
                wx.MessageBox("IPv4地址格式不正确!", "错误", wx.OK|wx.ICON_ERROR)
                return False
        return True

class FirewallRuleGenerator(wx.Frame):
    def __init__(self, parent, title):
        super(FirewallRuleGenerator, self).__init__(parent, title=title, size=(720, 640))

        self.InitUI()
        self.Centre()

    def InitUI(self):
        panel = wx.Panel(self)
        # 主容器
        vbox = wx.BoxSizer(wx.VERTICAL)
        # 水平容器
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        
        # 规则生成容器
        query_box = wx.StaticBoxSizer(wx.VERTICAL, panel, '规则生成')
        
        # 其他操作容器
        rule_operations_box = wx.StaticBoxSizer(wx.VERTICAL, panel, '其它操作')
        


        # 输入组件
        hbox_ip = wx.BoxSizer(wx.HORIZONTAL)
        self.tc_ip = wx.TextCtrl(panel, validator=IPValidator())
        self.tc_ip.SetHint("请输入IP地址(如192.168.1.1或2001:db8::1)")
        hbox_ip.Add(wx.StaticText(panel, label='IP地址: '), 0, wx.ALIGN_CENTRE|wx.RIGHT, 5)
        hbox_ip.Add(self.tc_ip, 1)

        hbox_port = wx.BoxSizer(wx.HORIZONTAL)
        self.tc_port = wx.TextCtrl(panel)
        self.tc_port.SetHint("请输入端口号(如80或8080)")
        hbox_port.Add(wx.StaticText(panel, label='端口号: '), 0, wx.ALIGN_CENTRE|wx.RIGHT, 5)
        hbox_port.Add(self.tc_port, 1)

        # 下拉框
        hbox_family = wx.BoxSizer(wx.HORIZONTAL)
        self.choice_family = wx.Choice(panel, choices=['ipv4', 'ipv6'])
        self.choice_family.SetSelection(0)
        hbox_family.Add(wx.StaticText(panel, label='地址类型: '), 0, wx.ALIGN_CENTRE|wx.RIGHT, 5)
        hbox_family.Add(self.choice_family, 1)

        hbox_protocol = wx.BoxSizer(wx.HORIZONTAL)
        self.choice_protocol = wx.Choice(panel, choices=['tcp', 'udp'])
        self.choice_protocol.SetSelection(0)
        hbox_protocol.Add(wx.StaticText(panel, label='协议类型: '), 0, wx.ALIGN_CENTRE|wx.RIGHT, 5)
        hbox_protocol.Add(self.choice_protocol, 1)

        # 操作类型下拉框
        hbox_operation = wx.BoxSizer(wx.HORIZONTAL)
        self.choice_operation = wx.Choice(panel, choices=['添加防火墙规则', '移除防火墙规则'])
        self.choice_operation.SetSelection(0)
        hbox_operation.Add(wx.StaticText(panel, label='操作类型: '), 0, wx.ALIGN_CENTRE|wx.RIGHT, 5)
        hbox_operation.Add(self.choice_operation, 1)

        # 自动重新加载防火墙单选框(默认不选中)
        self.check_reload = wx.CheckBox(panel, label='自动重新加载防火墙')
        self.check_reload.SetValue(False)

        # 生成按钮
        self.btn_generate = wx.Button(panel, label='生成指令')
        self.btn_generate.Bind(wx.EVT_BUTTON, self.on_generate)
        
        # 规则生成容器内布局
        query_box.Add(hbox_ip, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(hbox_port, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(hbox_family, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(hbox_protocol, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(hbox_operation, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(self.check_reload, 0, wx.EXPAND|wx.ALL, 10)
        query_box.Add(self.btn_generate, 0, wx.ALIGN_CENTRE|wx.ALL, 10)
        
        self.btn_query = wx.Button(panel, label='查询所有规则')
        self.btn_query.Bind(wx.EVT_BUTTON, self.on_query_rules)
        
        self.btn_reload = wx.Button(panel, label='重新加载防火墙')
        self.btn_reload.Bind(wx.EVT_BUTTON, self.on_reload_rules)
        
        self.btn_remove_all = wx.Button(panel, label='删除所有rich-rule(谨慎使用!!!)')
        self.btn_remove_all.SetForegroundColour(wx.RED)
        self.btn_remove_all.Bind(wx.EVT_BUTTON, self.on_remove_all_rules)
        
        self.btn_get_ip_query_frequency = wx.Button(panel, label='获取nginx IP查询频率')
        self.btn_get_ip_query_frequency.Bind(wx.EVT_BUTTON, self.on_get_ip_query_frequency)
        
        rule_operations_box.Add(self.btn_query, 0, wx.ALIGN_LEFT|wx.ALL, 10)
        rule_operations_box.Add(self.btn_reload, 0, wx.ALIGN_LEFT|wx.ALL, 10)
        rule_operations_box.Add(self.btn_remove_all, 0, wx.ALIGN_LEFT|wx.ALL, 10)
        rule_operations_box.Add(self.btn_get_ip_query_frequency, 0, wx.ALIGN_LEFT|wx.ALL, 10)
        
        
        hbox.Add(query_box, 1, wx.EXPAND|wx.ALL, 10)
        hbox.Add(rule_operations_box, 1, wx.EXPAND|wx.ALL, 10)
        
        # 富文本框
        self.te_output = wx.TextCtrl(panel, style=wx.TE_MULTILINE|wx.TE_READONLY)
        
        vbox.Add(hbox, 0, wx.EXPAND|wx.ALL, 10)
        vbox.Add(wx.StaticText(panel, label='生成指令:'), 0, wx.ALIGN_LEFT|wx.LEFT, 10)
        vbox.Add(self.te_output, 1, wx.EXPAND|wx.ALL, 10)

        panel.SetSizer(vbox)

    def on_query_rules(self, event):
        query_rule = 'firewall-cmd --list-rich-rules'
        self.te_output.SetValue(f'操作类型: 查询所有规则\n生成指令:\n{query_rule}')
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.TextDataObject(query_rule))
            wx.TheClipboard.Close()
            wx.MessageBox('查询指令已复制到剪贴板', '提示', wx.OK|wx.ICON_INFORMATION)
        else:
            wx.MessageBox('无法访问剪贴板', '错误', wx.OK|wx.ICON_ERROR)
    
    def on_reload_rules(self, event):
        reload_rule = 'firewall-cmd --reload'
        self.te_output.SetValue(f'操作类型: 重新加载防火墙\n生成指令:\n{reload_rule}')
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.TextDataObject(reload_rule))
            wx.TheClipboard.Close()
            wx.MessageBox('查询指令已复制到剪贴板', '提示', wx.OK|wx.ICON_INFORMATION)
        else:
            wx.MessageBox('无法访问剪贴板', '错误', wx.OK|wx.ICON_ERROR)
    
    def on_remove_all_rules(self, event):
        remove_all_rules = 'firewall-cmd --permanent --list-rich-rules | while read -r rule; do firewall-cmd --permanent --remove-rich-rule="$rule"; done'
        self.te_output.SetValue(f'操作类型: 删除所有防火墙(谨慎使用!!!)\n生成指令:\n{remove_all_rules}')
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.TextDataObject(remove_all_rules))
            wx.TheClipboard.Close()
            wx.MessageBox('删除指令已复制到剪贴板(谨慎使用!!!)', '提示', wx.OK|wx.ICON_INFORMATION)
        else:
            wx.MessageBox('无法访问剪贴板', '错误', wx.OK|wx.ICON_ERROR)
    
    def on_get_ip_query_frequency(self, event):
        get_ip_query_frequency = "awk '{print $1}' access.log | sort | uniq -c | sort -nr"
        self.te_output.SetValue(f'操作类型: 查询nginx日志中ip访问频率\n生成指令:\n{get_ip_query_frequency}')
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.TextDataObject(get_ip_query_frequency))
            wx.TheClipboard.Close()
            wx.MessageBox('查询nginx日志中ip访问频率指令已复制到剪贴板', '提示', wx.OK|wx.ICON_INFORMATION)
        else:
            wx.MessageBox('无法访问剪贴板', '错误', wx.OK|wx.ICON_ERROR)
    
    def on_generate(self, event):
        # 触发IP输入框的验证
        if not self.tc_ip.Validate():
            self.tc_ip.SetFocus()
            return
        ip = self.tc_ip.GetValue().strip()
        port = self.tc_port.GetValue().strip()
        family = self.choice_family.GetStringSelection()
        protocol = self.choice_protocol.GetStringSelection()

        if not ip or not port:
            wx.MessageBox('请填写IP地址和端口号', '错误', wx.OK|wx.ICON_ERROR)
            return
        if not port.isdigit():
            wx.MessageBox('端口号必须是数字', '错误', wx.OK|wx.ICON_ERROR)
            return
        
        auto_reload_rule = ""
        if self.check_reload.GetValue():
            auto_reload_rule = ' && firewall-cmd --reload'
            
        operation = self.choice_operation.GetStringSelection()
        action = '--add-rich-rule' if operation == '添加防火墙规则' else '--remove-rich-rule'
        rule = f'firewall-cmd --permanent {action}="rule family=\\"{family}\\" source address=\\"{ip}\\" port port=\\"{port}\\" protocol=\\"{protocol}\\" reject" {auto_reload_rule}'
        self.te_output.SetValue(rule)
        self.te_output.SetValue(f'操作类型: {operation}\n生成指令:\n{rule}')

        # 复制到剪贴板
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(wx.TextDataObject(rule))
            wx.TheClipboard.Close()
            wx.MessageBox('指令已复制到剪贴板(运行完毕请重新加载防火墙)', '提示', wx.OK|wx.ICON_INFORMATION)
        else:
            wx.MessageBox('无法访问剪贴板', '错误', wx.OK|wx.ICON_ERROR)


if __name__ == '__main__':
    app = wx.App()
    frame = FirewallRuleGenerator(None, '防火墙指令生成工具')
    frame.Show()
    app.MainLoop()
posted @ 2025-06-04 17:56  BrianSun  阅读(14)  评论(0)    收藏  举报