Dockerfile构建SQL-Labs靶场及Docker安全管控

作者:文刀竹肃日期:2026/3/9

Dockerfile构建SQL-Labs靶场及Docker安全管控

一、前言

SQL注入是网络安全领域最常见的漏洞之一,SQL-Labs是一款经典的SQL注入练习靶场,包含了各种类型的SQL注入场景(联合查询、盲注、报错注入等),是网安学习、漏洞验证的必备环境。本文将通过Dockerfile自定义构建SQL-Labs靶场镜像,完整演示从基础镜像选择、依赖安装、靶场部署到镜像优化的全过程,同时重点讲解容器权限管控、安全风险规避要点,贴合网安靶场搭建的实际需求,与上一篇Docker基础、核心命令内容形成衔接,实现“基础操作-实操案例-安全管控”的完整闭环。

二、Dockerfile构建SQL-Labs靶场(自定义靶场镜像)

2.1 靶场构建前置准备

  1. 环境要求:已安装Docker,确保Docker服务正常运行(systemctl status docker)。
  2. 核心思路:选择轻量化的Linux基础镜像(Centos7),安装Apache服务、PHP-5.6环境、MySQL-5.7数据库,下载SQL-Labs源码,配置数据库连接,固化镜像,最终实现一键启动靶场。
  3. 目录规划:创建单独的工作目录,存放Dockerfile和相关配置文件,避免文件混乱,便于后续维护和镜像构建。
1# 创建工作目录
2
3mkdir -p /root/sql-labs-docker && cd /root/sql-labs-docker
4
5# 目录下文件
6-rw-r--r-- 1 root root     112  3  7 21:12 db-creds.inc
7-rw-r--r-- 1 root root    2709  3  8 15:57 Dockerfile
8-rw-r--r-- 1 root root 3657281  3  7 20:17 sqli-labs-master.zip
9
10

2.2 编写Dockerfile(核心步骤,附详细注释)

在工作目录下创建Dockerfile文件(文件名必须为Dockerfile,大小写敏感),内容如下,每一步均添加注释,清晰说明作用,贴合网安靶场构建的安全规范:

