Proxmark3(Iceman Fork)Fedora 41 Docker 测试环境实战:构建矩阵、release_tests.sh 与 pm3_tests.sh 详解
【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3
本文以 docker/fedora-41/README.md 为核心,围绕 Proxmark3 Iceman Fork 仓库内置的 Fedora 41 Docker 测试环境展开:讲清该目录四个文件(Dockerfile、docker_conf.inc、run_tests.sh、README.md)各自的职责,逐行剖析 run_tests.sh 背后的“RDV4 / GENERIC / BTADDON 三组合 × make / cmake 双构建系统”测试矩阵,并结合 tools/release_tests.sh 与 tools/pm3_tests.sh 的源码,说明每个构建参数、每项自检的判定依据,以及如何在容器内手动跑单次构建加测试。读完后你可以独立完成:镜像构建、进入测试容器、执行全量发布测试并解读 PASS/FAIL 结果、按测试目标单独验证某一功能域。
1. 测试环境在仓库中的位置与整体分工
仓库在 docker/ 目录下为 17 个发行版各准备了一套同构的测试环境子目录(fedora-41、ubuntu-24.04、debian-13-trixie、archlinux 等),每个子目录包含四个文件:
| 文件 | 作用 |
|---|---|
| docker/fedora-41/Dockerfile | 定义基于fedora:41的基础镜像与全部编译依赖 |
| docker/fedora-41/docker_conf.inc | 声明镜像标签(DOCKER_IMAGE=pm3-fedora-41:1.0),供 run.sh / rm.sh 点源加载 |
| docker/fedora-41/run_tests.sh | 容器内的测试入口:更新系统包 → 跑发布测试矩阵 → 蜂鸣提示完成 |
| docker/fedora-41/README.md | 说明脚本用途、运行位置与单测命令 |
进入容器和清理容器则复用 docker/ 目录下的通用脚本:
- docker/run.sh:点源当前子目录的
docker_conf.inc取得镜像名,自动探测主机串口设备并挂载仓库源码,交互式进入容器; - docker/rm.sh:删除对应容器、删除镜像并清理构建缓存。
README 中给出的运行方式(在仓库根目录执行docker/fedora-41/run_tests.sh)对应的实际操作是:先用 docker/run.sh 进入容器(工作目录被设为/home/rrg/proxmark3,即仓库源码挂载点),再在容器内执行该脚本。
2. Dockerfile:编译依赖与测试用户是怎么准备的
Fedora 41 的 Dockerfile 只有一条基础镜像声明FROM fedora:41,随后按功能分批安装依赖,逐层可以对应到仓库构建系统的不同需求:
RUN dnf install -y passwd sudo git make cmake gcc gcc-c++ \ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel \ bzip2-devel lz4-devel zlib-ng-compat-devel bluez-libs-devel \ python3-devel openssl-devel gd-devel libatomic findutils各依赖的用途可以结合仓库结构印证:
arm-none-eabi-gcc-cs+arm-none-eabi-newlib:交叉编译 armsrc/(ARM 固件)、bootrom/ 与 recovery/ 固件所必需的 ARM 交叉工具链;make与cmake:对应 tools/release_tests.sh 中“make 与 cmake 两种构建系统分别验证”的设计,README 中“runs a bunch of different builds with make and cmake together”指的就是这一点;readline-devel:命令行客户端 client/ 的交互式输入支持;lz4-devel、bzip2-devel、zlib-ng-compat-devel:压缩与资源相关依赖(如 hardnested 表文件以.bin.lz4形式存放于client/resources/hardnested_tables/,测试脚本会检查其存在);bluez-libs-devel:BTADDON(蓝牙扩展板)组合构建所需的 BlueZ 库,对应PLATFORM_EXTRAS=BTADDON;gd-devel、python3-devel、openssl-devel:图像处理、Python 脚本支持与密码学相关依赖。
其余几个 RUN 层各有专门目的:
ARG SKIPQT=false RUN if [ "${SKIPQT}" = "false" ]; then \ dnf install -y qt6-qtbase-devel; \ fiQt6 开发库用于构建带图形界面的客户端;SKIPQT构建参数允许跳过以减小镜像体积。docker_conf.inc 中正好留了一行注释掉的#SKIPQT=1,表明该配置与 Dockerfile 参数联动。
RUN yum -y install mesa-libOpenCL ocl-icd-develOpenCL 运行时是 Hitag2 破解工具 OpenCL 版本的测试前提:tools/pm3_tests.sh 中对ht2crack5opencl的测试被标记为opencl类型,只有传入--opencl参数才会真正执行,否则显示SKIPPED ( opencl )。
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/uv是 Python 包运行器。pm3_tests.sh 开头的逻辑是:若系统存在uv则所有 Python 测试脚本(xorcheck、findbits、recover_pk 等)都通过uv run --script执行,否则回退到系统python3;设置SKIPUV=1可强制忽略 uv。
最后三组指令解决权限问题:
RUN useradd -ms /bin/bash rrg RUN passwd -d rrg ARG UART_GID RUN if [ -n "${UART_GID}" ]; then \ groupadd -g ${UART_GID} mydialout || true; \ usermod -aG ${UART_GID} rrg; \ fi RUN printf 'rrg ALL=(ALL) ALL\n' | tee -a /etc/sudoers- 创建无密码的普通用户
rrg并切换为容器运行用户,避免以 root 运行构建; UART_GID是一个构建期参数:不同 Linux 发行版上dialout组(串口设备属组)的数字 ID 不一致,注入该参数可让容器内的rrg用户获得与主机一致的串口访问组,使容器内能直接读写 Proxmark 设备的串口;rrg被授予完整 sudo 权限——这是 release_tests.sh 第 14 行中make install/make uninstall系统级安装测试能够执行的前提。
3. 用 run.sh / rm.sh 进入与清理容器
docker/run.sh 的完整流程(约 14 行):
. docker_conf.inc UART_PORT="$(../../pm3 --list|grep dev|head -n1|cut -d' ' -f2)" if [ -n "$UART_PORT" ]; then DEV="--device=/dev/tty0 --device=$UART_PORT" else DEV="" fi docker run $DEV $DOCKER_PLATFORM --volume="$(pwd)/../..:/home/rrg/proxmark3" \ -w /home/rrg/proxmark3 --net=host --rm -it "$DOCKER_IMAGE"要点:
- 脚本必须在某个发行版子目录内运行(找不到
docker_conf.inc会直接报错退出); - 先调用仓库自带的
pm3 --list探测主机上 Proxmark 设备所在的串口节点(如/dev/ttyACM0),若存在则通过--device映射进容器; - 仓库根目录整体挂载为容器内
/home/rrg/proxmark3,并设为工作目录——因此 README 强调“脚本要在容器内 proxmark 根目录下运行”; --net=host保证容器内可直达主机的串口与调试端口,--rm保证退出后不留容器。
docker/rm.sh 则按镜像标签过滤出同族容器执行docker rm,再删除pm3-fedora-41:1.0镜像并执行docker builder prune --force清理构建层缓存。
镜像本身可用标准的docker build命令构建,标签与docker_conf.inc中声明的DOCKER_IMAGE保持一致,例如docker build -t pm3-fedora-41:1.0 docker/fedora-41;如需跳过 Qt 依赖可追加--build-arg SKIPQT=true。
4. run_tests.sh:一次更新、一次全量矩阵、一声蜂鸣
docker/fedora-41/run_tests.sh 本体极短:
#!/usr/bin/env bash # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env # docker/fedora-41/run_tests.sh; sudo yum -y update tools/release_tests.sh # beeps for ((i=0; i<10;i++)) do echo -e "\a";sleep 0.3; done它做三件事:
sudo yum -y update——Fedora 41 的yum实际是 dnf 前端,与 README 单测流程中的sudo yum -y update是同一动作,保证测试基于最新系统包;- 委托 tools/release_tests.sh 执行真正的测试矩阵(下一节展开);
- 无论测试通过与否,连续 10 次、每次间隔 0.3 秒发出终端响铃(
\a)作为“跑完了”的人工提示——这是无头 CI 环境里一种很实用的完成信号。
5. release_tests.sh:真正的构建矩阵
tools/release_tests.sh 共 21 行,是 README 所说“make 与 cmake 对 RDV4、GENERIC、BTADDON 各种组合的构建”的完整实现。
5.1 前置保护:拒绝 SKIP 指令干扰
if [ -f Makefile.platform ]; then if grep -q "^SKIP_" Makefile.platform; then echo "ERROR: SKIP instructions in your Makefile.platform will interfere with this script, aborting..." exit 1; fi fi若本地存在Makefile.platform且包含SKIP_开头的行(用于跳过部分构建目标以节省时间),脚本直接中止退出——因为发布测试要求全量构建,任何跳过都会造成验证缺口。这也是“在 Docker 容器内跑测试”优于“在开发机上直接跑”的原因之一:容器里挂载的源码树是干净的,不会有本地Makefile.platform残留。
5.2 make 构建:三种硬件/功能组合
make clean && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= STANDALONE=LF_SAMYRUN && tools/pm3_tests.sh --long || exit 1 make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= STANDALONE=HF_ST25_TEAROFF || exit 1 make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON STANDALONE=HF_REBLAY || exit 1 make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON STANDALONE=HF_REBLAY && \ if sudo true; then \ INSTALLSUDO=sudo make install PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON STANDALONE=HF_REBLAY && \ ( cd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1' | grep 'Valid FDX-B ID found' ) && \ INSTALLSUDO=sudo make uninstall || exit 1; fi四个参数是构建矩阵的维度:
| 参数 | 取值 | 含义 |
|---|---|---|
PLATFORM | PM3GENERIC/PM3RDV4 | 目标硬件平台。PM3RDV4是根 Makefile help 中声明的默认平台(“default is PM3RDV4”);PM3GENERIC面向 RDV1/2/3 easy、iCopy-X 等通用平台,构建产物需适配不同的 FPGA 与 GPIO 布局 |
PLATFORM_EXTRAS | 空 /BTADDON | 是否编译蓝牙扩展板支持。选BTADDON时依赖 Dockerfile 中的bluez-libs-devel |
STANDALONE | LF_SAMYRUN/HF_ST25_TEAROFF/HF_REBLAY | 嵌入固件的 standalone 模式。三个目标分别对应 armsrc/Standalone/lf_samyrun.c、hf_st25_tearoff.c、hf_reblay.c,每种模式都会改变 ARM 固件的体积与入口行为,因此需要逐一验证链接与烧录布局 |
make -j | — | 全核并行编译 |
值得注意的三点:
- 每个组合之间都执行
make clean,确保上一组合的PLATFORM缓存不会污染下一组合;仓库根 Makefile 中有.Makefile.options.cache机制记录CACHED_PLATFORM_EXTRAS等缓存选项,clean 正是为了重置这类缓存; - 只有第一个组合(PM3GENERIC)编译完成后会紧接着运行
tools/pm3_tests.sh --long,即带--long(启用慢速测试)的完整自检,失败立即exit 1; - 第四行是“安装—真机回归—卸载”闭环:先以 sudo 执行
make install,然后在/tmp下用刚安装的proxmark3加载仓库自带的 traces/lf_EM4x05.pm3 离线信号文件并执行lf search -1,断言输出包含Valid FDX-B ID found;if sudo true守卫表示该步骤依赖 sudo 权限(Docker 里已满足),失败同样触发make uninstall前的exit 1。这条命令同时验证了make install的产物路径正确性与data load/lf search两条核心命令链。
5.3 cmake 构建:客户端三组合
( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j \ PLATFORM=PM3GENERIC PLATFORM_EXTRAS= STANDALONE=LF_SAMYRUN \ && cp -a ../*scripts ../*libs . \ && ../../tools/pm3_tests.sh --clientbin $(pwd)/proxmark3 client ) || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j \ PLATFORM=PM3RDV4 PLATFORM_EXTRAS= STANDALONE=HF_ST25_TEAROFF ) || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j \ PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON STANDALONE=HF_REBLAY ) || exit 1三组 cmake 构建与上面的 make 矩阵一一对应,但只构建 client/ 主机端程序。第一组额外做了两件事:
cp -a ../*scripts ../*libs .:把client/cmdscripts/、client/luascripts/、client/lualibs/、client/pyscripts/等脚本目录复制到构建目录——pm3_tests.sh 中的脚本类测试(script run example.cmd、script run data_hex_crc、script run parity.py)需要这些资源就位;- 通过
--clientbin $(pwd)/proxmark3 client告诉测试工具“只测 client 目标,且被测二进制就是这个 cmake 产物”,从而验证 cmake 路径构建出的客户端行为与 make 路径一致。
5.4 hitag2crack 与 PASS 判定
# Hitag2crack, optionally with --long and --opencl... make hitag2crack/clean && make hitag2crack && tools/pm3_tests.sh hitag2crack || exit 1 echo PASSHitag2 破解工具套件(tools/hitag2crack/)刻意没有并入根 Makefile 的all目标(源文件注释明确写着“not yet integrated in all, it must be called explicitly: make hitag2crack”),因此作为独立一项构建并测试。
全部步骤按顺序、失败即停地执行完毕后,脚本输出PASS——这正是 README 所说的判定标准:“If all tests OK, the script will finish with PASS.”。任何一步非零退出都会因|| exit 1中断整个矩阵,不会打印 PASS。
6. pm3_tests.sh:自检引擎的参数与判定机制
tools/pm3_tests.sh(约 670 行)是整个测试体系的核心引擎,run_tests.sh 矩阵与 README 的单测流程最终都汇到这里。
6.1 命令行接口
Usage: pm3_tests.sh [--long] [--opencl] [--clientbin /path/to/proxmark3] [mfkey|nonce2key|mf_nonce_brute|staticnested|mfd_aes_brute|mfulc_des_brute|cryptorf|fpga_compress|bootrom|armsrc|client|recovery|common] --long: Enable slow tests --opencl: Enable tests requiring OpenCL (preferably a Nvidia GPU) --clientbin ...: Specify path to proxmark3 binary to test If no target given, all targets will be tested- 不传目标时
TESTALL=true,覆盖全部测试域;传目标(如hitag2crack、client、common)则只跑对应域; --long开启SLOWTESTS,放行标记为slow(运行超过约 5 秒)的测试;README 单测命令tools/pm3_tests.sh --long即全量+慢速模式;--opencl开启OPENCLTESTS,放行opencl类测试(需要 OpenCL 设备,帮助文本建议 Nvidia GPU);--clientbin指定被测客户端二进制(见 5.3 节 cmake 流程),未指定时默认./client/proxmark3,即 make 路径的产物。
脚本开头还强制LANG=C.UTF-8,保证所有被测程序的帮助文本与错误输出是英文——因为断言全部基于英文输出做正则匹配,与容器 Dockerfile 中的ENV LANG=C.UTF-8形成双保险。
6.2 两个判定原语
CheckFileExist检查产物文件(可带opencl标记,无 OpenCL 时显示 SKIPPED 但不判失败);CheckExecute执行命令并用正则匹配输出,支持四个修饰位:
| 修饰位 | 行为 |
|---|---|
slow | 未开--long时跳过 |
opencl | 未开--opencl时跳过 |
retry | 失败最多重试 3 次 |
ignore | 失败不致命(如 Python 支持检测,缺失时后续 py 脚本测试自动跳过) |
执行超过 2 秒会打印耗时,失败会打印完整Execution trace便于定位。所有检查失败即break出主循环,打印红色Tests [ FAIL ]并以退出码 1 结束;全部通过打印Tests [ OK ]。
6.3 典型测试域举例
- common:检查
client/resources/与client/dictionaries/下的资源文件(hardnested 状态表 lz4、sim020.bin、iclass/mfc/mfdes 默认密钥字典、t55xx 密码字典等)是否存在,并运行tools/xorcheck.py、tools/findbits.py、tools/recover_pk.py selftests、tools/mkversion.sh --short等 Python/Shell 工具; - bootrom / armsrc / recovery / fpgacompress:分别断言
bootrom/obj/bootrom.elf、armsrc/obj/fullimage.elf、recovery/recovery.bin、tools/fpga_compress/fpga_compress四个构建产物存在——这解释了 release_tests.sh 里每一轮make必须成功的原因,产物缺失即 FAIL; - mfkey / staticnested / nonce2key / mf_nonce_brute / mfd_aes_brute / mfulc_des_brute / cryptorf:针对 tools/mfc/、tools/cryptorf/ 等密码学工具做“给定已知明文/nonce 输入,断言能解出预定密钥”的黄金向量测试,例如
mfkey32v2输入固定八组参数后断言输出Found Key: [a0a1a2a3a4a5]; - hitag2crack:验证 crack2 表构建/搜索工具、crack3/4/5 的生成—破解闭环(crack5 的破解耗时约十几秒,标记为
slow),以及 crack5opencl 的 OpenCL 版本(标记slow opencl,需要--opencl才跑); - client:对客户端二进制做纯离线回归——帮助文本、多命令执行(
-c分号串联与 stdin 管道)、cmdscript/luascript/pyscript 执行、data qrcode参数校验、data modulation自相关、trace load/list(ISO14443-A 与 ISO7816 两种解析)、nfc decode各类 NDEF 负载(vCard、WiFi WSC、Apple Wallet、PILet 签名等)、wiegand encode/decode多种格式回环、二十余种 LF 制式 demod(HID、AWID、Indala、NexWatch、Securakey 等)与 T5577 模拟信号的lf search识别,以及hf mf、hf mfdes、hf gst、emv test等 HF 域自检。断言全部针对仓库自带的 traces/ 离线文件,无需真实射频信号,只有 5.2 节那条make install后的真机测试需要设备在位。
7. 手动执行单次构建加测试(README 单测流程)
README 给出的精简流程是在容器内的仓库根目录执行:
sudo yum -y update make clean; make -j tools/pm3_tests.sh --long逐条说明:
sudo yum -y update:刷新系统包,保证工具链与库为最新稳定版;make clean; make -j:以默认平台(PM3RDV4,根 Makefile help 文本中声明)做一轮全量并行构建,产出 bootrom、armsrc 固件、recovery 镜像、客户端与 tools 二进制;tools/pm3_tests.sh --long:不带目标参数,即测试全部域,且放行所有慢速测试。注意该命令本身不校验--long之外的硬件状态,除真机相关断言外可完全离线完成。
相比 run_tests.sh 的完整矩阵,这套单测流程等价于矩阵中“PM3RDV4 + make + 全量 pm3_tests”的组合,适合在修改某一模块后快速自证;若要复现 CI 级覆盖,仍应回到tools/release_tests.sh全矩阵。
8. 相关文件索引
| 路径 | 说明 |
|---|---|
| docker/fedora-41/README.md | 本文核心文档:脚本用途、运行位置、单测命令 |
| docker/fedora-41/Dockerfile | 依赖清单、SKIPQT/UART_GID 构建参数、rrg 测试用户 |
| docker/fedora-41/docker_conf.inc | 镜像标签pm3-fedora-41:1.0 |
| docker/fedora-41/run_tests.sh | 容器内测试入口 |
| docker/run.sh / docker/rm.sh | 通用容器进入/清理脚本 |
| tools/release_tests.sh | make+cmake 双系统、三平台组合测试矩阵 |
| tools/pm3_tests.sh | 自检引擎:参数解析、CheckExecute/CheckFileExist、各测试域 |
| Makefile | 根构建入口,默认平台 PM3RDV4,hitag2crack独立目标 |
| armsrc/Standalone/readme.md | STANDALONE 参数对应模式的开发说明 |
9. 小结
Proxmark3 Iceman Fork 的 Fedora 41 Docker 目录看起来只有四个小文件,实际串起了一条完整的“干净环境验证链”:Dockerfile 精确复刻了交叉工具链、BlueZ、OpenCL、Qt、uv 等全部构建依赖并准备无密码的 sudo 测试用户;run.sh 负责串口直通与源码挂载;run_tests.sh 委托 release_tests.sh 跑完“3 种硬件/功能组合 × make/cmake 两套构建系统 + 安装真机回归 + hitag2crack”的全矩阵,最后以 PASS 收束;而所有断言最终落在 pm3_tests.sh 的 CheckExecute/CheckFileExist 黄金向量体系上,全部离线可复现。理解这条链之后,无论是复现 CI 失败、新增 standalone 模式、还是验证一次密码学工具的改动,都可以按同一套路径在容器内完成。
【免费下载链接】proxmark3Iceman Fork - Proxmark3项目地址: https://gitcode.com/GitHub_Trending/pr/proxmark3
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考