You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win10下如何通过Python临时拦截发往指定IP的UDP数据包

Windows 10 下Python临时拦截指定目标IP出站UDP包方案

所有方案均要求脚本以管理员身份运行,否则会因权限不足完全失效。


方案1:调用系统防火墙实现拦截(零依赖、最稳定)

这个方案直接调用Windows自带的高级防火墙API添加临时出站拦截规则,拦截动作在内核层完成,不会漏包,不需要安装任何第三方工具或驱动,适合只需要按IP/端口维度拦截、不需要解析包内容的场景。
拦截结束后脚本会自动清理防火墙规则,不会在系统里残留配置。

import subprocess
import atexit

# 按需修改配置
TARGET_IP = "192.168.3.45"  # 替换为你要拦截的目标IP
BLOCK_RULE_NAME = "Python_Temp_UDP_Block"
# 如果需要指定拦截端口,把下面的PORT配置改成对应端口,不需要就设为None
TARGET_PORT = None

def clean_firewall_rule():
    """退出时自动删除临时防火墙规则"""
    subprocess.run(
        ["netsh", "advfirewall", "firewall", "delete", "rule", f"name={BLOCK_RULE_NAME}"],
        capture_output=True,
        shell=True
    )

def start_block():
    """添加拦截规则"""
    rule_params = [
        "netsh", "advfirewall", "firewall", "add", "rule",
        f"name={BLOCK_RULE_NAME}",
        "dir=out",
        "action=block",
        "protocol=UDP",
        f"remoteip={TARGET_IP}",
        "enable=yes"
    ]
    if TARGET_PORT:
        rule_params.append(f"remoteport={TARGET_PORT}")
    
    res = subprocess.run(rule_params, capture_output=True, text=True, shell=True)
    if res.returncode != 0:
        raise PermissionError("规则添加失败,请确认脚本以管理员身份运行")
    atexit.register(clean_firewall_rule)
    print(f"已开启拦截:所有发往{TARGET_IP}的UDP出站包将被丢弃,按Ctrl+C停止拦截")

if __name__ == "__main__":
    try:
        start_block()
        while True:
            # 这里可以插入你的业务逻辑,比如满足特定条件后break结束拦截
            input()
    except KeyboardInterrupt:
        pass
    finally:
        clean_firewall_rule()
        print("拦截已停止,防火墙规则已清理")

方案2:基于WinDivert实现自定义规则拦截(支持包内容解析)

如果你需要根据UDP包的载荷内容、包特征做细粒度拦截(比如只拦截包含特定字符串的包,其余正常放行),可以用pydivert库封装的WinDivert驱动实现用户态透明拦截,支持拦截、修改、放行任意匹配的网络包。
先安装依赖:
pip install pydivert
示例代码:

import pydivert

# 按需修改配置
TARGET_IP = "192.168.3.45"  # 替换为目标IP
TARGET_PORT = None  # 需要指定端口就填对应数字,否则留None

def start_custom_block():
    # 构造过滤规则,语法和Wireshark过滤规则接近
    filter_rule = f"udp and ip.DstAddr == {TARGET_IP}"
    if TARGET_PORT:
        filter_rule += f" and udp.DstPort == {TARGET_PORT}"
    
    try:
        with pydivert.WinDivert(filter_rule) as handle:
            print(f"自定义拦截已开启,将检查所有发往{TARGET_IP}的UDP包,按Ctrl+C停止")
            for packet in handle:
                # 在这里写你的自定义拦截逻辑
                # 示例:拦截payload包含b"forbid"关键字的包,其余放行
                if b"forbid" in packet.payload:
                    print(f"拦截到违规包,长度{len(packet.payload)}字节,已丢弃")
                    # 不调用send方法就是直接丢弃包
                    continue
                # 不符合拦截条件的包正常放行
                handle.send(packet)
    except RuntimeError:
        raise PermissionError("驱动加载失败,请确认脚本以管理员身份运行,且安全软件未拦截驱动加载")

if __name__ == "__main__":
    try:
        start_custom_block()
    except KeyboardInterrupt:
        print("\n拦截已停止")

这个方案第一次运行时会自动释放对应系统版本的WinDivert驱动到临时目录,部分安全软件可能弹出驱动加载提示,选择允许即可正常使用。


避坑说明

  • 不要尝试用原始套接字、Scapy默认嗅探模式实现拦截:这两种方式只能在包已经发出到网卡后抓到副本,无法阻止包发送,本质是“抓包”不是“拦截”。
  • 如果只需要临时拦截固定IP的UDP流量优先选方案1,稳定性最高,不会被安全软件误报,性能损耗几乎为0。
  • 规则配置尽量收窄到具体端口,不要无差别拦截所有发往目标IP的流量,避免影响其他正常业务。

内容的提问来源于stack exchange,提问作者Spring93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:01:20