面向游戏开发人员的 Windows 防火墙

本文介绍 Windows 防火墙 - 它存在的原因、它完成的功能及其实现方式。 最重要的是,它描述如何配置游戏以很好地处理防火墙。

内容:

什么是防火墙?

防火墙提供针对基于网络的入侵的屏障。 它阻止未经请求的传入流量,并通过拒绝 Internet 控制消息协议(ICMP)请求使系统在 Internet 上大部分不可见。 这意味着 ping 和 tracert 将不起作用。 防火墙还会查找并拒绝无效数据包。

此屏障可防止机会攻击。 通过发现许多具有相同漏洞的系统来传播攻击。 防火墙可以通过为当前未使用的功能设置“请勿打扰”标志来挫败许多攻击;攻击被忽视,不会袭击回家。 Windows 防火墙的基本优势是,未使用的功能和应用程序不能成为攻击途径。

用户将系统配置为确定需要哪些应用程序和功能,并且应向网络开放。 在安装应用程序或尝试向网络打开自身时,都会发生这种情况。

如何判断我的游戏是否受到影响?

随着 Windows XP SP2 的到来,已广泛部署 Windows 防火墙。 所有多人游戏 Windows 游戏都会受到某种程度的影响。 虽然客户端通常形状良好,但对等服务器、主机和对等方都需要配置防火墙才能继续工作。 具体而言,传入的未经请求的流量将被删除。 防火墙根据数据包内容和最近的网络活动截获网络流量筛选器数据包。 防火墙使用内容和活动来决定转发或删除数据包。 正确配置防火墙后,游戏将能够像以前一样接受入站未经请求的流量。

谁有入站未经请求的流量?

  • 客户端/服务器:所有参与者都连接到中央服务器。 中央服务器是传入未请求流量的服务器。 连接到服务器的客户端正在请求返回流量,这是预期的,如果遵循客户端的规则,则允许通过防火墙。 必须将中央服务器配置为接受未经请求的流量,以允许客户端流量通过防火墙。
  • 大规模多人游戏(MMP):所有参与者都连接到数据中心。 这相当于复杂的客户端/服务器关系,因为数据中心有入站未经请求的流量。 参与者是客户端,通常不需要接受未经请求的流量。
  • 对等,其中所有参与者都直接连接到对方:所有参与者必须准备好接受来自加入组的任何新玩家的未经请求的流量。 从某种意义上说,每个参与者都必须充当主机,因此它们必须全部配置为主机。

客户端通常处于良好状态。 其传出传输控制协议/Internet 协议(TCP/IP)连接将正常工作,传出用户数据报协议(UDP)消息以及对这些消息的及时响应 -防火墙在每次传出消息预计回复后保持端口打开 90 秒。

Windows XP SP2 之前的防火墙

Windows XP 和 Windows Server 2003 中的 Internet 连接防火墙(ICF)是有状态数据包筛选器,处理 Internet 协议、版本 4(IPv4)和 Internet 协议版本 6(IPv6)。 但是,它默认不启用,不支持第三方网络堆栈,其中世界上有很多,如大型互联网提供商,包括国家电话公司。

对于不在 Windows XP SP2 上的用户,强烈建议启用 ICF。 Internet 连接防火墙(ICF)提供端口映射来替代数据包筛选器。 实质上,指定要打开的端口,并且它保持打开状态,直到关闭它。 如果用户在关闭之前重新启动,它将保持打开状态,直到专门关闭。 通过 INetSharingManager(IPv4)和 INetFwV6Mgr(IPv6)来控制防火墙和管理端口映射。

适用于 Windows XP SP2 的 Windows 防火墙是一种更全面的解决方案,它支持第三方网络堆栈,并更智能地处理端口:只要需要端口的应用程序仍然处于活动状态,端口才会保持打开状态。

Windows XP SP2 防火墙更好

Windows XP SP2 将安全选项和设置放在前面。 目标是默认保护,并允许用户做出有关允许在其计算机上运行的应用程序的明智选择。

新的 Windows 防火墙在 Windows XP SP2 和 Windows Server 2003 Service Pack 1(SP1)上都可用。 与 ICF 一样,它是支持 IPv4 和 IPv6 的软件防火墙,但与 ICF 不同的是 Windows 防火墙:

  • 对系统具有启动时间保护,在启动期间消除一个小漏洞窗口。
  • 支持第三方网络堆栈。
  • 具有“无例外”模式,阻止所有未经请求的传入数据包。 当你使用公用网络(例如在机场或咖啡店)时,这很好。