1FROM centos:7
2
3# 1. 修复 CentOS 7 官方源 (EOL) 并安装基础依赖
4RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo && \
5    sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS-Base.repo && \
6    sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-Base.repo && \
7    sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-Base.repo
8    
9RUN yum update -y
10
11RUN yum install -y wget epel-release yum-utils unzip && \
12    rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm && \
13    yum install -y yum-utils && \
14    yum-config-manager --enable remi-php56 && \
15    rpm -ivh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm && \
16    rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
17
18# 2. 安装并启用 Remi PHP 5.6 
19RUN yum install -y httpd \
20        php php-mcrypt php-cli php-gd php-curl php-mysqlnd \
21        php-ldap php-zip php-fileinfo php-mbstring
22
23# 3. 安装 MySQL 5.7
24RUN yum install -y mysql-community-server
25
26# 4. 部署 SQLi-Labs 源码
27# 请确保当前目录下有 sqli-labs-master.zip
28COPY sqli-labs-master.zip /tmp/sqli-labs-master.zip
29RUN unzip /tmp/sqli-labs-master.zip -d /var/www/html/ && \
30    mv /var/www/html/sqli-labs-master /var/www/html/sqli-labs && \
31    # 核心修复:移除 setup-db.php 中导致报错的 GBK 编码强制设置
32    sed -i 's/CHARACTER SET `gbk`//g' /var/www/html/sqli-labs/sql-connections/setup-db.php && \
33    sed -i 's/CHARACTER SET gbk//g' /var/www/html/sqli-labs/sql-connections/setup-db.php && \
34    rm -f /tmp/sqli-labs-master.zip
35
36COPY db-creds.inc /var/www/html/sqli-labs/sql-connections/db-creds.inc
37
38# 5. 配置 Apache  SQLi-Labs 权限
39# 自动加载的 php 模块通常无需手动 AddType,但保留 DocumentRoot 修改
40RUN sed -i 's|DocumentRoot "/var/www/html"|DocumentRoot "/var/www/html/sqli-labs"|' /etc/httpd/conf/httpd.conf && \
41    sed -i '/<Directory "\/var\/www\/html">/,/<\/Directory>/ s|AllowOverride None|AllowOverride All|' /etc/httpd/conf/httpd.conf && \
42    chown -R apache:apache /var/www/html/sqli-labs && \
43    chmod -R 755 /var/www/html/sqli-labs
44
45# 6. 数据库初始化配置
46RUN mkdir -p /var/run/mysqld /var/lib/mysql && \
47    chown -R mysql:mysql /var/run/mysqld /var/lib/mysql && \
48    mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
49
50# 允许远程连接并关闭 bind-address 限制
51RUN echo "[mysqld]\nbind-address = 0.0.0.0" >> /etc/my.cnf
52
53# 7. 编写启动脚本 (Entrypoint)
54RUN echo $'#!/bin/bash\n\
55# 启动 MySQL\n\
56/usr/sbin/mysqld --user=mysql --datadir=/var/lib/mysql &\n\
57echo "Waiting for MySQL to start..."\n\
58until mysqladmin -h127.0.0.1 ping --silent; do sleep 2; done\n\
59\n\
60# 配置数据库用户与权限\n\
61mysql -uroot -e "CREATE DATABASE IF NOT EXISTS security;"\n\
62mysql -uroot -e "ALTER USER \'root\'@\'localhost\' IDENTIFIED BY \'root123456\';"\n\
63mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO \'root\'@\'%\' IDENTIFIED BY \'root123456\' WITH GRANT OPTION;"\n\
64mysql -uroot -e "FLUSH PRIVILEGES;"\n\
65\n\
66echo "MySQL is ready. Starting Apache..."\n\
67exec /usr/sbin/httpd -D FOREGROUND' > /entrypoint.sh && \
68    chmod +x /entrypoint.sh
69
70EXPOSE 80 3306
71
72ENTRYPOINT ["/entrypoint.sh"]
73

2.3 构建并启动SQL-Labs靶场镜像(串联核心命令)

基于上述Dockerfile,执行Docker命令构建镜像、启动容器,步骤如下:

  1. 构建靶场镜像(使用docker build命令,自定义镜像名和版本号,便于识别):
1# 进入工作目录(确保Dockerfile在当前目录)
2
3cd /root/sql-labs-docker
4
5# 构建镜像,-t指定镜像名:版本号,.表示当前目录的Dockerfile
6
7docker build -t sql-labs:v1 .
8
9
  1. 查看构建好的镜像(验证镜像是否成功创建):
1docker images | grep sql-labs
2
3
  1. 启动靶场容器(配置端口映射、数据持久化,贴合网安场景安全要求):
1docker run -d -p 80:80 --name sql-labs-target \
2
3--restart=unless-stopped \
4
5-v sql-labs-data:/var/lib/mysql \
6
7sql-labs:v1
8
9

命令解释(关联上一篇核心命令):

  • -d:后台运行容器,适合长期部署的靶场;
  • -p 8080:80:将宿主机8080端口映射到容器80端口,避免与宿主机其他服务端口冲突;
  • –name sql-labs-target:指定容器名,便于后续管理(如停止、重启);
  • –restart=unless-stopped:容器异常退出时自动重启,保证靶场可用性;
  • -v sql-labs-data:/var/lib/mysql:挂载数据卷,持久化数据库数据,避免容器删除后靶场数据丢失;
  • sql-labs:v1:指定使用的靶场镜像。
  1. 验证靶场是否启动成功:
1# 查看容器运行状态
2
3docker ps | grep sql-labs-target
4
5# 查看容器日志,排查启动故障
6
7docker logs -f sql-labs-target
8
9
  1. 访问靶场:打开浏览器,输入http://宿主机IP,看到SQL-Labs首页,点击“Setup/reset Database for labs”初始化数据库,提示“Your DB has been created successfully”即为搭建成功,可开始SQL注入练习。

