python|python 控制Windows防火墙(FireWall)

一、说明

最近有朋友问有木有认识做.Net关于Windows防火墙开发的朋友,很是好奇,为啥子需要用.Net开发呢,为啥不用万能的python。然而在认识的同事和朋友中,并没有做.Net开发的(原因未知),就用python尝试一下吧
重点:
  • 管理员权限运行
  • netsh advfirewall firewall 了解一下(手动滑稽)
二、win32com通用
【python|python 控制Windows防火墙(FireWall)】不懂Windows的com组件,只知道python可以用win32com库调用com相关接口,或者加载调用dll库,需要的包:
import pythoncom import win32com

1. win32com.client.gencache.EnsureDispatch
根据官方声明,调用上述函数会自动生成指定com组件的结构,例如用python运行一下代码:
win32com.client.gencache.EnsureDispatch('HNetCfg.FwMgr', 0)
则会在目录C:\Users\Administrator\AppData\Local\Temp\gen_py\3.6\下生成一个py文件,其中:
class INetFwPolicy2(DispatchBaseClass): CLSID = IID('{98325047-C671-4174-8D81-DEFCD3F03186}') coclass_clsid = None .... # 表示该组件的get方法 _prop_map_get_ = { "CurrentProfileTypes": (1, 2, (3, 0), (), "CurrentProfileTypes", None), "LocalPolicyModifyState": (15, 2, (3, 0), (), "LocalPolicyModifyState", None), # Method 'Rules' returns object of type 'INetFwRules' #Rules保存所有规则,其返回类型为'INetFwRules‘ "Rules": (7, 2, (9, 0), (), "Rules", '{9C4C6277-5027-441E-AFAE-CA1F542DA009}'), # Method 'ServiceRestriction' returns object of type 'INetFwServiceRestriction' "ServiceRestriction": (8, 2, (9, 0), (), "ServiceRestriction", '{8267BBE3-F890-491C-B7B6-2DB1EF0E5D2B}'), } _prop_map_put_ = { } ... class INetFwRules(DispatchBaseClass): CLSID = IID('{9C4C6277-5027-441E-AFAE-CA1F542DA009}') coclass_clsid = None ... _prop_map_get_ = { "Count": (1, 2, (3, 0), (), "Count", None), } _prop_map_put_ = { } def __iter__(self): "Return a Python iterator for this object" try: ob = self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),()) except pythoncom.error: raise TypeError("This object does not support enumeration") return win32com.client.util.Iterator(ob, '{AF230D27-BABA-4E42-ACED-F524F22CFCE2}')

注:关于'HNetCfg.FwMgr'的来源--https://www.2cto.com/kf/200904/37096.html
2. 文件说明和接口调用
INetFwPolicy2类为一个com组件,其提供get和set接口,每一项代表一个接口,get接口有:
  • "CurrentProfileTypes": (1, 2, (3, 0), (), "CurrentProfileTypes", None)
  • "LocalPolicyModifyState": (15, 2, (3, 0), (), "LocalPolicyModifyState", None)
  • "Rules": (7, 2, (9, 0), (), "Rules", '{9C4C6277-5027-441E-AFAE-CA1F542DA009}')
  • "ServiceRestriction": (8, 2, (9, 0), (), "ServiceRestriction", '{8267BBE3-F890-491C-B7B6-2DB1EF0E5D2B}')
需要特别注意,元组中最后一项表示该接口返回的类型对应的已注册的com类型,如果为None,如上述的CurrentProfileTypes接口,则可以打印出,一般为数字 通过调用以下代码,来查看一下我们的防火墙规则:
fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0) print(fw.CurrentProfileTypes) rules = fw.Rules # 此处根据`Rules`的类型{9C4C6277-5027-441E-AFAE-CA1F542DA009}找到INetFwRules print(rules.Count) for rule in rules: print(rule)# rule的类型查找方法如上,INetFwRules为一个类迭代器,返回类型为{AF230D27-BABA-4E42-ACED-F524F22CFCE2} rule = `win32com.client.CastTo(rule, "INetFwRule3") print(rule.Name)

  • 根据接口Rules的类型{9C4C6277-5027-441E-AFAE-CA1F542DA009}找到类INetFwRules
  • INetFwRules为一个类迭代器,返回类型为{AF230D27-BABA-4E42-ACED-F524F22CFCE2} INetFwRule即为rule的类型
  • INetFwRule中的getput接口对防火墙规则的一个属性,通过设置属性来获取或设置防火墙
  • INetFwRule中的属性较少,我们可以用rule = win32com.client.CastTo(rule, "INetFwRule3")将其转换为INetFwRule3来查看更多属性
    INetFwRule3属性如下
