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