2.4 自定义靶场镜像优化(网安场景重点)

为提升靶场镜像的安全性、轻量化和可复用性,针对网安场景进行以下优化,可修改Dockerfile实现:

  1. 轻量化优化:删除镜像中无用的工具(如wget、unzip),仅保留靶场运行必需的依赖,减少镜像体积,降低攻击面(在Dockerfile的apk安装后添加&& apk del wget unzip)。
  2. 安全优化:禁止root用户运行容器,在Dockerfile中添加USER apache,使用低权限用户启动服务,即使容器被入侵,攻击者也无法获得root权限。
  3. 可复用优化:将数据库配置、靶场源码版本等参数提取为环境变量,通过ENV命令定义,构建镜像时可通过--build-arg动态修改,适配不同的练习场景。
  4. 日志优化:配置Apache和Mariadb日志输出到容器stdout,便于通过docker logs查看,同时避免日志文件占用过多空间。

三、Docker容器权限管控(网安场景核心)

Docker容器的权限管控是网安场景中规避安全风险的关键,尤其是靶场容器(本身存在漏洞,易被攻击),需通过权限限制,防止攻击者通过容器入侵宿主机或其他容器。以下是核心管控措施,结合SQL-Labs靶场案例详细说明:

3.1 容器运行权限管控(最核心)

  1. 禁止使用root用户运行容器:

容器默认以root用户运行,一旦容器被入侵,攻击者可直接获得宿主机的root权限(尤其是挂载宿主机目录的场景)。解决方案:

  • 方式1:Dockerfile中添加USER 非root用户(如上述优化中的USER apache),指定容器启动用户,该用户仅拥有靶场运行必需的权限。
  • 方式2:启动容器时通过--user参数指定用户,例如:
1docker run -d -p 80:80 --name sql-labs-target --user apache sql-labs:v1
2
3

⚠️ 注意:指定非root用户后,需确保容器内的文件、目录权限适配该用户,避免出现权限不足导致服务启动失败(如SQL-Labs的Web目录需赋予apache用户读写权限)。

  1. 限制容器的系统调用和权限:

通过--cap-drop参数删除容器不必要的系统权限,仅保留必需的权限,减少攻击面。例如,靶场容器仅需要网络访问、文件读写权限,可删除其他高风险权限:

1docker run -d -p 80:80 --name sql-labs-target \
2
3--cap-drop=ALL \
4
5--cap-add=NET_BIND_SERVICE \
6
7--cap-add=DAC_OVERRIDE \
8
9sql-labs:v1
10
11

解释:–cap-drop=ALL删除所有系统权限,–cap-add添加必需的权限(NET_BIND_SERVICE允许绑定端口,DAC_OVERRIDE允许文件权限覆盖)。

3.2 容器网络权限管控

  1. 隔离容器网络:为靶场容器创建独立的网络,禁止容器访问宿主机和其他容器,避免漏洞扩散。例如:
1# 创建独立网络
2
3docker network create sql-labs-network
4
5# 启动容器时加入该网络,不与宿主机网络互通
6
7docker run -d -p 8080:80 --name sql-labs-target \
8
9--network=sql-labs-network \
10
11sql-labs:v1
12
13
  1. 禁止容器使用主机网络模式:上一篇文档提到的--network=host模式会让容器共享宿主机网络栈,风险极高,靶场容器绝对禁止使用该模式,避免攻击者通过容器直接访问宿主机的网络资源。

3.3 容器挂载权限管控(网安场景重点规避点)