class INetFwRule(DispatchBaseClass): CLSID = IID('{AF230D27-BABA-4E42-ACED-F524F22CFCE2}') coclass_clsid = None_prop_map_get_ = { "Action": (18, 2, (3, 0), (), "Action", None), "ApplicationName": (3, 2, (8, 0), (), "ApplicationName", None), "Description": (2, 2, (8, 0), (), "Description", None), "Direction": (11, 2, (3, 0), (), "Direction", None), "EdgeTraversal": (17, 2, (11, 0), (), "EdgeTraversal", None), "Enabled": (14, 2, (11, 0), (), "Enabled", None), "Grouping": (15, 2, (8, 0), (), "Grouping", None), "IcmpTypesAndCodes": (10, 2, (8, 0), (), "IcmpTypesAndCodes", None), "InterfaceTypes": (13, 2, (8, 0), (), "InterfaceTypes", None), "Interfaces": (12, 2, (12, 0), (), "Interfaces", None), "LocalAddresses": (8, 2, (8, 0), (), "LocalAddresses", None), "LocalPorts": (6, 2, (8, 0), (), "LocalPorts", None), "Name": (1, 2, (8, 0), (), "Name", None), "Profiles": (16, 2, (3, 0), (), "Profiles", None), "Protocol": (5, 2, (3, 0), (), "Protocol", None), "RemoteAddresses": (9, 2, (8, 0), (), "RemoteAddresses", None), "RemotePorts": (7, 2, (8, 0), (), "RemotePorts", None), "serviceName": (4, 2, (8, 0), (), "serviceName", None), }

三、防火墙控制
上述内容中,我们介绍如何使用win32com组件生成py接口类,通过给定的接口查找我们的防火墙规则,以及各个组件属性、调用和返回值。下面将介绍规则属性:
items_name = { "Action":'操作', "ApplicationName":'程序', "Description":'描述', "Direction":'进站/出站', "EdgeTraversal":'边缘穿越', "EdgeTraversalOptions":'边缘穿越选项', "Enabled":'已启用', "Grouping":'组', "IcmpTypesAndCodes":'ICMP设置', "InterfaceTypes":'接口类型', "Interfaces":'接口', "LocalAddresses":'本地地址', "LocalAppPackageId":'应用程序包', "LocalPorts":'本地端口', "LocalUserAuthorizedList":'授权的本地计算机', "LocalUserOwner":'本地用户所有者', "Name":'名称', "Profiles":'配置文件', "Protocol":'协议', "RemoteAddresses":'远程地址', "RemoteMachineAuthorizedList":'授权的远程计算机', "RemotePorts":'远程端口', "RemoteUserAuthorizedList":'授权的远程用户', "SecureFlags":'安全', "serviceName":'服务名'}

