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、定期更新过滤器

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

相关推荐
这儿有一堆花1 小时前
视频文件的技术逻辑解析
windows·macos
百事牛科技1 小时前
压缩包安全升级:分享WinRAR的两种加密功能
windows·winrar
欧恩意2 小时前
【Viusal Studio】关于增量链接机制
汇编·windows·bug
定_格2 小时前
windows本地启动项目并使用arthas调试
windows
ReaF_star3 小时前
【安防】Windows Server 2008虚拟机忘记密码的一时兴起
网络·windows·安全
山峰哥3 小时前
EcMenu:解锁 Windows 右键菜单的终极自由
windows·性能优化·软件工程·鼠标右键菜单工具
天魔老师4 小时前
WSL2 “system.vhd找不到” 错误修复教程(实测有效)
windows·wsl
要站在顶端4 小时前
Jenkins设备监控(手机、手表)适配Windows、Linux
windows·智能手机·jenkins
Irene19914 小时前
Windows环境下使用Bash命令的解决方案和命令行工具推荐(附:前端开发者 Windows 终端配置清单)
windows·工具推荐·bash命令