1. 项目概述与核心价值最近在和一些刚入行安全研究的朋友交流时发现一个挺普遍的问题大家在网上看到很多关于漏洞分析、0day利用的文章但真想自己动手复现或者搭建一个环境来深入学习时往往第一步就卡住了。要么是依赖环境太复杂装半天报一堆错要么是好不容易把漏洞代码跑起来了却不知道如何构造一个完整的测试流程。这让我想起自己早年踩过的那些坑所以今天想系统性地聊聊如何从零开始在你自己可控的本地环境里搭建一个功能相对完整的漏洞测试平台。这个“平台”听起来可能有点唬人但其实核心目标很简单为你提供一个安全、隔离、可复现的沙箱环境。在这个环境里你可以放心大胆地部署那些存在已知或未知0day漏洞的应用程序、服务或代码片段然后使用各种工具进行扫描、分析、调试和利用测试而不用担心影响到你的主力开发机或生产网络。这对于安全研究员、渗透测试工程师甚至是想要深入理解漏洞原理的开发人员来说都是一个极其重要的基础能力。它不仅是学习研究的“练功房”也是验证POC、测试防御规则是否有效的“试验场”。为什么强调“本地环境”因为可控性和便捷性。云服务器虽然方便但涉及漏洞测试网络流量、文件操作都可能触发安全告警甚至违反服务条款。本地环境则完全由你掌控可以随意断网、快照恢复、进行底层调试。结合当下热门的容器化技术比如Docker我们可以用很低的资源开销快速构建出包含Web服务器、数据库、特定中间件版本的复杂漏洞靶场。接下来我会手把手带你走通整个流程从环境规划、工具选型到实战部署一个包含漏洞的Spring Boot应用并集成基础测试工具。2. 平台架构设计与核心组件选型搭建一个漏洞测试平台不是简单装几个软件而需要一套清晰的架构设计。一个好的设计应该满足环境隔离、快速重建、工具集成、流量可控。下面是我基于多年经验总结的一套务实方案。2.1 核心架构思路我推荐采用“宿主机 容器化靶场 独立工具链”的混合架构。宿主机你的物理机或虚拟机作为管理平面和重型工具的运行环境所有存在漏洞的靶标应用全部用Docker容器来封装和运行而一些通用的测试工具如代理、扫描器则根据情况选择宿主机部署或容器化部署。这种做法的好处显而易见极致隔离每个漏洞靶场都是独立的容器文件系统、网络、进程彼此隔离。即使某个靶场因为攻击测试而崩溃也不会影响宿主机或其他靶场。一键重建所有环境都通过Dockerfile或Docker Compose文件定义。测试完成后直接删除容器即可。需要再次研究时一条命令就能恢复原状保证实验环境的一致性。资源高效相比为每个靶场创建完整的虚拟机Docker容器共享宿主机内核启动速度快资源占用小让你能在普通配置的电脑上同时运行多个不同漏洞场景。便于分发你可以将构建好的Docker镜像保存下来或者分享Docker Compose文件团队成员能瞬间获得一模一样的环境极大减少了“在我机器上是好的”这类问题。2.2 关键组件选型与理由一个完整的测试平台需要以下几类组件我的选型基于稳定性、社区活跃度和上手难度1. 容器化引擎Docker没有悬念的选择。它是当前容器生态的事实标准拥有最丰富的镜像资源和最成熟的工具链。虽然也有Podman等替代品但Docker的桌面版Docker Desktop for Mac/Windows对新手尤其友好集成了图形化管理界面。对于Linux宿主机直接安装Docker Engine即可。2. 靶场应用来源去哪里找带漏洞的应用来练习我主要推荐以下几个DVWA (Damn Vulnerable Web Application) 老牌且经典的PHP漏洞靶场包含SQL注入、XSS、文件上传等十大常见漏洞适合Web安全入门。Vulhub 这是一个宝藏项目。它提供了大量流行组件如Struts2, Redis, Jenkins, Spring Boot等历史漏洞的一键式Docker环境。你只需要找到对应的漏洞目录执行docker-compose up -d一个完整的漏洞环境就在几秒钟内启动好了极大降低了复现漏洞的环境搭建成本。自己构建 当你需要研究特定版本的CMS如WordPress插件漏洞或自己编写的漏洞代码时就需要自己编写Dockerfile来构建镜像。这能让你最深入地理解应用依赖和环境配置。3. 测试工具集工具不在多在于精和顺手。本地测试平台通常集成以下几类代理工具 (Burp Suite / OWASP ZAP) 用于拦截、查看、修改和重放浏览器与目标应用之间的所有HTTP/HTTPS流量是手工测试和漏洞挖掘的核心。社区版的Burp Suite或开源的ZAP足以满足大部分需求。漏洞扫描器 (Nuclei) 与传统笨重的扫描器不同Nuclei基于YAML模板速度快定制能力强。你可以用它快速检测目标是否存在已知漏洞的指纹特征。它非常适合在搭建好靶场后进行第一轮的自动化安全检查。目录/文件扫描器 (Gobuster / Dirsearch) 用于发现Web应用隐藏的目录、文件和接口。在测试未知应用时这是信息收集的关键一步。网络工具 (Nmap) 经典的网络发现和安全审计工具用于扫描靶场容器开放的端口和服务版本。4. 辅助管理工具Docker Compose 用于定义和运行多容器Docker应用。通过一个docker-compose.yml文件你可以配置整个靶场如Web应用数据库缓存的启动参数、网络连接管理起来非常方便。Portainer (可选) 一个轻量级的Docker图形化管理界面。如果你不习惯命令行可以用它来直观地查看容器状态、日志执行启动停止等操作。注意 工具的选择具有很强的个人偏好。这里推荐的是经过广泛验证、文档齐全的“标准件”。当你熟练后完全可以替换成自己更顺手的工具链。3. 本地基础环境搭建与配置工欲善其事必先利其器。在开始部署漏洞靶场之前我们需要一个干净、稳定的基础环境。这里我以 macOS/Linux 为主要环境进行说明Windows 用户使用 WSL2 或 Docker Desktop 也可获得几乎一致的体验。3.1 Docker 与 Docker Compose 安装这是所有工作的基石。我强烈建议通过官方渠道安装避免版本兼容性问题。对于 macOS 和 Windows 用户最省心的方式是直接下载并安装 Docker Desktop 。它集成了 Docker Engine、Docker CLI 和 Docker Compose安装完成后即可使用。安装后在终端输入docker --version和docker-compose --version验证安装。对于 Linux 用户以 Ubuntu 20.04/22.04 为例可以通过官方仓库安装过程更可控。# 1. 卸载旧版本如有 sudo apt-get remove docker docker-engine docker.io containerd runc # 2. 安装依赖包允许 apt 通过 HTTPS 使用仓库 sudo apt-get update sudo apt-get install -y \ ca-certificates \ curl \ gnupg \ lsb-release # 3. 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 4. 设置稳定版仓库 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 5. 安装 Docker Engine 和 Compose 插件 sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 6. 验证安装 docker --version docker compose version # 注意新插件命令是 docker compose中间没有横杠 # 7. 可选但推荐将当前用户加入 docker 组避免每次使用 sudo sudo usermod -aG docker $USER # 执行此命令后需要**注销并重新登录**用户组更改才会生效。安装完成后运行一个测试容器来验证一切正常docker run hello-world如果能看到“Hello from Docker!”等欢迎信息说明 Docker 已正确安装并运行。3.2 创建项目工作目录保持文件系统整洁是个好习惯。我建议在用户目录下创建一个专门的工作空间。mkdir -p ~/vuln_lab/{targets, tools, data, scripts} cd ~/vuln_labtargets/: 存放各个漏洞靶场的 Docker Compose 文件或自定义 Dockerfile。tools/: 存放需要在宿主机运行的测试工具如 Nuclei、Gobuster 的二进制文件。data/: 用于挂载到容器中持久化保存数据库文件、上传的文件等方便下次启动时数据不丢失。scripts/: 存放一些自动化脚本比如批量启动靶场的脚本。3.3 配置网络与防火墙Linux 特别注意为了让宿主机上的工具能方便地访问容器内的靶场我们需要理解 Docker 的网络模式。默认情况下Docker 会创建一个名为bridge的虚拟网络容器会分配一个类似172.17.0.x的内网 IP。宿主机访问容器 最简单的方式是将容器端口映射到宿主机。例如在运行容器时使用-p 8080:80参数即可通过访问宿主机的http://localhost:8080来访问容器的 80 端口服务。容器间互相访问 如果靶场由多个容器组成如 Web 应用 MySQL使用 Docker Compose 时它们默认会加入同一个自定义网络可以通过容器名作为主机名直接通信这比记 IP 地址方便得多。防火墙设置 如果你的 Linux 宿主机开启了防火墙如ufw需要放行 Docker 相关的流量。# 查看 ufw 状态 sudo ufw status # 如果启用通常需要允许 Docker 的网桥流量 sudo ufw allow in on docker0 # 或者更直接地放行你将要映射的特定端口比如 80, 8080, 3306 等 sudo ufw allow 8080/tcp实操心得 在 Linux 上我经常遇到 Docker 容器能ping通外网但无法apt-get update的情况。这通常是 DNS 解析问题。可以尝试在宿主机修改 Docker 的 DNS 配置编辑/etc/docker/daemon.json文件如果不存在则创建{ dns: [8.8.8.8, 114.114.114.114] }然后重启 Docker 服务sudo systemctl restart docker。这个小技巧能解决很多网络连通性怪事。4. 实战部署一个 Spring Boot 漏洞靶场理论讲得再多不如动手做一遍。我们以复现一个经典的 Spring Boot 相关漏洞为例使用Vulhub项目它极大简化了环境搭建过程。4.1 获取 Vulhub 漏洞环境Vulhub 把漏洞环境做成了“开箱即用”的 Docker Compose 模板我们直接克隆它的仓库。# 进入之前创建的 targets 目录 cd ~/vuln_lab/targets # 克隆 Vulhub 仓库国内用户如果慢可以考虑使用 Gitee 镜像 git clone https://github.com/vulhub/vulhub.git cd vulhub仓库里按漏洞组件分门别类我们可以找一个 Spring Boot 的漏洞例如CVE-2022-22965即 Spring Framework 的 RCE 漏洞常被称作 “Spring4Shell”。# 进入该漏洞的目录 cd spring/CVE-2022-22965查看目录下的docker-compose.yml文件这就是定义整个环境的“配方”。4.2 解析与启动漏洞环境让我们看看这个docker-compose.yml文件的核心内容通常 Vulhub 已经为我们写好了version: 2 services: web: image: vulhub/spring-webmvc:5.3.17 ports: - 8080:8080非常简单它从 Docker Hub 拉取一个预构建好的镜像vulhub/spring-webmvc:5.3.17这个镜像里已经部署了存在漏洞的 Spring 应用。然后将容器的 8080 端口映射到宿主机的 8080 端口。启动环境只需要一条命令# 在 docker-compose.yml 文件所在目录执行 docker-compose up -d-d参数代表后台运行。执行后Docker 会拉取镜像如果本地没有并启动容器。使用以下命令确认容器运行状态docker-compose ps # 或 docker ps你应该能看到一个名为spring-cve-2022-22965-web-1的容器正在运行并且端口映射为0.0.0.0:8080-8080/tcp。此时在宿主机浏览器中访问http://localhost:8080就能看到启动的漏洞应用界面了。4.3 自定义与深入构建自己的漏洞镜像使用 Vulhub 很方便但有时我们需要测试特定的应用版本或者研究自己写的漏洞代码。这时就需要自己编写Dockerfile来构建镜像。假设我们有一个存在 SQL 注入漏洞的简单 Java Web 应用一个.war包需要部署到 Tomcat 中进行测试。准备项目文件 在~/vuln_lab/targets下新建目录my-sqli-app。mkdir -p ~/vuln_lab/targets/my-sqli-app cd ~/vuln_lab/targets/my-sqli-app将你的漏洞应用vulnerable-app.war和数据库初始化脚本init.sql放入此目录。编写 Dockerfile# 使用官方 Tomcat 镜像作为基础 FROM tomcat:9-jdk11-openjdk-slim # 设置工作目录可选但好习惯 WORKDIR /usr/local/tomcat # 删除 Tomcat 自带的默认应用保持环境干净 RUN rm -rf webapps/* # 将我们的漏洞应用 WAR 包复制到 Tomcat 的 webapps 目录下Tomcat 会自动解压部署 COPY vulnerable-app.war webapps/ROOT.war # 如果需要可以复制一个自定义的 server.xml 配置文件来修改 Tomcat 设置 # COPY server.xml conf/ # 暴露 Tomcat 默认端口 EXPOSE 8080 # 使用默认的启动命令 CMD [catalina.sh, run]这个 Dockerfile 做了几件事基于一个轻量化的 Tomcat 镜像清理了默认应用把我们自己的应用复制进去并指定了启动命令。编写 docker-compose.yml 一个完整的靶场通常需要数据库。我们用 Docker Compose 来编排应用和数据库。version: 3.8 services: mysql: image: mysql:5.7 container_name: mysql-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: rootpassword123 # 强烈建议在测试环境使用强密码养成好习惯 MYSQL_DATABASE: vulndb MYSQL_USER: testuser MYSQL_PASSWORD: userpassword123 volumes: - ./mysql_data:/var/lib/mysql # 持久化数据库数据 - ./init.sql:/docker-entrypoint-initdb.d/init.sql # 容器启动时自动执行SQL脚本 networks: - vuln-net webapp: build: . # 使用当前目录的 Dockerfile 构建镜像 container_name: sqli-webapp restart: unless-stopped ports: - 18080:8080 # 映射到宿主机的 18080 端口避免与其它服务冲突 depends_on: - mysql environment: DB_HOST: mysql-db # 通过服务名连接数据库这是 Docker Compose 网络的优势 DB_NAME: vulndb DB_USER: testuser DB_PASSWORD: userpassword123 networks: - vuln-net networks: vuln-net: driver: bridge这个配置定义了两个服务一个 MySQL 5.7 数据库一个由我们 Dockerfile 构建的 Web 应用。它们通过自定义的vuln-net网络连接。depends_on确保数据库先启动。volumes将宿主机的mysql_data目录和init.sql脚本挂载到容器内实现数据持久化和初始化。构建并运行# 在 my-sqli-app 目录下执行 docker-compose up --build -d--build参数会强制重新构建 Web 应用的镜像。运行成功后访问http://localhost:18080即可看到你的漏洞应用并且它已经连上了数据库。注意事项 在编写 Dockerfile 时尽量使用官方镜像的特定版本标签如tomcat:9-jdk11-openjdk-slim而不是latest。这能确保构建环境的一致性避免因为基础镜像更新而导致应用行为变化。此外将应用配置文件、数据库初始化脚本等通过COPY指令放入镜像而不是在容器启动后手动修改这样能保证镜像本身的自包含和可重现性。5. 集成测试工具链与工作流环境搭好了接下来需要武装我们的“武器库”。我们将把常用的测试工具集成到工作流中形成从信息收集到漏洞验证的闭环。5.1 代理工具配置以 Burp Suite 为例Burp Suite 是手动测试的瑞士军刀。我们需要配置浏览器和 Burp使其能拦截到我们本地靶场的流量。启动 Burp Suite 从官网下载社区版启动后在Proxy-Options选项卡中确保代理监听在127.0.0.1:8080这是 Burp 默认设置。配置浏览器代理方法一推荐使用浏览器插件如SwitchyOmega为测试单独创建一个代理情景指向127.0.0.1:8080。这样只有访问靶场时才走代理不影响正常上网。方法二直接在浏览器系统设置中配置 HTTP/HTTPS 代理为127.0.0.1:8080。但注意这会使所有浏览器流量都经过 Burp。安装 Burp 的 CA 证书 为了拦截和解密 HTTPS 流量需要在浏览器中安装 Burp 生成的 CA 证书。在 Burp 中访问http://burp或http://127.0.0.1:8080点击 “CA Certificate” 下载证书然后导入到浏览器的证书管理机构中。测试拦截 配置好后在浏览器中访问你的靶场地址如http://localhost:18080Burp 的Proxy-Intercept选项卡如果显示为 “Intercept is on”你应该能看到捕获到的 HTTP 请求。将其放行页面正常加载说明代理配置成功。5.2 自动化扫描与信息收集在手动测试前用自动化工具做一遍初步侦察能帮你快速发现低垂的果实。1. 使用 Nuclei 进行漏洞扫描Nuclei 使用模板驱动非常高效。首先安装它以 Linux/macOS 为例# 进入工具目录 cd ~/vuln_lab/tools # 下载最新版的 Nuclei 二进制文件请从 GitHub 发布页获取最新链接 wget https://github.com/projectdiscovery/nuclei/releases/download/v3.2.0/nuclei_3.2.0_linux_amd64.tar.gz tar -xzf nuclei_3.2.0_linux_amd64.tar.gz sudo mv nuclei /usr/local/bin/ # 更新模板 nuclei -update-templates扫描我们的靶场nuclei -u http://localhost:18080 -silent-silent参数只显示有问题的结果。Nuclei 会基于其庞大的模板库快速检测目标是否存在已知的漏洞、暴露的敏感文件、错误配置等。2. 使用 Gobuster 进行目录爆破目录爆破可以帮助我们发现隐藏的管理后台、API接口、备份文件等。# 安装 Gobuster (以 Kali/Ubuntu 为例) sudo apt-get install gobuster # 或者用 Go 安装go install github.com/OJ/gobuster/v3latest # 使用常见字典进行目录爆破 gobuster dir -u http://localhost:18080 -w /usr/share/wordlists/dirb/common.txt -t 50-w指定字典文件-t指定线程数。你可以准备更专业的字典文件放在~/vuln_lab/tools/wordlists/下。5.3 形成基础测试工作流一个高效的本地测试流程可以固化如下启动与确认docker-compose up -d启动靶场用浏览器直接访问确认服务正常。信息收集nmap -sV -p- localhost -p18080扫描端口和服务版本虽然我们知道是8080但这是习惯。gobuster dir ...进行目录爆破。手动浏览网站观察功能点、参数、使用的技术栈查看源码、响应头。代理设置 配置浏览器流量经过 Burp Suite。手动测试在 Burp 中将站点地图 (Target-Site map) 添加到范围 (Scope)。遍历所有功能点拦截每一个请求和响应。对每一个输入点参数、Cookie、Header尝试注入、越权等测试。使用 Burp 的Repeater模块对可疑请求进行重放和修改测试。使用Intruder模块进行模糊测试和暴力破解。专项扫描 针对发现的具体技术如 ThinkPHP, Spring使用 Nuclei 对应的模板进行深入扫描。清理环境 测试完成后docker-compose down关闭并移除容器。如果需要保留数据库数据下次docker-compose up -d时会自动恢复。实操心得 我习惯为每一个靶场项目创建一个简单的README.md文件记录其访问地址、默认账号密码、已知漏洞类型和利用方式。时间久了项目一多很容易忘记。这个文档不仅是给自己的笔记也方便分享给同事。另外在 Docker Compose 文件中我会为每个服务设置固定的容器名称 (container_name)这样在查看日志docker logs [container_name]或进入容器docker exec -it [container_name] /bin/bash时不需要去查冗长的容器ID效率高很多。6. 高级技巧、问题排查与优化当你能熟练搭建和测试基础靶场后可以进一步优化你的平台提升效率和专业性。6.1 网络隔离与流量控制默认的bridge网络虽然方便但所有靶场容器都在一个大内网里有时我们可能需要更复杂的网络拓扑来模拟真实网络环境如 DMZ、内网。创建自定义网络docker network create --subnet172.20.0.0/24 --gateway172.20.0.1 my-isolated-net然后在docker-compose.yml中让某个靶场服务使用这个网络services: vulnerable_app: ... networks: my-isolated-net: ipv4_address: 172.20.0.10 # 可以指定固定IP networks: my-isolated-net: external: true # 声明使用外部已创建的网络这样这个靶场就与其他使用默认网络的容器隔离了。你可以创建多个不同网段的网络模拟复杂的网络分区。使用--network host模式 在某些特殊场景下例如需要容器内工具扫描宿主机网络可以使用主机网络模式但这会降低隔离性慎用。6.2 持久化与数据管理测试过程中产生的数据如上传的 Webshell、修改的数据库内容你可能希望保留。Docker 的卷Volume和绑定挂载Bind Mount是解决方案。命名卷 (Named Volume) Docker 管理的存储位置在宿主机/var/lib/docker/volumes/下与容器生命周期解耦。适合存储数据库文件等。volumes: mysql_data: # 声明一个命名卷 services: mysql: volumes: - mysql_data:/var/lib/mysql绑定挂载 (Bind Mount) 将宿主机特定目录挂载到容器。适合挂载配置文件、源代码、日志文件方便在宿主机直接编辑查看。services: webapp: volumes: - ./app/logs:/usr/local/tomcat/logs # 将日志输出到宿主机当前目录下的app/logs - ./config:/config # 挂载配置文件目录一个重要技巧快速进入容器调试当应用行为异常时需要进入容器内部查看。# 进入名为 ‘sqli-webapp’ 的容器并启动一个 bash shell docker exec -it sqli-webapp /bin/bash # 如果容器内没有 bash可以试试 sh docker exec -it sqli-webapp sh在容器内你可以查看进程ps aux查看日志文件tail -f /usr/local/tomcat/logs/catalina.out甚至安装调试工具如curl,vim但注意测试镜像通常很精简。6.3 常见问题与排查实录在搭建和测试过程中你肯定会遇到各种问题。这里记录几个高频问题问题1容器启动后应用无法访问Connection refused。排查思路检查容器状态docker-compose ps或docker ps确认容器是Up状态而不是Exited。如果是Exited用docker logs [container_name]查看启动日志通常会有错误信息如端口冲突、依赖服务未就绪。检查端口映射docker ps查看PORTS列确认宿主机的端口如0.0.0.0:18080-8080/tcp映射正确。有时可能映射到了其他端口或只映射到了127.0.0.1。检查应用日志 即使容器是Up的内部应用也可能启动失败。进入容器查看应用日志例如 Tomcat 的catalina.outSpring Boot 的控制台输出等。检查防火墙 确保宿主机防火墙没有阻止映射的端口如 18080。问题2Web 应用容器无法连接到数据库容器。排查思路确认网络 确保它们在同一个 Docker Compose 定义的自定义网络中或者都在默认的 bridge 网络中并能互通。在 Web 应用容器内执行ping mysql-db数据库服务名看是否通。检查连接参数 确认 Web 应用配置中使用的数据库主机名、端口、用户名、密码与docker-compose.yml中environment部分定义的环境变量一致。可以在 Web 应用容器内打印环境变量echo $DB_HOST来验证。检查数据库服务状态 数据库容器可能启动较慢。在docker-compose.yml中使用depends_on只是控制启动顺序不保证数据库服务已完全初始化。可以考虑使用healthcheck指令或者让 Web 应用具备重连数据库的机制。问题3修改了 Dockerfile 或代码但重新构建后变化没生效。原因与解决 Docker 构建有缓存机制。如果你只修改了源代码文件但COPY命令之前的层没有变化Docker 会使用缓存导致新代码没被复制进去。强制重建 使用docker-compose up --build -d。--build会强制重建镜像。更彻底的重建 先删除旧镜像和容器。docker-compose down # 停止并删除容器 docker-compose build --no-cache # 无缓存构建镜像 docker-compose up -d问题4Burp Suite 抓不到本地靶场的 HTTPS 请求。排查思路证书是否安装 确保已在浏览器或系统信任库中正确安装 Burp 的 CA 证书。代理设置是否生效 访问http://burp是否能下载证书如果不能说明浏览器流量没走 Burp。目标是否为 HTTPS 如果靶场是 HTTP 服务Burp 默认可以拦截。如果是 HTTPS如https://localhost:8443必须安装并信任 Burp CA 证书才能解密。浏览器是否有插件干扰 尝试使用无痕模式或禁用所有浏览器插件进行测试。搭建本地漏洞测试平台是一个持续迭代和积累的过程。一开始可能会觉得繁琐但一旦这套流程跑顺你会发现它带来的效率和安全感是无可替代的。你可以随时暂停、销毁、重建任何一个实验环境可以放心地进行各种破坏性测试而这一切都发生在你完全掌控的本地沙箱中。这不仅是学习安全技术的基石也是培养工程化思维和动手能力的绝佳途径。