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

Linux下如何配置Python L2层Socket阻止捕获数据包进入网络

Linux下L2层拦截并阻止数据包传输的解决方案

先澄清混杂模式的误区

混杂模式仅用于让网卡接收所有经过的以太网帧(包括目标MAC不是本机的帧),它没有阻止数据包传输的功能——内核依然会正常处理这些捕获到的包,将其递交给上层协议栈或转发至网络。你的问题核心是需要拦截并丢弃数据包,而非单纯捕获。


推荐方案:结合iptables与NetfilterQueue精准拦截

NetfilterQueue可以让你介入Linux内核的数据包处理流程,捕获指定规则的数据包并决定是否放行/丢弃/修改,是实现L2层拦截阻断的可靠方式。

步骤1:安装依赖

# 安装系统库
sudo apt install libnetfilter-queue-dev python3-pip
# 安装Python绑定库
pip3 install netfilterqueue

步骤2:配置iptables规则

将目标数据包导向Netfilter队列(示例为拦截进入eth0的所有IPv4数据包):

sudo iptables -A INPUT -i eth0 -j NFQUEUE --queue-num 1

如果需要拦截转发的数据包,可添加:

sudo iptables -A FORWARD -i eth0 -j NFQUEUE --queue-num 1

步骤3:Python拦截代码

通过NetfilterQueue捕获数据包并丢弃(阻止进入网络):

from netfilterqueue import NetfilterQueue
import scapy.all as scapy

def handle_packet(packet):
    # 解析数据包(可选,用于判断是否需要阻断)
    scapy_pkt = scapy.IP(packet.get_payload())
    print(f"捕获到数据包: {scapy_pkt.summary()}")
    
    # 丢弃数据包,阻止其进入网络
    packet.drop()
    # 若需放行特定包,替换为 packet.accept()

if __name__ == "__main__":
    nfqueue = NetfilterQueue()
    # 绑定到队列号1,与iptables规则对应
    nfqueue.bind(1, handle_packet)
    
    try:
        print("开始拦截数据包...按Ctrl+C停止")
        nfqueue.run()
    except KeyboardInterrupt:
        print("\n停止拦截")
    finally:
        nfqueue.unbind()
        # 可选:清空iptables规则
        # import subprocess
        # subprocess.run(["sudo", "iptables", "-F"])

注意:需以sudo权限运行代码,因为操作Netfilter和iptables需要管理员权限。


替代方案:关闭网卡转发(粗暴阻断)

如果仅需整体阻止网卡转发数据包,可直接关闭系统转发功能:

# 临时关闭IPv4转发
sudo sysctl -w net.ipv4.ip_forward=0
# 永久关闭(需重启生效)
echo "net.ipv4.ip_forward=0" | sudo tee -a /etc/sysctl.conf

这种方式适合全局阻断,但无法精准控制单个数据包的放行/丢弃。


修正你的混杂模式配置(若仍需捕获更多数据包)

如果需要保留混杂模式以捕获非本机目标的数据包,可使用更简洁的fcntl实现:

import fcntl
import socket

def toggle_promiscuous(iface, enable=True):
    SIOCGIFFLAGS = 0x8913
    SIOCSIFFLAGS = 0x8914
    IFF_PROMISC = 0x100

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 构造ifreq结构体数据
    ifr = iface.encode() + b'\x00' * (16 - len(iface))
    # 获取当前网卡标志
    flags = fcntl.ioctl(sock.fileno(), SIOCGIFFLAGS, ifr)[16:18]
    current_flags = int.from_bytes(flags, byteorder='little')
    
    if enable:
        new_flags = current_flags | IFF_PROMISC
    else:
        new_flags = current_flags & ~IFF_PROMISC
    
    # 设置新的网卡标志
    ifr = iface.encode() + b'\x00'*(16 - len(iface)) + new_flags.to_bytes(2, byteorder='little')
    fcntl.ioctl(sock.fileno(), SIOCSIFFLAGS, ifr)
    sock.close()

# 开启eth0的混杂模式
toggle_promiscuous("eth0")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:43:12