趙慶明
(成都理工大學 四川 成都 610059)
Windows Server在企事業單位中扮演了重要的角色,對于一些保存了重要數據的Windows Server來說,其安全問題尤為突出。雖然可以通過前置的安全設備對這些服務器進行保護以抵御外部網絡上的攻擊,但卻無法抵御內部網絡中的攻擊。而Windows Server自身提供了一個“高級安全Windows防火墻”對自身系統的提供了“安全”防護。該管理界面對用戶“簡單”易用,同時卻顯得“簡陋”。在系統管理員對防火墻規則的設置和檢查的時候,這個“簡陋”的界面難以有效管理“大量”的規則。本文探討一種采用自定義的配置文件,編程的方式來設置Windows防火墻規則,以便系統管理員更高效、便捷地管理Windows Server自身的防火墻。
Windows系統是一個友好的系統,其公開的API(應用程序接口)多達一萬個以上,并且每一次發布的新版本都會增加數以千計的新API。除了Windows保留的一些特殊的API的外,對外公開API幾乎包含了Window系統的方方面面。而這些API大多以dll文件存儲在Windows系統相關目錄中,還有不少以COM接口的方式公開了接口。
總體上,這些接口可以分如下幾大類:基礎服務,提供對Windows系統可用的基礎資源的訪問接口。比如文件系統、外部設備、進程、線程以及訪問注冊表和錯誤處理機制等等。圖形設備接口,提供的功能為:輸出圖形內容到顯示器、打印機以及其他外部輸出設備。圖形化用戶界面,提供了創建和管理屏幕和大多數基本控件的功能,比如按鈕和滾動條、接收鼠標和鍵盤輸入以及其他與GUI有關的功能。通用對話框鏈接庫,為應用程序提供標準對話框,比如打開/保存文檔對話框、顏色對畫框和字體對話框等等。通用控件鏈接庫,為應用程序提供接口來訪問操作系統提供的一些高級控件。比如狀態欄、進度條、工具欄和標簽等等。網絡服務,為訪問操作系統提供的多種網絡功能提供接口,包括NetBIOS、Winsock、NetDDE及RPC等等。
與防火墻相關的API由“C:WindowsSystem32FirewallAPI.dll”文件提供。如果使用Visual Studio 2019進行基于C#的開發,則在項目中引用名為“NetFwTypeLib”的COM組件即可。當然,也可以直接添加對于“FirewallAPI.dll”的引用,Visual Studio會自動將其封裝成一個名為“NetFwTypeLib”的.NET的程序集,同時生成一個可以支持互操作的“Interop.NetFwTypeLib.dll”文件。作為一個工具的開發,無需開發太多功能,開發的功能可以滿足自己需求即可,這樣可以快速完成開發工作,進而快速投入使用。
在Visual Studio 2019的引用中,雙擊“NetFwTypeLib”,可打開“對象瀏覽器”窗口,聚焦在“Interop.NetFwTypeLib”子項之上,點擊該子項可以看到其來自于本項目”Debug”目錄中的“Interop.NetFwTypeLib.dll”之中。展開子項,里面僅僅可見9個枚舉:“NET_FW_ACTION_、NET_FW_IP_PROTOCOL_、NET_FW_IP_VERSION_、NET_FW_MODIFY_STATE_、NET_FW_PROFILE_TYPE2_、NET_FW_PROFILE_TYPE_、NET_FW_RULE_DIRECTION_、NET_FW_SCOPE_、NET_FW_SERVICE_TYPE_”,由字面可以理解其表示的含義。進一步展開這些枚舉,可以根據枚舉成員的字面意思理解其表示的含義。
使用.net程序反編譯器dnSpy打開“Interop.NetFwTypeLib.dll”文件,除了可以看到Visual Studio 2019“對象瀏覽器”可以看到的基本內容外,還能看到這些枚舉中枚舉項的常量值。另外,還可以看到反編譯后的19個接口以及這些接口內部的定義。相關的說明,可以參考MSDN。
在使用該工具的時候,通常需要啟動防火墻。因此,無需檢查Windows Server防火墻是否已經啟用,調用API直接啟用即可。可分別對“域網絡”、“專用網絡”和“公用網絡”啟用防火墻規則。“域網絡”指工作區域中已加入域的網絡;“專用網絡”指家中或工作單位的網絡;“公共網絡”指如機場或咖啡店等公共場所的網絡。通常無需區分,全部“啟用”防火墻。
防火墻中,以規則名稱來辨認規則,但不同規則可以有相同的名稱。實際使用過程中,盡可能避免不同的規則取相同的名稱。無論是在程序中,還是在“高級安全Windows防火墻”,均可以通過選擇“規則名”的方式來刪除指定規則。雖然在“高級安全Windows防火墻”可以“修改”規則,但在Windows公開的API并無“修改”的功能,那么實現機制則為“讀取+刪除+添加”。
刪除指定名稱的規則后,再重新創建一條同名的規則,將其添加至規則列表即可。使用開放的API對規則讀取,無需管理員權限。但修改規則(刪除、添加)則需管理員權限。在C#的項目中添加一個名為“app.manifest”的XML格式的“應用程序清單文件”,修改requestedExecutionLevel元素的level屬性為”requireAdministrator”,編譯好的程序在啟動的時候會自動申請管理員權限。
在代碼編寫之前,先引用“NetFwTypeLib”命名空間,接下來便可使用與防火墻相關的枚舉和接口。由于設置的功能是通過COM接口來實現的,因此需要在本地創建“遠程”對象的引用,然后對該對象進行相關的操作。
首先取得防火墻規則的COM對象的類型。
Type type=Type.GetTypeFromProgID(“HNetCfg.FwPolicy2”);
接下來,在本地創建該“遠程”對象的引用,并將其強制轉換為INetFwPolicy2類型。
INetFwPolicy2 INetFwPolicy=(INetFwPolicy2)Activator.CreateInstance(type);
在三個“網絡”區域上,全部都啟用防火墻。
INetFwPolicy.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC]=true;
INetFwPolicy.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE]=true;
INetFwPolicy.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_DOMAIN]=true;
根據規則名稱刪除舊規則。這句需要管理員權限,否則報錯。如果“規則名”存在,則會刪除此規則,如果“規則名”不存在,執行此行代碼也不會報錯。
INetFwPolicy.Rules.Remove(“規則名”);
接下來創建一條規則,此功能同樣通過COM接口實現,同樣需要在本地創建“遠程”對象的引用,然后對此規則進行相關的操作。
Type type2=Type.GetTypeFromProgID(“HNetCfg.FwRule”);
在本地創建該“遠程”對象的引用,并將其強制轉換為INetFwRule類型。
INetFwRule INetFwRule=(INetFwRule)Activator.CreateInstance(type2);
設置規則名稱:
INetFwRule.Name=“規則名”;
設置規則描述:
INetFwRule.Description=“我的規則名”;
啟用規則:
INetFwRule.Enabled=true;
將規則的“行為”設置為“允許”
INetFwRule.Action=NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
設置數據的流動的方向
INetFwRule.Direction=NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
設置協議類型,6代表TCP協議。
INetFwRule.Protocol=6;
設置本地地址,星號”*”代表全部本地地址。
INetFwRule.LocalAddresses=“*”;
設置本地端口,多個端口之間使用逗號分割。
INetFwRule.LocalPorts=“1555”;
設置網絡接口類型,全部。
INetFwRule.InterfaceTypes=“ALL”;
設置允許的某些遠程地址來訪問,各個地址之間使用英文逗號進行分割。
INetFwRule.RemoteAddresses=“10.5.100.29/255.255.255.255,10.5.100.130/255.255.255.255”;
設置遠程端口,星號(“*”)代表全部,或者不限。
INetFwRule.RemotePorts=“*”;
添加規則。這一句需要管理員權限執行,否則會出現異常。解決方法,前文有述。
INetFwPolicy.Rules.Add(INetFwRule);
Windows系統提供了非常簡單易用的圖形化工具來對自身的防火墻進行管理,對于使用者來說,學習難度非常低,很容易上手。但對于需要頻繁改動、或大量改動來說,圖形化界面的工具缺少靈活性。在另一方面,Windows公開了大量的應用程序接口(API),系統管理員使用任意一種腳本語言或者編譯語言即可使用這些API來直接對Windows進行操作和管理,也大大降低了傳統的工作量。
示例項目:您可以訪問網址https://github.com/zmrbak/FireWallAdmin下載本文所述的示例的代碼,稍作修改便可用到你的實際管理工作中,以期簡化您的管理工作。