在“无例外”模式下,所有静态漏洞均已关闭。 允许打开静态洞的 API 调用,但延迟;也就是说,在防火墙切换回正常作之前,不会应用它们。 应用程序的所有侦听请求也将被忽略。 出站连接仍将成功。

对于新应用程序,请在安装过程中将应用程序添加到“异常列表”。 可以使用 INetFwAuthorizedApplications 接口添加应用程序,并提供完整路径。 我们将介绍示例中的详细信息。

作为一个旁注,你可能想知道应用程序是否可以在例外列表中添加和删除应用程序的安全风险,或者你可能认为更大的风险是应用程序可以完全禁用防火墙。 若要执行这些壮举,应用程序必须具有管理员权限。 如果你的系统上以管理员模式运行恶意代码,游戏已经结束,黑客已经获胜。 黑客禁用防火墙的能力将比脚注更值得一点。

旧版应用程序(包括用户升级到 Windows XP SP2 之前安装的应用程序)会处理异常列表弹出窗口(请参阅图 1)。 此对话框显示当应用程序尝试为传入流量打开端口时( 调用 bind() 和 UDP 的非零端口时,或为 TCP/IP 协议调用 accept()。 你必须以管理员身份运行以“取消阻止”应用程序,而“稍后询问”则不允许这次访问,但下次会再次询问。

这是一个非阻塞的系统模式对话框。 运行全屏Microsoft Direct3D 应用程序时,对话框位于下方;然后,当应用程序退出全屏模式或替换选项卡回到桌面时,用户可以处理它。 但是,对于用户来说,当游戏全屏运行时,此对话框似乎并不明显,因此请务必避免使用 INetFwAuthorizedApplications 界面显示此对话框,如下所示。

图 1. 异常列表弹出对话框

异常列表弹出对话框

你会注意到弹出窗口知道应用程序的名称和发布者。 这里没有魔术 - 它从可执行文件的版本信息中提取。 此信息是重要的系统管理工具;它甚至用于正在进行的应用程序兼容性工作。 某些应用程序忽略了 up-to-date 保留此版本信息。

用户还可以通过用户界面(UI)添加其应用程序(请参阅图 2)

图 2. 配置防火墙

配置防火墙

图 3. 将程序添加到防火墙例外列表

将程序添加到防火墙例外列表

最佳方案是自动从异常列表中添加和删除。 执行这些添加和删除的最佳时间是在安装和卸载过程中。 添加或删除防火墙例外列表需要管理员权限,因此请务必考虑到这一点。

使用 Windows 防火墙

同样,大多数游戏只需添加到防火墙例外列表中,如果他们可以充当服务器,或者它们实现对等通信协议。 FirewallInstallHelper.dll 是从安装程序调用的示例 DLL。 如果要将源直接集成到自己的应用程序中,则提供源。 可在此处找到示例:

文件
来源: (SDK root)\Samples\C++\Misc\FirewallInstallHelper
可执行文件: (SDK root)\Samples\C++\Misc\Bin\<arch>\FirewallInstallHelper.dll

 

此 DLL 导出的函数如下:

AddApplicationToExceptionListW

此函数将应用程序添加到异常列表。 它采用可执行文件的完整路径,以及将在防火墙例外列表中显示的友好名称。 此函数需要管理员权限。

AddApplicationToExceptionListA

AddApplicationToExceptionListW 的 ANSI 版本

RemoveApplicationFromExceptionListW

此函数从异常列表中删除应用程序。 它采用可执行文件的完整路径。 此函数需要管理员权限

RemoveApplicationFromExceptionListA

RemoveApplicationFromExceptionListW 的 ANSI 版本

CanLaunchMultiplayerGameW

此函数报告应用程序是否已禁用或删除异常列表。 每次运行游戏时都应调用它。 该函数采用可执行文件的完整路径。 此函数不需要管理员权限。

CanLaunchMultiplayerGameA

CanLaunchMultiplayerGameW 的 ANSI 版本

SetMSIFirewallProperties

仅当在 Windows Installer 中使用自定义作时调用此功能。 有关详细信息,请参阅下文。

AddToExceptionListUsingMSI

仅当在 Windows Installer 中使用自定义作时调用此功能。 有关详细信息,请参阅下文。

RemoveFromExceptionListUsingMSI

仅当在 Windows Installer 中使用自定义作时调用此功能。 有关详细信息,请参阅下文。

以下部分介绍了从 InstallShield、Wise 或 Windows Installer 包中从此 FirewallInstallHelper 调用导出的 DLL 函数的特定方法。 所有方法都呈现相同的结果,由开发人员确定要实现的方法。

使用 InstallShield InstallScript 集成

使用防火墙 API 的替代方法是将函数调用添加到 InstallShield InstallScript。 集成所需的步骤非常简单:

  1. 在 InstallShield 编辑器中打开 InstallScript 项目。

  2. 将 FirewallInstallHelper.dll 作为支持文件添加到项目。

    1. 在“项目助手”选项卡下,打开“应用程序文件”选项卡。
    2. 单击“添加文件”按钮,将文件添加到应用程序目标文件夹。
    3. 浏览到已生成或使用 DirectX SDK 中提供的 FirewallInstallHelper.dll,并将其添加到项目中。
  3. 将 InstallScript 添加到项目。

    1. 打开“安装设计器”视图,然后单击“行为和逻辑” |InstallScript
    2. 单击 InstallScript 文件(通常为 setup.rul),在编辑器中将其打开
    3. 将以下代码粘贴到 InstallScript 文件中:
    #include "ifx.h"
    
    prototype BOOL FirewallInstallHelper.AddApplicationToExceptionListW( WSTRING, WSTRING );
    prototype BOOL FirewallInstallHelper.RemoveApplicationFromExceptionListW( WSTRING );
    
    function OnMoved()
        WSTRING path[256];
    begin
        // The DLL has been installed into the TARGETDIR
        if !MAINTENANCE then // TRUE when installing
            UseDLL( TARGETDIR ^ "FirewallInstallHelper.dll" );
            path = TARGETDIR ^ "TODO: change to relative path to executable from install directory";
            FirewallInstallHelper.AddApplicationToExceptionListW( path, "TODO: change to friendly app name" );
            UnUseDLL( TARGETDIR ^ "FirewallInstallHelper.dll" );
        endif;
    end;
    
    
    function OnMoving()
        WSTRING path[256];
    begin
        // The DLL is about to be removed from TARGETDIR
        if MAINTENANCE && UNINST != "" then // TRUE when uninstalling
            UseDLL( TARGETDIR ^ "FirewallInstallHelper.dll" );
            path = TARGETDIR ^ "TODO: change to relative path to executable from install directory";
            FirewallInstallHelper.RemoveApplicationFromExceptionListW( path );
            UnUseDLL( TARGETDIR ^ "FirewallInstallHelper.dll" );
        endif;
    end;
    
    1. 使用防火墙例外列表中显示的应用程序名称以及相对于安装目录的游戏可执行文件的路径更改 TODO 注释。

集成到适用于 Windows Installer 的 Wise

若要与 Wise for Windows Installer 集成,必须执行以下步骤:

  1. 打开你的 Wise for Windows Installer 项目。

  2. 选择底部的“安装专家”选项卡。

  3. 单击“文件”,将 DXSDK 中的 FirewallInstallHelper.dll 添加到游戏的安装目录。

  4. 选择底部的“MSI 脚本”选项卡。

  5. 选择底部附近的“立即执行”选项卡。

  6. 在 CostFinalize 之后,添加一个“Set Property”作,该作将 FULLPATH 设置为“[INSTALLDIR]从安装目录到可执行文件的相对路径”。 例如,不带引号的“[INSTALLDIR]game.exe”

  7. 选择底部附近的“执行延迟”选项卡。

  8. PublishProduct 后,添加条件为“NOT Installed”的“If 语句”(区分大小写)。

  9. 在 If 块中,添加“从目标调用自定义 DLL”作。

    1. 将 DLL 文件字段设置为“[INSTALLDIR]FirewallInstallHelper.dll”。
    2. 将“函数名称”字段设置为“AddApplicationToExceptionListA”。
    3. 添加类型为“string pointer”、值源“Property”和属性名称“FULLPATH”的参数。
    4. 添加类型为“字符串指针”、值源“Constant”的第二个参数,并将常量值设置为要在防火墙例外列表中显示的友好应用程序名称。
    5. 通过添加“End 语句”关闭 If 块。
  10. 就在顶部附近的 RemoveFiles作上方,添加另一个 If 块,条件为“REMOVE~=”ALL“(区分大小写且不包含外部引号)。

  11. 在第二个 If 块中,添加“从目标调用自定义 DLL”作。

    1. 将 DLL 文件字段设置为“[INSTALLDIR]FirewallInstallHelper.dll”。
    2. 将函数名称字段设置为“RemoveApplicationFromExceptionListA”。
    3. 添加类型为“string pointer”、值源“Property”和属性名称“FULLPATH”的参数。
    4. 通过添加“End 语句”关闭第二个 If 块。

集成到 Windows Installer 中

若要在高级别与 Windows Installer 集成,必须完成这些步骤。 下面将详细介绍它们:

  • 添加 2 个属性“FriendlyNameForFirewall”和“RelativePathToExeForFirewall”,如下所示。
  • 在 CostFinalize作之后,立即在自定义作中调用“SetMSIFirewallProperties”,为其他自定义作设置相应的 MSI 属性。
  • 在 InstallFiles作之后安装期间,调用使用 FirewallInstallHelper 的“AddToExceptionListUsingMSI”函数的延迟自定义作。
  • 在 InstallFiles作后卸载期间,调用使用 FirewallInstallHelper 的“RemoveFromExceptionListUsingMSI”函数的延迟自定义作。
  • 在回滚期间,调用延迟的自定义作,该作还调用 FirewallInstallHelper 的“RemoveFromExceptionListUsingMSI”函数。

以下是使用在平台 SDK 中找到的 MSI 编辑器(如 Orca)执行此作所需的步骤。 请注意,某些编辑器具有简化这些步骤的向导:

  1. 在 Orca 中打开 MSI 包。

  2. 将以下内容添加到 Binary 表:

    名字 数据
    防火墙 指向 FirewallInstallHelper.dll。 此文件将嵌入 MSI 包中,因此每次重新编译 FirewallInstallHelper.dll时都必须执行此步骤。

     

  3. 将以下内容添加到 CustomAction 表:

    行动 类型 目标
    FirewallSetMSIProperties msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData + msidbCustomActionTypeContinue = 65 防火墙 SetMSIFirewallProperties
    FirewallAdd msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData + msidbCustomActionTypeContinue + msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate = 3137 防火墙 AddToExceptionListUsingMSI
    FirewallRemove msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData + msidbCustomActionTypeContinue + msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate = 3137 防火墙 RemoveFromExceptionListUsingMSI
    FirewallRollBackAdd msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData + msidbCustomActionTypeContinue + msidbCustomActionTypeRollback + msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate = 3393 防火墙 RemoveFromExceptionListUsingMSI
    FirewallRollBackRemove msidbCustomActionTypeDll + msidbCustomActionTypeBinaryData + msidbCustomActionTypeContinue + msidbCustomActionTypeRollback + msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate = 3393 防火墙 AddToExceptionListUsingMSI

     

  4. 将以下内容添加到 InstallExecuteSequence 表:

    行动 条件 序列 笔记
    FirewallSetMSIProperties 1010 这在 CostFinalize 之后不久就位了。
    FirewallAdd 未安装 4021 此自定义作仅在全新安装期间发生。 序列号将作放在 InstallFiles 之后和回滚之后。
    FirewallRollBackAdd 未安装 4020 仅当取消全新安装时,才会执行此自定义作。 序列号将作放在 InstallFiles 之后和添加自定义作之前。
    FirewallRemove 安装 3461 此自定义作仅在卸载期间发生。 序列号将作直接置于 RemoveFiles 和回滚之后。
    FirewallRollBackRemove 未安装 3460 仅当取消卸载时,才会执行此自定义作。 序列号将作直接放在 RemoveFiles 和 Remove 自定义作之前。

     

  5. 将以下内容添加到 Property 表:

    财产 价值
    FriendlyNameForFirewall 需要是异常列表将显示的名称。 例如,“示例游戏”
    RelativePathToExeForFirewall 需要是游戏的已安装可执行文件。 例如,“ExampleGame.exe”

     

有关 Windows Installer 的详细信息,请参阅 Windows Installer

建议

防火墙在此处保留。 这些建议将为客户提供良好的 Windows 游戏防火墙体验:

  • 不要告诉用户禁用防火墙来玩游戏。 这使得整个计算机易受攻击,即使它们没有玩游戏。
  • 让用户无缝地配置防火墙。 在安装过程中将应用程序添加到异常列表中,并在安装过程中从异常列表中删除应用程序。
  • 如果多人游戏被防火墙状态阻止,则向用户提供反馈。 例如,如果网络功能因应用程序被禁止或系统处于“无例外”模式而不起作用,则禁用网络功能。