windows的WFP过滤域名

经过多方的调研,发现,域名过滤其实本质也是IP地址的过滤,我们接着上篇文章来续写WFP过滤域名的方法:其实大致思路是这样的,首选将域名调用本地的DNS解析成IP地址,然后再将IP地址使用上篇文章的方法添加过滤器,但是这个时候有个问题,就是域名对应的IP地址可能会更新可能会变化,怎么办呢?我的初步解决办法是再添加了过滤器后,创建一个定时任务或者说创建一个线程,定时去DNS解析域名,将解析出来的IP地址去更新之前创建的过滤器,即可实现WFP域名过滤的功能。

1、解析域名

我的入参是多个域名的vector,在解析完vector后,再将解析的Ip地址集合以vector的方式返回,简易代码如下:

cpp 复制代码
DWORD FilterFunC::DomainsToIps(const std::vector<std::string>& domains,std::vector<std::string>& ips) {
    DWORD res = ERROR_SUCCESS;
    // 2. 使用 getaddrinfo 解析域名(示例:允许访问 example.com)
    struct addrinfo hints = { 0 };
    hints.ai_family = AF_INET;  // 只支持 IPv4
    hints.ai_socktype = SOCK_STREAM;

    for (auto domain : domains) {
        struct addrinfo* result = NULL;
        res = getaddrinfo(domain.c_str(), NULL, &hints, &result);
        if (res != 0 || result == NULL)
        {   
            domain = "DomainsToIps 域名转换错误:"+domain;
            ERROR_PRINT(domain.c_str(),ERROR_INVALID_FUNCTION);
            continue;
        }
        sockaddr_in* ipv4_addr = (sockaddr_in*)result->ai_addr;
        uint32_t ip = ipv4_addr->sin_addr.S_un.S_addr; // 网络字节序IP地址
        std::string ipStr = Uint32ToIpStr(ntohl(ip));   
        ips.push_back(ipStr);
    }
    return res;
}

要使用getaddrinfo函数进行转换,需要包含以下头文件

#include <winsock2.h>

#include <ws2tcpip.h>

2、添加过滤器

可以看到上面的输出已经是ip地址的vector数组了,然后使用此数组,去创建多IP的过滤器即可:

cpp 复制代码
DWORD FilterFunC::AddWFPFilterArray(HANDLE engineHandle, const std::vector<std::string>& ipAddresses,GUID filterKeyDef) {
    DWORD result = ERROR_SUCCESS;
    FWPM_FILTER0 filter = {};
    //filter.providerKey = outProviderGUID;
    filter.displayData.name = const_cast<wchar_t*>(L"IP Whitelist");
    filter.displayData.description = const_cast<wchar_t*>(L"Block traffic to Ips");
    filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4; // IPv4包层
    filter.weight.type = FWP_EMPTY; // 默认权重
    filter.action.type = FWP_ACTION_PERMIT; // 允许,白名单
    filter.numFilterConditions = ipAddresses.size();
    filter.filterKey = filterKeyDef;

    FWPM_FILTER_CONDITION0 condition[ipAddresses.size()];
    // Initialize conditions for each IP address
    for (size_t i = 0; i < ipAddresses.size(); ++i) {
        condition[i].fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS;
        condition[i].matchType = FWP_MATCH_EQUAL;
        condition[i].conditionValue.type = FWP_UINT32;
        
        // Convert IP address string to DWORD
        unsigned long ipAddress = inet_addr(ipAddresses[i].c_str());
        if (ipAddress == INADDR_NONE) {
            std::cerr << "Invalid IP address: " << ipAddresses[i] << std::endl;
            return ERROR_INVALID_DATA;
        }
        condition[i].conditionValue.uint32 = htonl(ipAddress);
    }
    filter.filterCondition = condition;

    result = FwpmTransactionBegin0(engineHandle, 0); // 0 - 读写事务
    if (result != ERROR_SUCCESS) {
        // 错误处理
        ERROR_PRINT("FwpmTransactionBegin0 failed", result);
        return 1;
    }
    result = FwpmFilterAdd0(engineHandle, &filter, NULL, NULL);
    if (result != ERROR_SUCCESS) {
        ERROR_PRINT("FwpmFilterAdd0 failed", result);
        FwpmTransactionAbort0(engineHandle);
    } else {
        SUCCESS_PRINT("Filter added successfully. Traffic to is blocked.");
        FwpmTransactionCommit0(engineHandle);
    }
    return result;
}

这部分的代码和上一篇的文章的代码有些许差别,主要是是否自定义创建filterKey 的区别,上篇文章没有定义filterKey ,使用系统自动分配,这次的功能,将自定义的filterKey 以参数的形式传递进去。此处这样的做法是为了后续定期更新过滤器做准备,因为你需要定期更新过滤器,更新的方法是先删除后创建,删除不能全部删除过滤器,有其他人的设置,所以此处我们自定义一个过滤器的filterKey ,后面删除也通过此filterKey 来进行删除。

3、定期更新过滤器

此处不做详细的代码示例,此处比较简单,要么是在再创建一个进程去定期执行这个事情,要么创建一个进行定期去解析域名,然后更新过滤器。

相关推荐
Curtain_Gin4 小时前
windows nvim lazy
windows
生而为虫6 小时前
Claude Code 最新版安装教程(Windows/Mac/Linux 全平台) 面向普通用户的 Claude Code 安装与模型接入指南
linux·windows·macos
DevilSeagull6 小时前
Windows 批处理 (Batch) 编程: 从入门到入土. (一) 基础概念与环境配置
开发语言·windows·后端·batch·语言
CyL_Cly7 小时前
Parsec(parsec安卓/windows/macos下载)
windows
2601_958320578 小时前
【小白零基础上手 】钉钉内部机器人接入 OpenClaw 完整流程讲解(含安装包)
人工智能·windows·机器人·钉钉·open claw·open claw安装
love530love8 小时前
f2 项目(多平台的作品下载与接口数据处理)源码部署记录
人工智能·windows·f2
生而为虫9 小时前
在VScode中使用Claude Code agent并配置模型(仅mac电脑实际操作,windows电脑未实际操作如有问题可留言)
windows·vscode·macos
叶小鸡9 小时前
Java 篇-项目实战-天机学堂(从0到1)-day10
windows·microsoft
love530love9 小时前
如何在 Google Chrome 中强制开启 Gemini AI 侧边栏(完整图文教程)
前端·人工智能·chrome·windows
skilllite作者9 小时前
Zed 1.0 编辑器深度评测与实战指南
开发语言·人工智能·windows·python·编辑器·agi