挂载宿主机目录或数据卷是容器持久化数据的常用方式,但也是安全风险的高发点,需严格管控:

  1. 禁止挂载宿主机敏感目录:绝对禁止将宿主机的/etc/root/var/run/docker.sock等敏感目录挂载到靶场容器,避免攻击者通过容器篡改宿主机配置、控制Docker引擎。
  2. 只读挂载非必要目录:对于仅需要读取的宿主机目录,使用-v 宿主机目录:容器目录:ro(ro=read only)设置为只读挂载,防止容器内的恶意程序篡改宿主机文件。例如,若需挂载宿主机的配置文件,可设置为只读:
1docker run -d -p 80:80 --name sql-labs-target \
2
3-v /root/sql-labs-config:/var/www/sql-labs/config:ro \
4
5sql-labs:v1
6
7
  1. 使用数据卷替代宿主机目录挂载:数据卷是Docker管理的存储方式,与宿主机目录隔离,安全性更高,靶场的数据库数据、日志等建议使用数据卷挂载(如上述案例中的-v sql-labs-data:/var/lib/mysql)。

四、Docker容器安全风险规避(网安场景实操要点)

结合SQL-Labs靶场搭建案例,针对Docker容器在网安场景中常见的安全风险,提出具体的规避方案,覆盖镜像、容器、运行环境全流程:

4.1 镜像安全风险规避

  1. 避免使用来源不明的镜像:靶场镜像需自行通过Dockerfile构建,或从官方仓库、可信来源下载,禁止使用网上流传的未知镜像(可能植入恶意代码、后门,导致靶场被控制)。
  2. 定期更新镜像和依赖:及时更新基础镜像(如Alpine、Ubuntu)和依赖包(Apache、PHP、Mariadb),修复已知的安全漏洞,避免攻击者利用漏洞入侵容器。例如,定期重新构建SQL-Labs镜像,更新依赖版本。
  3. 镜像瘦身与漏洞扫描:删除镜像中无用的工具、文件,减少攻击面;使用Docker镜像扫描工具(如Trivy)扫描镜像中的安全漏洞,修复后再部署。例如:
1# 安装Trivy工具
2
3docker pull aquasec/trivy
4
5# 扫描SQL-Labs镜像漏洞
6
7docker run --rm aquasec/trivy image sql-labs:v1
8
9

4.2 容器运行安全风险规避

  1. 限制容器资源占用:靶场容器若被攻击者利用进行恶意攻击(如挖矿、DDoS),会占用大量宿主机资源,需通过--memory--cpus限制容器的内存和CPU使用:
1docker run -d -p 8080:80 --name sql-labs-target \
2
3--memory=1G \
4
5--cpus=0.5 \
6
7sql-labs:v1
8
9

解释:限制容器最大使用1G内存、0.5个CPU核心,避免资源耗尽。

  1. 禁止容器特权模式:特权模式(--privileged)会让容器拥有宿主机的所有权限,风险极高,无论何种场景,靶场容器都禁止使用该模式。
  2. 启用容器日志监控:通过docker logs实时查看容器运行日志,或结合ELK等日志分析工具,监控容器内的异常行为(如多次失败的数据库连接、异常的文件读写),及时发现攻击行为。
  3. 定期清理无用容器和镜像:靶场练习结束后,及时停止并删除容器,清理无用的镜像,避免残留容器成为安全隐患(参考上一篇文档的docker stopdocker rmdocker rmi命令)。

4.3 宿主机与Docker引擎安全风险规避

  1. 加固Docker引擎配置:修改Docker守护进程配置(/etc/docker/daemon.json),启用TLS认证,限制远程访问,避免未授权用户控制Docker引擎:
