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