防火墙规则请参考Windows文档(皮一下),接口文档 四、全量代码
# fw_rules.pyclass rule: items = {} # 中英文转换 items_name = { "Action":'操作', "ApplicationName":'程序', "Description":'描述', "Direction":'进站/出站', "EdgeTraversal":'边缘穿越', "EdgeTraversalOptions":'边缘穿越选项', "Enabled":'已启用', "Grouping":'组', "IcmpTypesAndCodes":'ICMP设置', "InterfaceTypes":'接口类型', "Interfaces":'接口', "LocalAddresses":'本地地址', "LocalAppPackageId":'应用程序包', "LocalPorts":'本地端口', "LocalUserAuthorizedList":'授权的本地计算机', "LocalUserOwner":'本地用户所有者', "Name":'名称', "Profiles":'配置文件', "Protocol":'协议', "RemoteAddresses":'远程地址', "RemoteMachineAuthorizedList":'授权的远程计算机', "RemotePorts":'远程端口', "RemoteUserAuthorizedList":'授权的远程用户', "SecureFlags":'安全', "serviceName":'服务名'} items_shell = { "Action": 'action', "ApplicationName": 'program', "Description": 'description', "Direction": 'dir', "EdgeTraversal": 'edge', "EdgeTraversalOptions": '边缘穿越选项', "Enabled": 'enable', "Grouping": '组', "IcmpTypesAndCodes": 'ICMP设置', "InterfaceTypes": 'interfacetype', "Interfaces": '接口', "LocalAddresses": 'localip', "LocalAppPackageId": '应用程序包', "LocalPorts": 'localport', "LocalUserAuthorizedList": '授权的本地计算机', "LocalUserOwner": '本地用户所有者', "Name": 'name', "Profiles": 'profile', "Protocol": 'protocol', "RemoteAddresses": 'remoteip', "RemoteMachineAuthorizedList": 'rmtcomputergrp', "RemotePorts": 'remoteport', "RemoteUserAuthorizedList": 'rmtusrgrp', "SecureFlags": 'security', "serviceName": 'service' } def __init__(self,index): self.index = index for i in self.items_name.keys(): self.items[i] = ''def init_by_app(self, app_in): for key in self.items_name.keys(): self.items[key] = " " + str(eval("app_in."+key)) print(self.items[key] )def init_by_dict(self,dirc_con): flag = False for item_key in self.items_name.keys(): if self.items_name[item_key] in dirc_con.keys(): flag = True self.items[item_key] = dirc_con[self.items_name[item_key]]if not flag: for key in dirc_con.keys(): self.items[key] = dirc_con[key]def create_rule(self): app = win32com.client.Dispatch('HNetCfg.FwRule') res = [] # 注意赋值顺序 app.Action = int(self.items["Action"]) app.Description = self.items["Description"] app.Direction = int(self.items["Direction"]) app.EdgeTraversal = self.items["EdgeTraversal"] app.EdgeTraversalOptions = self.items["EdgeTraversalOptions"] app.Enabled = self.items["Enabled"] app.Grouping = self.items["Grouping"] ## app.IcmpTypesAndCodes = self.items["IcmpTypesAndCodes"] app.InterfaceTypes = self.items["InterfaceTypes"] ## app.Interfaces = self.items["Interfaces"] app.LocalAddresses = self.items["LocalAddresses"] app.LocalAppPackageId = self.items["LocalAppPackageId"] ## app.LocalPorts = str(self.items["LocalPorts"]), ## app.LocalUserAuthorizedList = self.items["LocalUserAuthorizedList"] app.LocalUserOwner = self.items["LocalUserOwner"] app.Name = self.items["Name"] app.Profiles = self.items["Profiles"] app.Protocol = self.items["Protocol"] app.RemoteAddresses = self.items["RemoteAddresses"] ## app.RemoteMachineAuthorizedList = self.items["RemoteMachineAuthorizedList"] app.RemotePorts = self.items["RemotePorts"] app.LocalPorts = self.items['LocalPorts'] ## app.RemoteUserAuthorizedList = '' app.SecureFlags = self.items["SecureFlags"] # app.serviceName = "null" # app.ApplicationName = "null" return appdef __str__(self): result = "="*10 + '\n序号 : ' + str(self.index) + '\n' for key in self.items_name.keys(): result += self.items_name[key] + " : " + str(self.items[key]) +"\n" return resultdef add_rule(dict_value): fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0) apps = fw.Rules print(apps.Count) # app = win32com.client.Dispatch('HNetCfg.FwRule3') rule_obj = rule(-1) rule_obj.init_by_dict(dict_value) app = rule_obj.create_rule() apps.Add(app)def del_rule(dict_value):fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0) apps = fw.Rules print("before :", apps.Count) rule_obj = rule(-1) rule_obj.init_by_dict(dict_value) for app in apps: print(rule_obj.items['Name'] , str(app.Name)) print(rule_obj.items['LocalPorts'] , str(app.LocalPorts)) print(rule_obj.items['RemoteAddresses'] , str(app.RemoteAddresses)) if rule_obj.items['Name'] == str(app.Name) and rule_obj.items['LocalPorts'] == str(app.LocalPorts) and rule_obj.items['RemoteAddresses'] == str(app.RemoteAddresses): # 只能根据Name删除,大概是个傻子哟 apps.Remove(str(app.Name)) # break print("after :", apps.Count)if __name__ == '__main__': my_dict = { '序号' : '2', '操作' : '0', '程序' : '', '描述' : '', '进站/出站' : '1', '边缘穿越' : 'False', '边缘穿越选项' : '0', '已启用' : 'True', '组' : '', 'ICMP设置' : '', '接口类型' : 'All', '接口' : 'None', '本地地址' : '*', '应用程序包' : '', '本地端口' : '9876', '授权的本地计算机' : '', '本地用户所有者' : '', '名称' : 'test_cmd', '配置文件' : '2', '协议' : '6', '远程地址' : '114.115.250.41/255.255.255.255', '授权的远程计算机' : '', '远程端口' : '*', '授权的远程用户' : '', '安全' : '0', '服务名' : '' } add_rule(my_dict) del_rule(my_dict)

原创不易,不喜勿喷
https://www.jianshu.com/p/78e70e8e363d

    推荐阅读