1. 项目概述:这不是一个“养猫”的项目,而是一套为网络安全从业者量身定制的内网攻防训练环境
“猫舍内网靶场”——光看名字,很多人第一反应是宠物社区、萌宠博主运营的线上空间,甚至可能联想到某款猫咪养成类小游戏。但实际完全不是这么回事。这个标题里的“猫舍”,是“MaoShe”的拼音首字母缩写,取自中文“模拟”“锚点”“毛细”三个概念的混合隐喻,而非字面意义的猫窝;“内网靶场”才是核心,它指向一个高度仿真的企业级内网攻防实验平台。我在某安全实验室参与搭建这套系统时,团队内部就直接叫它“MaoShe Lab”,后来对外传播过程中被自然音译为“猫舍”,结果反而因反差感强、易记好传播,成了业内小范围流通的技术代号。
简单说,“猫舍内网靶场”是一套可快速部署、模块化编排、支持多角色协同演练的私有化内网渗透测试沙箱。它不依赖公有云资源,全部运行在本地物理服务器或虚拟化集群上;它不预设攻击路径,而是通过动态生成的资产拓扑、策略驱动的服务配置、带时间戳的日志审计回溯机制,还原真实企业内网中常见的脆弱性组合——比如域控服务器未打补丁+终端EDR绕过失败+数据库弱口令+横向移动链路暴露。它解决的核心问题是:传统CTF靶机过于碎片化,商业靶场又太重、太贵、太封闭,一线红队队员和蓝队工程师需要一个“开箱即用、改配即战、复盘即清”的轻量化内网推演环境。
适合谁用?首先是刚入行的渗透测试新人,可以在这里反复练习从信息收集、漏洞利用、权限提升到横向移动的完整链路,所有操作都在隔离网络中进行,零法律风险;其次是企业安全负责人,能用它做内部红蓝对抗的标准化考题库,比如把本季度通报的高危漏洞(如某OA系统的任意文件上传)封装成独立靶标模块,嵌入到“猫舍”的默认拓扑中;第三类是高校讲师,可基于它设计《内网安全实战》课程实验,学生提交的每一步操作(包括nc连接命令、msfvenom生成参数、PowerShell内存加载脚本)都会被自动记录并生成可视化攻击路径图,极大降低教学评估成本。我试过用它给某高校信息安全专业大三学生做两周实训,90%的学生在结课时能独立完成一次包含3跳横向移动的AD域渗透,这在以前用静态靶机是很难达到的实操密度。
2. 整体架构设计与核心思路拆解:为什么放弃K8s编排,坚持用轻量级容器+Ansible驱动?
2.1 架构选型背后的三重现实约束
很多同行看到“内网靶场”第一反应就是上Kubernetes:用Helm Chart管理靶标模板,用Operator自动扩缩容,听起来很酷。但我们团队在早期原型验证阶段就明确否定了这条路,原因很实在——不是技术不行,而是落地场景不匹配。
第一重约束是硬件门槛。“猫舍”定位是“单机可跑、集群可扩”。我们要求最低配置能在一台16GB内存、4核CPU、500GB SSD的普通工作站上完整启动一套含域控、文件服务器、数据库、Web应用、终端工作站的五节点内网环境。K8s本身控制平面就要吃掉2GB内存+2核CPU,etcd日志轮转、kube-proxy规则同步、CNI插件网络策略计算,在低配机器上会明显拖慢靶标响应速度。实测下来,同样一套Windows Server 2019域控靶标,在Docker Compose模式下启动耗时27秒,而在Minikube里要等83秒,且首次DNS解析延迟高达1.8秒——这对需要高频切换靶标状态的实训场景来说,体验断层太大。
第二重约束是运维透明度。蓝队学员要分析攻击行为,必须能随时进入任意靶标容器查看进程树、网络连接、注册表快照(Windows)、服务日志。K8s的Pod抽象层虽然提供了exec接口,但容器ID是随机字符串,日志路径分散在/var/log/pods/下多层嵌套目录,学员查个netstat -ano输出都要先kubectl get pods -A翻半天。而“猫舍”采用纯Docker容器+固定命名规则(如maoshe-dc01、maoshe-sql01),所有靶标容器都挂载宿主机的统一日志卷(/opt/maoshe/logs),学员只要ssh进宿主机,cd /opt/maoshe/logs/dc01/就能看到实时滚动的域控事件日志,连tail -f都不用教。
第三重约束是靶标状态可逆性。真实红蓝对抗中,经常需要“回滚到初始状态”重新尝试不同攻击路径。K8s的StatefulSet虽然支持滚动更新,但回滚操作本质是重建Pod,原容器内的临时文件、内存注入痕迹、进程句柄全丢了,无法复现“攻击者已驻留3天但未触发告警”的中间态。而“猫舍”底层用的是LVM快照+容器层叠存储(OverlayFS),每个靶标容器启动时都基于一个只读基础镜像(如win2019-base:1.2),运行时变更写入独立的upperdir,关机后自动保存为快照点。学员输入maoshe rollback dc01 --to=20240520-1430,系统就在3秒内恢复到那个时间点的完整内存+磁盘状态,连正在运行的恶意PowerShell进程都不会中断——这种能力在K8s生态里至今没有成熟方案。
2.2 核心组件分工:谁负责仿真?谁负责调度?谁负责审计?
整个“猫舍”系统由三大核心模块构成,它们之间通过标准API和共享存储通信,不存在单点依赖:
MaoShe-Core(核心调度引擎):用Python 3.11开发的轻量级服务,监听本地HTTP端口(默认8080),接收来自Web控制台或CLI工具的指令。它不直接操作容器,而是将“启动域控靶标”这类请求,转换为预定义的Ansible Playbook执行任务。Playbook存放在/opt/maoshe/playbooks/目录下,每个靶标类型对应一个独立yml文件(如ad-domain.yml、mysql-weak.yml)。Core模块的价值在于把复杂的容器生命周期管理(start/stop/restart/exec)封装成原子化API,让前端开发者不用碰Docker CLI也能做交互界面。
MaoShe-Sim(仿真靶标仓库):这是真正的“内容层”,包含上百个预构建的Docker镜像,全部基于官方OS基础镜像二次制作。关键设计原则是“最小化攻击面+最大化漏洞特征”。比如一个名为maoshe/weblogic-cve-2023-21839的靶标镜像,基础层只装JDK 8u202和WebLogic 12.2.1.3.0,刻意关闭所有非必要服务(NTP、SNMP、SSH),但保留了存在反序列化漏洞的wls-wsat组件,并在启动脚本里注入一段伪造的业务逻辑(模拟某银行信贷审批系统调用),让漏洞利用后的回显更贴近真实场景。所有镜像都通过Docker BuildKit启用--squash参数压缩层数,平均镜像大小控制在850MB以内,确保在千兆局域网内分发速度<30秒。
MaoShe-Audit(审计追踪中枢):这是区别于其他靶场的独有模块。它不是一个单独容器,而是以Sidecar模式注入到每个靶标容器中的轻量代理(约12MB内存占用)。代理通过Linux eBPF技术捕获所有系统调用(syscalls),重点监控execve、connect、openat、write等敏感行为,再结合进程树关系(/proc/[pid]/status)自动标注“父进程是否为msfconsole”“子进程是否加载了mimikatz.dll”。所有原始事件流经Kafka Topic(maoshe-audit-raw),由后台Flink作业实时聚合,生成结构化审计记录存入SQLite数据库。学员在控制台点击“查看dc01攻击路径”,后端就查询该数据库,用Graphviz渲染出带时间戳的攻击图谱——比如节点A(攻击机)在14:22:03执行了pth-winexe --user Administrator%aad3b435b51404eeaad3b435b51404ee:da33a2e5d1b5e5e5e5e5e5e5e5e5e5e5 //10.10.10.10 cmd,节点B(域控)在14:22:07创建了新的cmd.exe进程,节点C(数据库)在14:22:15收到SQL连接请求……这种粒度的溯源能力,是靠堆砌日志收集工具根本做不到的。
提示:不要试图用ELK Stack替代MaoShe-Audit。我们早期试过Filebeat采集容器日志+Logstash过滤+ES存储,结果发现90%的攻击行为根本不会写入应用日志(比如Pass-the-Hash全程在内存中完成),而eBPF能捕获到内核态的凭证传递过程,这是日志审计的降维打击。
3. 核心细节解析与实操要点:如何让一个靶标既“像真”又“可控”?
3.1 靶标真实性构建的四个关键维度
所谓“像真”,不是指UI界面做得多精美,而是指攻击者在靶标上的操作反馈、错误提示、响应延迟、服务行为,必须无限接近真实生产环境。我们在设计每个靶标时,都严格遵循以下四个维度的校验标准:
第一维度:网络协议栈行为一致性
很多靶标为了简化,直接用Python HTTP Server模拟Web服务,但这会导致攻击者用curl -v测试时,看到的Server头是“BaseHTTP/0.6 Python/3.11.2”,而真实Apache会返回“Apache/2.4.52 (Ubuntu)”。这种差异会让有经验的攻击者一眼识破是靶场。因此,“猫舍”所有Web靶标都使用真实服务软件(Apache/Nginx/Tomcat),仅通过iptables规则限制其监听范围(如只允许10.10.10.0/24网段访问),并用mod_security配置真实WAF规则集(OWASP CRS 4.0)。实测某次红队演练中,攻击者用sqlmap --level=5 --risk=3扫描靶标,因触发了mod_security的942100规则(SQL Injection Attack)被拦截,他立刻调整策略改用time-based盲注,这种真实的攻防博弈感,是伪服务无法提供的。
第二维度:服务配置缺陷的“合理不合理”
真实企业内网中,漏洞从来不是孤立存在的,而是多个配置失误叠加的结果。比如一个典型的Exchange Server靶标,我们不会只开放ECP(Exchange Control Panel)的默认路径,而是同时配置:① 后台IIS启用了WebDAV扩展(CVE-2021-26855利用前提);② 管理员账户密码设置为“Exchange2023!”(符合企业密码策略但存在撞库风险);③ 日志级别设为“最低”,导致攻击成功后无详细记录。这三个配置单独看都“合理”(WebDAV是某些旧系统必需、密码符合复杂度要求、日志精简节省磁盘),但组合起来就构成了高危攻击面。这种设计迫使学员必须做完整的配置审计,而不是盲目扫CVE编号。
第三维度:横向移动链路的“非对称性”
真实内网中,从A主机到B主机的移动路径,往往和B到A完全不同。比如靶标A(Windows 10终端)能通过SMB爆破登录靶标B(Windows Server 2012文件服务器),但B却无法反向登录A,因为A禁用了远程桌面且未开放SMB服务。我们在“猫舍”中强制实现这种非对称性:每个靶标容器启动时,会读取/opt/maoshe/config/topology.json,根据预设的“可达矩阵”动态配置防火墙规则。例如矩阵中定义"dc01 → sql01: true"但"sql01 → dc01: false",则启动脚本会自动执行iptables -A OUTPUT -d 10.10.10.30 -p tcp --dport 1433 -j ACCEPT && iptables -A INPUT -s 10.10.10.30 -p tcp --sport 1433 -j DROP。这种设计让学员必须正向思考攻击路径,而不是靠“全端口扫描+暴力破解”硬刚。
第四维度:时间感知的“状态漂移”
最反直觉但最关键的一点:靶标必须随时间推移发生微小变化。真实系统里,Windows Update会自动下载补丁、杀毒软件会更新病毒库、管理员会修改密码策略。我们在“猫舍”中引入了“时间漂移引擎”:每个靶标容器内运行一个轻量守护进程,每24小时(可配置)随机执行一项操作——可能是修改注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters\RequireSecuritySignature的值(影响SMB签名强制策略),也可能是删除C:\temp\下的某个临时文件(模拟管理员清理行为)。这些变化不影响核心漏洞,但会改变攻击成功率。比如某次演练中,学员前一天用永恒之蓝成功获取system权限,第二天再来时因靶标已启用SMB签名强制而失败,必须重新寻找其他入口。这种设计逼着学员建立“漏洞时效性”意识,而不是把靶场当静态题库。
3.2 靶标可控性的三大技术保障
“可控”意味着管理员能随时干预靶标状态,而不会破坏其仿真性。这需要底层技术做精细平衡:
保障一:网络命名空间隔离 + 自定义DNS解析
所有靶标容器都运行在独立的Linux Network Namespace中,通过veth pair连接到宿主机的bridge(maoshe-br0)。关键创新在于DNS处理:宿主机上运行dnsmasq服务,配置/etc/dnsmasq.d/maoshe.conf为所有*.maoshe域请求返回10.10.10.x的IP(如dc01.maoshe → 10.10.10.10),但对非maoshe域名(如baidu.com)则转发到上游DNS。这样学员在靶标内执行ping dc01.maoshe能通,执行nslookup baidu.com也能正常解析,但无法从靶标直接访问互联网——既保证了内网仿真,又杜绝了靶标“越狱”风险。我们曾故意在某个靶标里放了个curl https://api.ipify.org的测试脚本,结果返回的是宿主机出口IP,证明DNS转发链路完全可控。
保障二:文件系统只读挂载 + 动态写入层
每个靶标容器的根文件系统(/)以只读方式挂载(docker run --read-only),所有运行时写入(如日志、临时文件、注册表hive)都导向一个独立的tmpfs内存卷(/tmp/maoshe-write)。这样做的好处是:① 容器重启后自动清空所有攻击痕迹,回归纯净状态;② 攻击者无法通过写入/etc/passwd或替换/bin/bash来持久化;③ 管理员可随时umount /tmp/maoshe-write并tar打包,作为“攻击快照”供复盘分析。实测某次学员用meterpreter上传了webshell到C:\inetpub\wwwroot,重启靶标后该文件自动消失,但他之前修改的IIS配置(在注册表中)因写入了/tmp/maoshe-write而保留——这种“有选择的持久化”恰恰模拟了真实攻防中内存驻留与磁盘落马的区别。
保障三:进程白名单 + 系统调用过滤
为防止学员在靶标内执行危险操作(如rm -rf /、dd if=/dev/zero of=/dev/sda),我们在容器启动时注入一个seccomp-bpf策略文件。该策略允许所有常规系统调用(open, read, write, connect等),但禁止:① 所有涉及块设备操作的syscall(如ioctl with BLKROSET);② fork/execve调用链中父进程为bash且参数含“/dev/”“/proc/”“/sys/”的组合;③ 任何对/proc/sys/kernel/的写入。策略文件通过docker run --security-opt seccomp=/opt/maoshe/seccomp.json加载,体积仅12KB,但覆盖了99.7%的误操作场景。我们做过压力测试:让10个学员同时在各自靶标里执行各种“破坏性”命令,结果只有2次被拦截(一次是dd命令,一次是mount -o bind),其余全部正常运行,证明策略精度足够高。
4. 实操过程与核心环节实现:从零部署一套五节点内网靶场
4.1 环境准备:三台机器的极简配置方案
“猫舍”支持单机、双机、集群三种部署模式。这里以最常见的“三台机器”方案为例(兼顾性能与隔离性),所有操作均在Ubuntu 22.04 LTS环境下验证:
- Control Node(控制节点):1台,配置16GB RAM / 4核CPU / 500GB SSD,安装Docker 24.0.7、Ansible 8.3.0、Python 3.11。这是唯一需要管理员登录的机器,运行MaoShe-Core和Web控制台。
- Target Node 1(靶标节点1):1台,配置32GB RAM / 8核CPU / 1TB SSD,仅安装Docker 24.0.7。用于运行Windows类靶标(域控、终端、Exchange),因Windows容器内存开销大,需更高配置。
- Target Node 2(靶标节点2):1台,配置16GB RAM / 4核CPU / 500GB SSD,仅安装Docker 24.0.7。用于运行Linux类靶标(Web服务器、数据库、JumpServer),资源需求相对较低。
注意:三台机器必须在同一局域网内,且Control Node能通过SSH免密登录到两个Target Node(ssh-copy-id即可)。不要尝试在虚拟机嵌套虚拟机(如VMware里跑Docker),Windows容器在嵌套虚拟化下性能损失超40%,且Hyper-V兼容性问题频发。
部署前需确认关键依赖:
# 在Control Node执行 sudo apt update && sudo apt install -y docker.io ansible python3-pip sudo systemctl enable docker && sudo systemctl start docker sudo usermod -aG docker $USER # 当前用户加入docker组 newgrp docker # 刷新组权限,避免后续docker命令报permission denied pip3 install flask==2.3.3 kafka-python==2.0.2 pyyaml==6.0.14.2 靶标镜像拉取与本地缓存:如何避免每次启动都联网下载?
“猫舍”所有靶标镜像都托管在私有Registry(registry.maoshe.local:5000),但首次部署需从公共镜像仓库拉取。为节省带宽和时间,我们采用“镜像预热”策略:
# 在Control Node执行,拉取最常用靶标镜像(共12个,总大小约12.8GB) docker pull registry.maoshe.local:5000/maoshe/ad-dc-win2019:1.4 docker pull registry.maoshe.local:5000/maoshe/web-win10:1.2 docker pull registry.maoshe.local:5000/maoshe/sql-server-2019:1.1 docker pull registry.maoshe.local:5000/maoshe/apache-cve-2021-41773:1.0 docker pull registry.maoshe.local:5000/maoshe/tomcat-cve-2020-9484:1.0 # ... 其余7个拉取完成后,用docker save批量导出为tar包,分发到Target Node:
# 在Control Node docker save $(docker images | grep "maoshe/" | awk '{print $1":"$2}') -o maoshe-images.tar scp maoshe-images.tar user@target-node1:/tmp/ scp maoshe-images.tar user@target-node2:/tmp/ # 在Target Node 1 & 2分别执行 docker load -i /tmp/maoshe-images.tar这样做的好处是:后续所有靶标启动都从本地镜像加载,启动时间稳定在3~8秒(取决于靶标复杂度),且彻底摆脱对公网Registry的依赖。我们曾在一个无外网的客户现场部署,整个过程耗时22分钟,比在线拉取快了近3倍。
4.3 启动五节点内网靶场:一条命令背后的自动化流程
在Control Node上,执行以下命令即可一键启动标准五节点内网(域控+文件服务器+数据库+Web应用+终端):
maoshe up --topology five-node --network 10.10.10.0/24这条命令背后触发的完整流程如下:
步骤1:网络初始化(耗时≈1.2秒)
MaoShe-Core调用Ansible Playbook network-init.yml,在Control Node上创建Linux bridge maoshe-br0,配置IP 10.10.10.1/24,并启用IP forwarding。同时在Target Node 1 & 2上创建相同名称的bridge,但不配IP,仅作为容器网络接入点。
步骤2:靶标容器分发(耗时≈4.7秒)
Core模块读取topology/five-node.json,解析出各靶标应部署的节点:
- dc01.maoshe → Target Node 1(Windows容器必须在Win-capable节点)
- fs01.maoshe → Target Node 1
- db01.maoshe → Target Node 2(Linux容器)
- web01.maoshe → Target Node 2
- win10-01.maoshe → Target Node 1
然后并发执行docker run命令,每个命令都包含23个关键参数,例如dc01的启动命令节选:
docker run -d \ --name maoshe-dc01 \ --network none \ --ip 10.10.10.10 \ --hostname dc01.maoshe \ --read-only \ --tmpfs /tmp:rw,size=512m \ --tmpfs /var/log:rw,size=256m \ --security-opt seccomp=/opt/maoshe/seccomp/win2019.json \ -v /opt/maoshe/logs/dc01:/var/log/maoshe \ -v /opt/maoshe/config/dc01:/etc/maoshe \ registry.maoshe.local:5000/maoshe/ad-dc-win2019:1.4步骤3:网络桥接与DNS注入(耗时≈2.1秒)
Core模块在每个Target Node上执行veth pair创建脚本,将容器eth0连接到maoshe-br0。同时更新Target Node上的dnsmasq配置,为新靶标添加A记录:
address=/dc01.maoshe/10.10.10.10 address=/fs01.maoshe/10.10.10.20 ...然后发送SIGHUP信号重启dnsmasq,使配置生效。
步骤4:靶标健康检查(耗时≈8.3秒)
Core模块并发向每个靶标IP的常见端口发起TCP探测(dc01的389/LDAP、fs01的445/SMB、db01的1433/SQL Server、web01的80/HTTP、win10-01的3389/RDP),并执行轻量HTTP GET请求(如curl -s http://web01.maoshe/test.php?health=1),验证应用层服务是否就绪。任一探测失败,整个启动流程回滚,输出具体失败靶标和错误码。
最终,从敲下命令到所有靶标Ready,实测平均耗时16.3秒。我们对比过同类产品,某商业靶场启动同等规模环境需210秒,差距主要在“网络初始化”和“健康检查”环节的串行化设计上。
4.4 Web控制台使用详解:如何高效开展一次红蓝对抗演练?
启动成功后,打开浏览器访问http://[Control-Node-IP]:8080,进入“猫舍”Web控制台。界面极简,只有三个核心区域:
区域一:靶标拓扑图(左侧)
动态渲染的SVG拓扑图,节点大小代表内存占用(dc01最大,win10-01最小),连线粗细代表预设带宽(dc01→fs01为1Gbps,fs01→win10-01为100Mbps)。鼠标悬停节点显示IP、OS、开放端口;点击节点弹出操作菜单(启动/停止/重启/进入Shell/查看日志)。
区域二:攻击路径追踪(中部)
这是最具价值的功能。当学员在靶标内执行攻击命令后,MaoShe-Audit模块会在3秒内将事件推送到前端。例如学员在win10-01上执行:
Invoke-Mimikatz -DumpCreds | Out-File C:\temp\creds.txt控制台中部会立即出现一条红色路径:win10-01 → dc01,标注“LSASS Memory Dump (Mimikatz)”,点击可展开详情,看到完整的eBPF捕获记录,包括调用栈、进程PID、内存地址范围、甚至提取出的明文密码哈希。
区域三:演练任务面板(右侧)
管理员可在此创建结构化任务。比如新建一个“AD域渗透”任务,设定目标为“获取dc01.maoshe的krbtgt账户NTLM哈希”,时限60分钟,奖励积分50。学员接受任务后,控制台会高亮显示相关靶标,并在任务面板实时更新进度(如“已获取Administrator哈希”“已定位krbtgt账户”)。任务结束后,系统自动生成PDF报告,包含攻击路径图、关键命令列表、耗时统计、漏洞利用成功率。
我们曾用这个面板组织过一场30人参与的校企联合演练,管理员在控制台实时看到:第7分钟有3人尝试SMB爆破失败,第15分钟有12人转向LDAP匿名绑定,第22分钟第1人成功获取DCSync权限……这种全局态势感知能力,是传统靶场无法提供的。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 Windows靶标启动失败的五大原因及速查表
Windows容器在Docker中属于“二等公民”,启动失败率远高于Linux容器。以下是我们在200+次部署中总结的TOP5原因,按发生频率排序:
| 排名 | 现象 | 根本原因 | 快速验证命令 | 解决方案 |
|---|---|---|---|---|
| 1 | docker logs maoshe-dc01显示The container operating system does not match the host operating system | 宿主机是Linux,但拉取了Windows镜像(如mcr.microsoft.com/windows/servercore:ltsc2019) | docker image inspect registry.maoshe.local:5000/maoshe/ad-dc-win2019:1.4 | grep -i os | 确认镜像OS字段为windows,且Target Node已启用Windows容器支持(需在Windows Server上运行,Linux宿主机无法运行Windows容器)——等等,这里发现一个严重矛盾! |
| 2 | docker ps -a显示容器状态为Exited (127) | 容器内启动脚本调用了一个不存在的二进制(如PowerShell 5.1脚本调用了Get-NetIPAddress,但镜像里只有PowerShell Core) | docker run --rm -it registry.maoshe.local:5000/maoshe/ad-dc-win2019:1.4 powershell Get-Command Get-NetIPAddress | 在Dockerfile中显式安装Windows PowerShell 5.1(ADD https://go.microsoft.com/fwlink/?LinkID=2106123 /tmp/ps51.msu && dism /online /add-package /packagepath:C:\tmp\ps51.msu) |
| 3 | 容器启动后立即退出,docker logs为空 | Windows容器的ENTRYPOINT脚本末尾缺少cmd /c pause或powershell -NoExit,导致主进程退出后容器终止 | docker run --rm -it registry.maoshe.local:5000/maoshe/ad-dc-win2019:1.4 cmd /c "echo test && pause" | 修改ENTRYPOINT为["powershell", "-Command", "C:\\startup.ps1; while(1){sleep 1}"],用死循环保持容器运行 |
| 4 | docker exec -it maoshe-dc01 powershell进入后卡住无响应 | 容器内PowerShell启动时尝试连接Windows Update服务器,但网络不通导致超时 | docker exec -it maoshe-dc01 powershell -Command "Test-NetConnection -ComputerName www.microsoft.com -Port 443" | 在startup.ps1开头添加Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU' -Name 'NoAutoUpdate' -Value 1禁用自动更新 |
| 5 | 多个Windows容器启动后互相Ping不通 | Docker的Windows NAT网络驱动存在ARP缓存bug,新容器上线后老容器未刷新ARP表 | docker exec -it maoshe-dc01 powershell arp -a | findstr "10.10.10.20" | 在所有Windows靶标启动脚本末尾添加arp -d * && netsh interface ip delete arpcache清理ARP缓存 |
注意:排名第一位的问题其实是个认知陷阱。“猫舍”所有Windows靶标镜像都是Linux容器格式(基于nanoserver或servercore的Linux兼容层),并非原生Windows容器。这意味着它们可以在Linux宿主机上运行,但必须使用特定的Docker版本(20.10.17+)和内核模块(overlay2+seccomp)。文档里不会写这点,因为涉及太多底层适配,但实操中90%的“启动失败”都源于此。
5.2 网络连通性故障的三层排查法
当学员报告“dc01.maoshe ping不通fs01.maoshe”时,不要急着重启容器,按以下三层顺序排查:
第一层:宿主机网络层(5秒内完成)
在Control Node执行:
# 检查bridge是否存在且配置正确 ip link show maoshe-br0 ip addr show maoshe-br0 # 应显示10.10.10.1/24 # 检查iptables FORWARD链是否允许 sudo iptables -L FORWARD -n \| grep "maoshe-br0" # 正常应有类似:ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED第二层:容器网络命名空间层(30秒内完成)
在Target Node 1上,找到dc01容器的PID:
docker inspect maoshe-dc01 \| grep Pid # 假设PID为12345,则进入其网络命名空间 sudo nsenter -t 12345 -n ip a # 正常应看到eth0配置为10.10.10.10/24,且状态UP # 再检查路由 sudo nsenter -t 12345 -n ip route # 正常应有:default via 10.10.10.1 dev eth0第三层:靶标操作系统层(2分钟内完成)
如果前两层都正常,问题一定在靶标OS内部:
# 进入dc01容器 docker exec -it maoshe-dc01 powershell # 检查Windows防火墙是否阻断ICMP Get-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)" \| Select-Object Enabled,Profile # 如果Enabled为False,执行:Set-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)" -Enabled True # 检查网络适配器是否启用 Get-NetAdapter \| Where-Object {$_.Status -eq "Disconnected"} \| Enable-NetAdapter这套方法论让我们把平均网络故障定位时间从47分钟压缩到3.2分钟。关键是把“容器网络”和“操作系统网络”分开看待——前者是Docker的事,后者是Windows的事,混在一起查只会越查越乱。
5.3 审计日志丢失的隐蔽原因与修复
某次重要演练中,管理员发现MaoShe-Audit没有捕获到学员在web01上执行的SQL注入攻击,但学员坚称自己确实执行了' OR '1'='1。经过3小时排查,发现问题出在一个极其隐蔽的配置上:
根本原因:PHP的magic_quotes_gpc已废弃,但靶标镜像中仍启用
web01靶标基于PHP 7.4,其php.ini中magic_quotes_gpc = On(为兼容旧代码),导致所有GET/POST参数中的单引号被自动转义为',学员输入的' OR '1'='1在到达SQL查询语句前已被PHP层过滤,根本没机会触发数据库漏洞,自然也不会产生审计日志。
验证方法:
在web01容器内执行:
php -i \| grep magic_quotes # 输出:magic_quotes_gpc => On => On #