ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从零搭建发包机:内核调优、脚本编写与容器化压测实践

从零搭建发包机:内核调优、脚本编写与容器化压测实践 简介本资源为DDoS发包机搭建教程与配套脚本合集面向网络安全学习者、运维人员及安全研究人员用于理解分布式拒绝服务攻击的常见类型与实现原理从而辅助防御策略的构建。包内共152个文件涵盖C语言源码、pkt数据包样本、PHP脚本、txt说明文档、md笔记及wmv视频教程等压缩包约50.83MB目录结构按攻击类型与功能模块划分便于对照查阅。内容涉及SYN、UDP、ACK、DNS反射、SSDP放大、NTP、SNMP等多种攻击方式的脚本实现并包含扫描过滤、资源探测与攻击策略相关代码视频教程演示了环境准备与脚本执行流程。目前已有3672人学习下载适合希望系统了解DDoS攻击机制、研究流量特征与防御思路的中高级读者参考建议仅用于合法学习与安全防护研究。1. 发包机搭建到底在搭什么从一台云主机到可复现的压测环境很多人第一次听到「发包机」这个词脑子里浮现的是一台神秘机器插上电就能往目标狂发数据包。实际干过一轮就知道它本质是一台专门用来产生并发送网络请求的云主机或物理机核心诉求是发包速率可控、源端口可管理、结果可观测。你要么用它做压力测试要么用它做协议一致性验证要么用它模拟大量客户端行为。这套教程要解决的就是从零把这样一台机器搭起来配上可复用的脚本让下一次测试不用从头再来。适合谁看手里有云主机、会基本 Linux 命令、想自己掌控压测链路的运维和后端同学。如果你只是想点一下按钮看个 QPS 数字商业压测平台更省事但如果你需要自定义报文、控制发包节奏、把测试脚本纳入 CI那自己搭一台发包机是绕不过去的。下面按「选机器 → 配环境 → 写脚本 → 调参数 → 避坑」的顺序推。2. 选机器与系统发包机的硬件和内核参数怎么定2.1 云主机选型为什么发包机不能只看 CPU 核数发包机的瓶颈通常不在 CPU而在网络带宽和网卡队列。一台 4 核 8G 的机器如果带宽只有 5Mbps发包速率上限就被卡死了。我一般按三个维度选第一是带宽压测目标如果是内网服务选内网带宽大的规格第二是网卡多队列单队列网卡在高 PPS 场景下会先于 CPU 饱和第三才是 CPU因为发包脚本本身的计算量不大除非你要做加密或复杂协议封装。系统层面Ubuntu 22.04 和 Debian 12 是我用得最顺手的内核版本新SO_REUSEPORT和sendmmsg支持完整。CentOS 7 虽然稳但内核 3.10 在高并发发包时缺少一些批量发送的优化不建议新搭环境再用。云主机用什么系统这个问题答案就是选你能最快拿到 root、能改内核参数、能装最新工具链的那个。2.2 内核参数调优让发包不被本机限制拖后腿默认内核参数是为通用场景设计的发包机需要针对性调整。下面这份配置我每次搭新机器都会先刷一遍# 查看当前网卡和队列情况 ip link show ethtool -l eth0 # 临时调整内核参数写入 /etc/sysctl.conf 可持久化 sysctl -w net.core.rmem_max16777216 sysctl -w net.core.wmem_max16777216 sysctl -w net.core.rmem_default262144 sysctl -w net.core.wmem_default262144 sysctl -w net.ipv4.ip_local_port_range1024 65535 sysctl -w net.ipv4.tcp_tw_reuse1 sysctl -w net.core.somaxconn65535 sysctl -w net.ipv4.tcp_max_syn_backlog65535 # 提高网卡队列和 ring buffer ethtool -G eth0 rx 4096 tx 4096 ethtool -L eth0 combined 8逻辑说明rmem/wmem调大是为了让 socket 缓冲区能容纳突发流量避免send调用频繁阻塞ip_local_port_range扩大可用源端口范围因为发包机经常需要大量短连接tcp_tw_reuse让 TIME_WAIT 状态的端口可以复用这对短连接压测是刚需。ethtool -G调整的是网卡环形缓冲区太小会导致丢包太大增加延迟4096 是多数场景的平衡点。参数怎么改如果你的压测是长连接为主tcp_tw_reuse可以不开如果是 UDP 发包重点看net.core.netdev_max_backlog建议调到 65535。改完用sysctl -p生效然后ethtool -S eth0看有没有rx_dropped增长有就继续加 buffer。3. 发包脚本怎么写从 shell 到 Python 的三种落地方式3.1 shell 脚本快速验证用 nc 和 hping3 做最小发包搭好机器后先用最简单的方式验证链路通不通。nc和hping3是两把快刀# 用 nc 发 TCP 包验证目标端口可达 for i in $(seq 1 100); do echo hello-$i | nc -w 1 192.168.1.100 8080 done # 用 hping3 发 SYN 包测目标响应 hping3 -S -p 80 -c 1000 --fast 192.168.1.100 # 用 hping3 发 UDP 包测丢包率 hping3 --udp -p 53 -c 5000 -d 512 --fast 192.168.1.100逻辑说明nc循环发 100 个 TCP 连接每个带 1 秒超时适合验证目标服务是否稳定接受连接。hping3 -S发 SYN 包--fast表示尽快发送-c 1000是发 1000 个。UDP 那条命令发 512 字节载荷用来测 DNS 类服务的丢包情况。参数说明-w 1是 nc 的连接超时压测时别设太大否则卡住不动hping3的--fast等价于每秒发 100 个包要更高频率用--faster或-i u1000每 1000 微秒一个包。这些命令只适合验证不适合长时间高并发因为 shell 循环本身开销大。3.2 Python 脚本用 socket 和 asyncio 控制发包节奏要精细控制发包速率和并发数Python 更合适。下面是一个基于 asyncio 的 TCP 发包脚本import asyncio import time TARGET_HOST 192.168.1.100 TARGET_PORT 8080 CONCURRENCY 500 TOTAL_REQUESTS 10000 PAYLOAD bx * 256 async def send_one(sem, counter): async with sem: try: reader, writer await asyncio.open_connection(TARGET_HOST, TARGET_PORT) writer.write(PAYLOAD) await writer.drain() writer.close() await writer.wait_closed() except Exception as e: pass finally: counter[0] 1 async def main(): sem asyncio.Semaphore(CONCURRENCY) counter [0] start time.time() tasks [send_one(sem, counter) for _ in range(TOTAL_REQUESTS)] await asyncio.gather(*tasks) elapsed time.time() - start print(fsent {counter[0]} requests in {elapsed:.2f}s, frate{counter[0]/elapsed:.0f} req/s) asyncio.run(main())逻辑说明Semaphore控制同时进行的连接数避免一次性创建太多 socket 导致文件描述符耗尽。每个任务建立连接、发送 256 字节、关闭连接。counter记录实际完成数最后算速率。参数说明CONCURRENCY是并发上限500 在 4 核机器上比较稳调到 2000 以上需要先确认ulimit -n够大。TOTAL_REQUESTS是总请求数压测时按目标 QPS 乘以持续时间估算。PAYLOAD大小影响带宽占用256 字节适合模拟 API 请求如果要测大包改成 1400 左右接近 MTU。3.3 脚本参数化把目标地址、并发数、持续时间抽成配置硬编码的脚本没法复用。我习惯把参数抽到命令行或配置文件import argparse import asyncio def parse_args(): p argparse.ArgumentParser() p.add_argument(--host, requiredTrue) p.add_argument(--port, typeint, requiredTrue) p.add_argument(--concurrency, typeint, default500) p.add_argument(--duration, typeint, default60) p.add_argument(--payload-size, typeint, default256) return p.parse_args() async def main(): args parse_args() payload bx * args.payload_size sem asyncio.Semaphore(args.concurrency) stop_at time.time() args.duration # ... 发包循环直到 stop_at逻辑说明用argparse接收参数--duration控制压测持续时间比固定请求数更贴近真实场景。发包循环里每次检查time.time() stop_at到点就停。参数说明--concurrency和--duration是最常调的两个。并发数上不去时先看ulimit -n再看内核somaxconn。持续时间建议先跑 30 秒看趋势再拉长到 5 分钟以上观察稳定性。4. 发包机避坑与排查那些让测试结果失真的细节4.1 源端口耗尽现象是连接失败率突然飙升现象压测跑了几十秒后connect开始大量报Cannot assign requested address。原因短连接场景下每个连接占用一个源端口ip_local_port_range默认只有 28000 个左右加上 TIME_WAIT 回收慢很快就用完了。解决把ip_local_port_range调到1024 65535开启tcp_tw_reuse如果还是不够给目标加多个源 IP 轮询。4.2 网卡丢包现象是发送速率上不去但 CPU 不高现象ethtool -S eth0里tx_dropped持续增长发包速率卡在某个值。原因网卡环形缓冲区太小或者队列数不够单队列处理不过来。解决ethtool -G eth0 tx 4096加大缓冲区ethtool -L eth0 combined 8增加队列数同时确认中断亲和性有没有绑到多个核上。4.3 脚本本身成为瓶颈现象是目标没压力但发包机 CPU 跑满现象目标服务 QPS 很低但发包机 CPU 已经 100%。原因Python 的 GIL 限制了多线程或者脚本里做了太多字符串拼接、日志打印。解决用 asyncio 替代多线程关掉调试日志把 payload 预生成好而不是每次拼接。如果还不够换 Go 或 C 写发包端。4.4 时间同步问题现象是压测报告里的延迟数据对不上现象发包机记录的发送时间和目标记录的接收时间差了几百毫秒。原因发包机和目标机器没有做 NTP 同步或者时区不一致。解决所有参与压测的机器统一用chrony或ntpd同步时间压测前用chronyc sources确认偏移在毫秒级。4.5 云主机带宽限速现象是内网压测正常公网压测速率腰斩现象同一套脚本压内网服务能到 10 万 QPS压公网服务只有 3 万。原因云主机公网带宽有上限或者走了 NAT 网关有额外瓶颈。解决确认云主机的带宽规格压公网时把并发数降到带宽能支撑的范围或者用内网压测加公网小流量验证的方式分开做。5. 进阶技巧用容器化和编排把发包机变成可复用资产5.1 把发包脚本打成 Docker 镜像每次搭新机器都重装环境太慢。我现在的做法是把发包脚本和依赖打成一个镜像FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY send.py . ENTRYPOINT [python, send.py]逻辑说明基础镜像用slim版本减少拉取时间。requirements.txt里只放asyncio相关的依赖实际上标准库就够所以这个文件可以是空的。ENTRYPOINT让容器启动即发包参数通过docker run传入。参数说明--network host是必须的否则容器内的网络栈会多一层 NAT影响发包速率。--ulimit nofile65535:65535也要加上否则容器内文件描述符不够。5.2 用 docker compose 编排多台发包机单台机器压不出目标流量时用 compose 在多个节点上同时跑services: sender: image: my-sender:latest network_mode: host ulimits: nofile: soft: 65535 hard: 65535 command: [--host, 192.168.1.100, --port, 8080, --concurrency, 1000, --duration, 120] deploy: replicas: 4逻辑说明replicas: 4在 swarm 模式下会起 4 个容器每个独立发包。network_mode: host让容器直接用宿主机网络。command里的参数按实际目标改。参数说明replicas数量取决于目标能承受的并发别一上来就拉满。ulimits必须设否则每个容器默认 1024 个文件描述符跑几百并发就报错。5.3 结果验证怎么确认发包机真的发出去了发包机自己说发了多少不算数要在目标侧验证。我一般做三件事第一在目标机器上用ss -s看连接数变化第二用tcpdump抓包抽样确认报文内容正确第三对比目标服务的监控面板看 QPS 和发包机报告是否一致。如果目标侧 QPS 只有发包机报告的一半先查是不是有中间设备限速再查是不是脚本里把失败请求也算进去了。# 目标侧抓包验证 tcpdump -i eth0 -c 100 -w /tmp/capture.pcap host 192.168.1.50 # 发包机侧看连接状态 ss -s ss -tn state established | wc -l逻辑说明tcpdump抓 100 个包存下来用 Wireshark 分析报文是否符合预期。ss -tn state established统计当前建立的连接数和脚本里的并发数对比差太多说明连接没建起来。参数说明-c 100是抓包数量别抓太多否则磁盘和 CPU 都吃不消。host后面跟发包机 IP过滤掉无关流量。这套东西搭下来一台发包机从裸机到能跑可复现的压测大概两小时。我自己的习惯是每换一个项目就把脚本参数改一遍但内核参数和 Docker 镜像不动这样至少保证环境是一致的。踩过的坑里源端口耗尽和网卡丢包是最常见的两个每次搭新机器先查这两项能省不少排查时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表