一、项目背景详细介绍

在 Windows 系统中,防火墙(Windows Defender Firewall) 是一项关键安全机制,用于阻止未经授权的程序访问网络,从而保护系统免受外部攻击。

但是,在实际开发中,我们的程序往往需要访问网络。例如:

  • 客户端程序要访问服务器;

  • 工控设备监控软件需要通信;

  • 内部系统管理工具需要远程连接;

  • 程序更新模块要访问网络。

如果应用程序未加入防火墙允许列表(白名单),系统可能会自动阻止该程序的网络请求,或者在首次启动时弹出防火墙确认窗口。

为了提升用户体验和自动化部署,我们希望程序在首次运行时自动将自己添加到防火墙白名单中,从而:

  • 允许出站(Outbound)和入站(Inbound)通信;

  • 避免用户手动点击确认;

  • 提高自动化安装体验;

  • 支持企业批量部署和无人值守安装。

因此,本项目旨在讲解如何在 VC++ 程序中调用 Windows 防火墙 API 或命令行接口(netsh / COM 接口),自动添加应用程序至防火墙允许列表。


二、项目需求详细介绍

1. 功能性需求

  • 程序启动后自动检测自己是否在防火墙白名单;

  • 若不在,则自动添加;

  • 支持入站、出站规则;

  • 支持自定义程序路径和名称;

  • 可删除旧规则并重新添加。

2. 技术性需求

  • 使用 VC++(Win32 桌面应用);

  • 支持 Windows 10/11;

  • 使用防火墙 COM 接口(推荐);

  • 若 COM 接口不可用,可退回使用 netsh 命令方式;

  • 必须以管理员权限运行。

3. 安全性要求

  • 程序仅能修改自身防火墙策略;

  • 禁止修改系统全局配置;

  • 需检测添加是否成功。

4. 用户体验

  • 若添加失败,提示用户以管理员身份重新运行;

  • 操作过程静默执行,不弹出黑窗。


三、相关技术详细介绍

1. Windows 防火墙工作原理

Windows 防火墙通过系统服务(MpsSvc)和安全策略存储(INetFwPolicy2)管理应用的网络访问。
规则通常分为两类:

  • 入站规则 (Inbound Rules):控制外部访问本程序;

  • 出站规则 (Outbound Rules):控制本程序访问外部网络。

每个规则定义了以下信息:

  • 程序路径;

  • 协议类型(TCP/UDP/All);

  • 端口号;

  • 方向(Inbound/Outbound);

  • 操作(Allow/Deny)。

2. 防火墙 COM 接口简介

Windows 提供了 COM 接口来编程控制防火墙设置:

  • 头文件:netfw.h

  • 库文件:ole32.lib、oleaut32.lib

  • 主接口:INetFwPolicy2

  • 规则对象接口:INetFwRule

这套接口允许我们在代码中创建规则对象,然后调用 Add() 方法添加到策略中。

3. 另一种方式:调用 netsh 命令

如果 COM 接口使用不便,也可以直接在程序中调用命令行:


netsh advfirewall firewall add rule name="MyApp" dir=in action=allow program="C:\MyApp.exe" enable=yes

不过这种方式依赖命令解释器(cmd.exe),稍显笨重。推荐优先使用 COM 接口方式。


四、实现思路详细介绍

  1. 初始化 COM 环境

    • 调用 CoInitializeEx();

    • 以单线程模式初始化 COM。

  2. 创建防火墙策略对象

    • 使用 CoCreateInstance() 创建 INetFwPolicy2 实例;

    • 用于访问系统防火墙配置。

  3. 创建规则对象

    • 使用 CoCreateInstance() 创建 INetFwRule 实例;

    • 设置规则名称、描述、程序路径、方向、操作等属性。

  4. 将规则添加到策略

    • 调用 INetFwPolicy2::Rules->Add();

    • 若已存在同名规则,先删除再添加。

  5. 退出 COM

    • 调用 CoUninitialize() 释放资源。

  6. 可选扩展

    • 检测是否已存在规则;

    • 支持删除规则;

    • 支持命令行参数控制。


五、完整实现代码

/**************************************************************
 * 文件名: FirewallAddWhiteList.cpp
 * 功能: 在 Windows 防火墙中添加应用程序白名单
 * 作者: ChatGPT 教学版
 * 环境: Visual Studio 2019 / 2022
 * 平台: Windows 10 / 11
 * 编译标准: C++17
 **************************************************************/

#include <windows.h>
#include <netfw.h>
#include <comutil.h>
#include <iostream>

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

using namespace std;

/**
 * 功能:添加应用程序到防火墙白名单
 * 参数:
 *   ruleName  - 规则名称
 *   exePath   - 程序完整路径
 *   description - 规则描述
 * 返回:
 *   true 表示成功,false 表示失败
 */