1{
2
3"registry-mirrors": ["https://docker.mirrors.aliyun.com"],
4
5"tls": true,
6
7"tlscert": "/etc/docker/server-cert.pem",
8
9"tlskey": "/etc/docker/server-key.pem",
10
11"tlsverify": true
12
13
  1. 定期更新Docker引擎:及时更新Docker引擎版本,修复Docker本身的安全漏洞,避免攻击者利用引擎漏洞入侵宿主机。
  2. 限制宿主机用户权限:仅授权必要的用户使用Docker命令,禁止普通用户执行Docker命令(Docker命令默认需要root权限,或添加用户到docker用户组),避免未授权用户通过Docker创建恶意容器。

五、总结

本文通过Dockerfile完整实现了SQL-Labs靶场的自定义镜像构建,串联了Dockerfile编写、镜像构建、容器启动等核心操作,同时重点讲解了容器权限管控和安全风险规避要点,贴合网安场景中靶场搭建、容器安全的实际需求。核心要点总结如下:

  1. 自定义靶场镜像:通过Dockerfile选择轻量化基础镜像,安装必需依赖,固化靶场环境,优化镜像安全性和可复用性,避免使用来源不明的镜像。
  2. 容器权限管控:核心是“降权运行”,禁止root用户启动容器,限制系统权限、网络权限和挂载权限,减少攻击面。
  3. 安全风险规避:覆盖镜像、容器、宿主机全流程,定期更新镜像和引擎,监控容器日志,清理无用资源,避免漏洞扩散和恶意攻击。

Dockerfile构建SQL-Labs靶场及Docker安全管控》 是转载文章,点击查看原文


相关推荐


Gateway—— 高级流量路由
离恨烟~2026/3/1

0 前言 Gateway API 是 Kubernetes 官方推出的下一代流量管理标准,旨在解决传统 Ingress 在协议支持、扩展性和多租户等方面的不足。它通过 GatewayClass、Gateway、HTTPRoute 等 CRD 实现流量治理的分层解耦,让基础设施和应用团队各司其职。本章将以若依项目为例,实战部署 Envoy Gateway 并实现高级流量路由。 1 Gateway的概念 1.1 什么是Gateway Gateway API 是 Kubernetes 官方下一代“流量


2026年,我的AI编程助手使用心得(纯个人体验,非评测)
PieroPc2026/2/21

今年在AI编程助手上摸索出一套自己的组合拳,分享给同样在路上的创作者们: 初稿设计 首选小米MiMo。不是因为它功能多强,而是因为它出设计稿真的快、真的漂亮。脑子里的想法扔给它,几分钟就能看到赏心悦目的初稿,这种“即时满足感”别的工具给不了。 aistudio.xiaomimimo.com/ 数据处理 遇到图片要转CSV或JSON,我会切到豆包Doubao。它的综合模型对图片支持确实好,识别准、转换快。不过坦白说,深入问下去就容易卡壳,这时候别硬撑。 www.doubao.c


从少年到父亲:我在异乡的第一个年
修己xj2026/2/13

今天是老历腊月二十五。写下“老历”这两个字时,忽然觉得它们只在过年时才被记起——像老家,那个我长到二十岁的地方。工作以后,也就过年才回了。 今年不同了。我的身份栏里添了“父亲”二字,恍惚间,竟像回到了我小时候。今天,想和家人们聊聊年味,聊聊这些年,我是有着怎样不一样的感受的。 🧨 童年的年:年是撒欢的鞭炮 小的时候,特别喜欢过年,那会的过年,从进入腊月开始,过年的氛围越来越浓了,那会我们每天兜里揣满鞭炮,满村子放鞭炮,今天给二大爷家的房顶上扔,明天炸五太爷家的果园,虽然因此也挨了不少的打,可


网络接口设备详解:从 `eth0`、`lo` 到 `br0`,看懂 Linux 网络的“器官”
哈里谢顿2026/2/4

在 Linux 系统中,执行 ip addr 或 ifconfig 命令时,你会看到形如 eth0、lo、br0、docker0、vethxxx 的网络接口。它们有的代表真实网卡,有的却是纯软件构造的“虚拟器官”。 这些接口共同构成了 Linux 强大而灵活的网络能力,支撑着从本地通信到容器化、虚拟化的复杂场景。 本文将以 eth0(物理接口)、lo(回环接口)、br0(网桥接口) 为例,深入解析各类网络接口的本质、作用及典型应用场景。 一、什么是网络接口(Network Interface)


Langchain学习笔记(一):认识Langchain-调用LLM的正确姿势
Shawn_Shawn2026/1/26

Langchain是一款开源框架,用于构建Agent,集成了众多大模型供应商和工具。 langchain主要负责与LLM交互,Tool,Rag,Memory,Agent等功能。 LangGraph负责实现Agent编排,专用于构建、管理和部署长时间运行(long-running)且具备状态管理(stateful的智能体。 LangSmith则负责提升Agent的可观测性,提供了用于开发、调试和部署 LLM 应用程序的工具。 它能够帮助您在一个统一的平台上追踪请求、评估输出、测试提示词(Prom


Vercel React 最佳实践 中文版
ssshooter2026/1/17

React 最佳实践 版本 1.0.0 Vercel 工程团队 2026年1月 注意: 本文档主要供 Agent 和 LLM 在 Vercel 维护、生成或重构 React 及 Next.js 代码库时遵循。人类开发者也会发现其对于保持一致性和自动化优化非常有帮助。 摘要 这是一份针对 React 和 Next.js 应用程序的综合性能优化指南,专为 AI Agent 和 LLM 设计。包含 8 个类别的 40 多条规则,按影响力从关键(消除瀑布流、减少打包体积)到增量(高级模式)排序。每


PHP 8.5 #[\NoDiscard] 揪出“忽略返回值“的 Bug
catchadmin2026/1/9

PHP 8.5 #[\NoDiscard] 揪出"忽略返回值"的 Bug 有些 bug 会导致异常、致命错误、监控面板一片红。 还有一类 bug 长这样:“一切都跑了,但什么都没发生”。方法调了,副作用也有了,但关键返回值(成功标志、错误列表、新的不可变实例)被扔掉了。粗看代码没毛病,测试没覆盖到边界情况也能过。bug 就这么混进生产环境。 PHP 一直允许这种风格的失误: doSomethingImportant(); // 返回了一个值……但没人用 PHP 8.5 新增了一种原生


React 从入门到出门第一章 JSX 增强特性与函数组件入门
怕浪猫2026/1/1

今天咱们从 React 19 的基础语法入手,聊聊 JSX 增强特性和函数组件的核心用法。对于刚接触 React 19 的同学来说,这两块是搭建应用的基石——函数组件是 React 19 的核心载体,而 JSX 则让我们能以更直观的方式描述 UI 结构。 更重要的是,React 19 对 JSX 做了不少实用增强,比如支持多根节点默认不包裹、改进碎片语法等,这些特性能直接提升我们的开发效率。下面咱们结合具体案例,从“是什么→怎么用→为什么”三个维度,把这些知识点讲透~ 一、先搞懂核心概念:函数组


数据挖掘12
upper20202025/12/22

数据挖掘12 – 零样本分类 一、预备知识 1.底层特征(Low-level Features) 底层特征是从原始输入数据中直接提取的、最基础的、通常不具有明确语义含义的数值或信号特征。 例子(以图像为例): 像素强度(灰度值、RGB值) 2.中层属性(Mid-level Attributes / Mid-level Features) 中层属性是在底层特征基础上进一步组合、聚合或抽象得到的具有一定结构或局部语义的特征。它们比底层特征更接近人类可理解的概念,但尚未达到高层语义(如“猫”、“汽车”


JConsole 中 GC 时间统计的含义
千百元2025/12/14

要理解 JConsole 中 GC 时间统计的含义,需结合 垃圾收集器类型​ 和 统计维度​ 拆解: 1. 关于 PS MarkSweep 上的 12.575 秒 (16 收集) PS MarkSweep:是 JVM 中用于清理 老年代(PS Old Gen)​ 的垃圾收集器(属于 Full GC 收集器,触发时会暂停所有应用线程,即 STW)。 16 收集:表示该收集器 总共执行了 16 次 Full GC。 12.575 秒:这 16 次 Full GC 的 总耗

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客