bool AddAppToFirewall(const wstring& ruleName, const wstring& exePath, const wstring& description)
{
    HRESULT hr = S_OK;
    INetFwPolicy2* pNetFwPolicy2 = nullptr;
    INetFwRules* pFwRules = nullptr;
    INetFwRule* pFwRule = nullptr;

    // 初始化 COM
    hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        wcerr << L"COM 初始化失败: " << hex << hr << endl;
        return false;
    }

    do {
        // 创建防火墙策略对象
        hr = CoCreateInstance(__uuidof(NetFwPolicy2), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2), (void**)&pNetFwPolicy2);
        if (FAILED(hr)) break;

        // 获取规则集合
        hr = pNetFwPolicy2->get_Rules(&pFwRules);
        if (FAILED(hr)) break;

        // 创建规则对象
        hr = CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule);
        if (FAILED(hr)) break;

        // 设置规则属性
        pFwRule->put_Name(_bstr_t(ruleName.c_str()));
        pFwRule->put_Description(_bstr_t(description.c_str()));
        pFwRule->put_ApplicationName(_bstr_t(exePath.c_str()));
        pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
        pFwRule->put_Direction(NET_FW_RULE_DIR_IN);
        pFwRule->put_Action(NET_FW_ACTION_ALLOW);
        pFwRule->put_Enabled(VARIANT_TRUE);

        // 添加规则
        hr = pFwRules->Add(pFwRule);
        if (FAILED(hr)) break;

        wcout << L"成功添加防火墙白名单规则: " << ruleName << endl;
    } while (false);

    // 释放资源
    if (pFwRule) pFwRule->Release();
    if (pFwRules) pFwRules->Release();
    if (pNetFwPolicy2) pNetFwPolicy2->Release();

    CoUninitialize();

    if (FAILED(hr)) {
        wcerr << L"添加防火墙规则失败,错误码: " << hex << hr << endl;
        return false;
    }

    return true;
}

/**
 * 主函数
 */
int wmain()
{
    wchar_t path[MAX_PATH] = { 0 };
    GetModuleFileNameW(NULL, path, MAX_PATH);  // 获取当前程序路径

    wstring exePath = path;
    wstring ruleName = L"MyFirewallTest";
    wstring description = L"允许程序访问网络";

    bool success = AddAppToFirewall(ruleName, exePath, description);
    if (success)
        wcout << L"白名单添加成功!" << endl;
    else
        wcout << L"白名单添加失败,请以管理员身份运行程序!" << endl;

    return 0;
}

六、代码详细解读

  1. AddAppToFirewall()

    • 初始化 COM;

    • 创建 INetFwPolicy2 实例;

    • 通过 get_Rules() 获取规则集合;

    • 创建 INetFwRule 对象;

    • 设置名称、描述、程序路径、协议、方向等;

    • 调用 Add() 将规则加入系统策略;

    • 释放所有 COM 对象并返回结果。

  2. wmain()

    • 获取当前程序路径;

    • 设置规则名称与描述;

    • 调用 AddAppToFirewall();

    • 打印结果。


七、项目详细总结

本项目实现了一个完整的 Windows 防火墙白名单自动注册流程。
核心思想是:

  • 通过 COM 接口访问系统防火墙策略;

  • 构建并注册新的入站规则;

  • 程序自我添加白名单,自动允许通信。

优点:

  • 无需外部命令;

  • 执行静默、稳定;

  • 权限安全;

  • 支持多版本 Windows。

该机制广泛用于:

  • 自动更新系统;

  • 网络控制类软件;

  • 远程控制端;

  • 游戏防封端通信允许。


八、项目常见问题及解答

Q1:程序运行提示权限不足?
A:必须以管理员权限运行,否则 COM 接口会被拒绝访问。

Q2:如何添加出站规则?
A:修改代码:


pFwRule->put_Direction(NET_FW_RULE_DIR_OUT);

Q3:如何删除规则?
A:


pFwRules->Remove(_bstr_t(ruleName.c_str()));

Q4:是否支持 TCP/UDP 端口控制?
A:可以添加:


pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP); pFwRule->put_LocalPorts(_bstr_t(L"8080"));

Q5:是否能检测规则是否已存在?
A:可遍历 pFwRules 集合或调用 Item() 方法检查。


九、扩展方向与性能优化

  1. 检测规则是否存在

    • 若存在则跳过添加;

    • 防止重复注册。

  2. 支持批量程序添加

    • 从配置文件读取多个程序路径;

    • 循环注册规则。

  3. 日志与回滚机制

    • 添加成功后记录日志;

    • 程序卸载时删除相应规则。

  4. UI可视化版本

    • 用 MFC 或 Qt 显示当前防火墙状态;

    • 允许用户一键授权。

  5. 兼容 Windows Server

    • 支持 Server 2016 / 2019 / 2022;

    • 检查防火墙服务状态。

更多推荐